From 549d708f03c6a0dc0ef6071f1aedfb21f666a777 Mon Sep 17 00:00:00 2001 From: Anneke Sinnema Date: Mon, 12 Oct 2026 17:47:56 +0200 Subject: [PATCH 1/3] feat(#185): decrease opacity of ring Signed-off-by: Anneke Sinnema --- .../angular/src/lib/ui/accordion/src/lib/hlm-accordion.css | 2 +- packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css | 2 +- packages/angular/src/lib/ui/button/src/lib/hlm-button.css | 2 +- packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css | 2 +- packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css | 2 +- .../src/lib/ui/input-group/src/lib/hlm-input-group.css | 2 +- .../angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css | 2 +- packages/angular/src/lib/ui/input/src/lib/hlm-input.css | 2 +- packages/angular/src/lib/ui/item/src/lib/hlm-item.css | 2 +- .../src/lib/ui/native-select/src/lib/hlm-native-select.css | 2 +- .../lib/ui/navigation-menu/src/lib/hlm-navigation-menu.css | 4 ++-- .../src/lib/ui/radio-group/src/lib/hlm-radio-group.css | 2 +- packages/angular/src/lib/ui/select/src/lib/hlm-select.css | 2 +- packages/angular/src/lib/ui/sidebar/src/lib/hlm-sidebar.css | 2 +- packages/angular/src/lib/ui/slider/src/lib/hlm-slider.css | 2 +- packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css | 2 +- packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css | 4 ++-- packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css | 2 +- packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css | 2 +- packages/angular/src/styles/base.css | 2 +- .../react/src/components/ui/accordion/accordion.module.css | 2 +- packages/react/src/components/ui/badge/badge.module.css | 2 +- packages/react/src/components/ui/button/button.module.css | 2 +- packages/react/src/components/ui/calendar/calendar.module.css | 2 +- packages/react/src/components/ui/checkbox/checkbox.module.css | 2 +- packages/react/src/components/ui/combobox/combobox.module.css | 2 +- .../src/components/ui/input-group/input-group.module.css | 2 +- .../react/src/components/ui/input-otp/input-otp.module.css | 2 +- packages/react/src/components/ui/input/input.module.css | 2 +- packages/react/src/components/ui/item/item.module.css | 2 +- .../src/components/ui/native-select/native-select.module.css | 2 +- .../components/ui/navigation-menu/navigation-menu.module.css | 4 ++-- .../src/components/ui/radio-group/radio-group.module.css | 2 +- .../src/components/ui/scroll-area/scroll-area.module.css | 2 +- packages/react/src/components/ui/select/select.module.css | 2 +- packages/react/src/components/ui/slider/slider.module.css | 4 ++-- packages/react/src/components/ui/switch/switch.module.css | 2 +- packages/react/src/components/ui/tabs/tabs.module.css | 2 +- packages/react/src/components/ui/textarea/textarea.module.css | 2 +- packages/react/src/components/ui/toggle/toggle.module.css | 2 +- 40 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css b/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css index c287c970..cca100cd 100644 --- a/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css +++ b/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css @@ -41,7 +41,7 @@ .curve-accordion-trigger:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-accordion-trigger:focus-visible::after { diff --git a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css index 6490314f..e962d718 100644 --- a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css +++ b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css @@ -24,7 +24,7 @@ .curve-badge:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .curve-badge[aria-invalid='true'] { diff --git a/packages/angular/src/lib/ui/button/src/lib/hlm-button.css b/packages/angular/src/lib/ui/button/src/lib/hlm-button.css index 1ec9907c..d0c9bb5a 100644 --- a/packages/angular/src/lib/ui/button/src/lib/hlm-button.css +++ b/packages/angular/src/lib/ui/button/src/lib/hlm-button.css @@ -32,7 +32,7 @@ .curve-button:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .curve-button:disabled, diff --git a/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css b/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css index 08fb1958..b2181c0a 100644 --- a/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css +++ b/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css @@ -27,7 +27,7 @@ .curve-checkbox:focus-visible { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css b/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css index d3e593b4..78bc0ac8 100644 --- a/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css +++ b/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css @@ -83,7 +83,7 @@ .curve-combobox-chips:focus-within { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css b/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css index 2d129d29..335bd00e 100644 --- a/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css +++ b/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css @@ -27,7 +27,7 @@ .curve-input-group:has([data-slot='input-group-control']:focus-visible) { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css b/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css index bf96f82b..1e8d0602 100644 --- a/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css +++ b/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css @@ -66,7 +66,7 @@ z-index: 10; border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css index 7a5a6665..069dd270 100644 --- a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css +++ b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css @@ -26,7 +26,7 @@ .curve-input:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .curve-input:disabled { diff --git a/packages/angular/src/lib/ui/item/src/lib/hlm-item.css b/packages/angular/src/lib/ui/item/src/lib/hlm-item.css index f52d5d5a..a29b352c 100644 --- a/packages/angular/src/lib/ui/item/src/lib/hlm-item.css +++ b/packages/angular/src/lib/ui/item/src/lib/hlm-item.css @@ -21,7 +21,7 @@ a.curve-item:hover { .curve-item:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-item--variant-default { diff --git a/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css b/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css index c6d8a122..39b6e6d3 100644 --- a/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css +++ b/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css @@ -54,7 +54,7 @@ .curve-native-select:focus-visible { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/navigation-menu/src/lib/hlm-navigation-menu.css b/packages/angular/src/lib/ui/navigation-menu/src/lib/hlm-navigation-menu.css index a15a4bba..0bd45450 100644 --- a/packages/angular/src/lib/ui/navigation-menu/src/lib/hlm-navigation-menu.css +++ b/packages/angular/src/lib/ui/navigation-menu/src/lib/hlm-navigation-menu.css @@ -62,7 +62,7 @@ .curve-navigation-menu-trigger:focus-visible { outline-style: solid; outline-width: 1px; - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-navigation-menu-trigger:disabled { @@ -121,7 +121,7 @@ .curve-navigation-menu-link:focus-visible { outline-style: solid; outline-width: 1px; - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-navigation-menu-link[data-disabled='true'] { diff --git a/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css b/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css index cf0ee5b2..bc6dba64 100644 --- a/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css +++ b/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css @@ -50,7 +50,7 @@ .curve-radio:has(:focus-visible) .curve-radio-indicator { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css index 4fcd598c..5ae36ba0 100644 --- a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css +++ b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css @@ -48,7 +48,7 @@ .curve-select-trigger:focus-visible { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/sidebar/src/lib/hlm-sidebar.css b/packages/angular/src/lib/ui/sidebar/src/lib/hlm-sidebar.css index d3d4dfd5..79ff170e 100644 --- a/packages/angular/src/lib/ui/sidebar/src/lib/hlm-sidebar.css +++ b/packages/angular/src/lib/ui/sidebar/src/lib/hlm-sidebar.css @@ -298,7 +298,7 @@ } .curve-input.curve-sidebar-input:focus-visible { - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-input.curve-sidebar-input[data-matches-spartan-invalid='true'] { diff --git a/packages/angular/src/lib/ui/slider/src/lib/hlm-slider.css b/packages/angular/src/lib/ui/slider/src/lib/hlm-slider.css index ffae4061..127001b4 100644 --- a/packages/angular/src/lib/ui/slider/src/lib/hlm-slider.css +++ b/packages/angular/src/lib/ui/slider/src/lib/hlm-slider.css @@ -95,7 +95,7 @@ .curve-slider-thumb:hover, .curve-slider-thumb:focus-visible { box-shadow: - 0 0 0 4px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 4px color-mix(in oklab, var(--ring) 32%, transparent), 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); } diff --git a/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css b/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css index b311becc..ff9de1bb 100644 --- a/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css +++ b/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css @@ -39,7 +39,7 @@ .curve-switch:focus-visible { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css b/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css index 97723153..ea4d332b 100644 --- a/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css +++ b/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css @@ -86,7 +86,7 @@ .curve-tabs-trigger:focus-visible { border-color: var(--ring); outline: 1px solid var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-tabs-trigger:disabled { @@ -119,7 +119,7 @@ [data-active]:not([data-active='false']) ):focus-visible { box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); } diff --git a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css index ec24930e..d1faacb3 100644 --- a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css +++ b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css @@ -24,7 +24,7 @@ .curve-textarea:focus-visible { border-color: var(--ring); box-shadow: - 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent), + 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); } diff --git a/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css b/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css index cd17cafb..e0cb95bb 100644 --- a/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css +++ b/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css @@ -46,7 +46,7 @@ .curve-toggle:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } .curve-toggle[data-matches-spartan-invalid='true'] { diff --git a/packages/angular/src/styles/base.css b/packages/angular/src/styles/base.css index 1d4e86fe..1b83acba 100644 --- a/packages/angular/src/styles/base.css +++ b/packages/angular/src/styles/base.css @@ -2,7 +2,7 @@ *::before, *::after { border-color: var(--border); - outline-color: color-mix(in oklab, var(--ring) 50%, transparent); + outline-color: color-mix(in oklab, var(--ring) 32%, transparent); } html { diff --git a/packages/react/src/components/ui/accordion/accordion.module.css b/packages/react/src/components/ui/accordion/accordion.module.css index e80554a7..45cbe144 100644 --- a/packages/react/src/components/ui/accordion/accordion.module.css +++ b/packages/react/src/components/ui/accordion/accordion.module.css @@ -34,7 +34,7 @@ .trigger:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .trigger[aria-disabled='true'] { diff --git a/packages/react/src/components/ui/badge/badge.module.css b/packages/react/src/components/ui/badge/badge.module.css index bba27163..e65d00a0 100644 --- a/packages/react/src/components/ui/badge/badge.module.css +++ b/packages/react/src/components/ui/badge/badge.module.css @@ -19,7 +19,7 @@ .badge:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .badge[aria-invalid='true'] { diff --git a/packages/react/src/components/ui/button/button.module.css b/packages/react/src/components/ui/button/button.module.css index 3ad48a61..cdba4cdf 100644 --- a/packages/react/src/components/ui/button/button.module.css +++ b/packages/react/src/components/ui/button/button.module.css @@ -22,7 +22,7 @@ .button:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .button:active:not([aria-haspopup]) { diff --git a/packages/react/src/components/ui/calendar/calendar.module.css b/packages/react/src/components/ui/calendar/calendar.module.css index b36290ee..fa1ed5bc 100644 --- a/packages/react/src/components/ui/calendar/calendar.module.css +++ b/packages/react/src/components/ui/calendar/calendar.module.css @@ -274,7 +274,7 @@ position: relative; z-index: 10; border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .dayButton[data-range-end='true'] { diff --git a/packages/react/src/components/ui/checkbox/checkbox.module.css b/packages/react/src/components/ui/checkbox/checkbox.module.css index 6d768897..9bd6b671 100644 --- a/packages/react/src/components/ui/checkbox/checkbox.module.css +++ b/packages/react/src/components/ui/checkbox/checkbox.module.css @@ -25,7 +25,7 @@ .checkbox:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .checkbox:disabled { diff --git a/packages/react/src/components/ui/combobox/combobox.module.css b/packages/react/src/components/ui/combobox/combobox.module.css index 46061bdd..7968a137 100644 --- a/packages/react/src/components/ui/combobox/combobox.module.css +++ b/packages/react/src/components/ui/combobox/combobox.module.css @@ -160,7 +160,7 @@ .chips:focus-within { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .chips:has([aria-invalid='true']) { diff --git a/packages/react/src/components/ui/input-group/input-group.module.css b/packages/react/src/components/ui/input-group/input-group.module.css index 2c87a6ec..6b760c1e 100644 --- a/packages/react/src/components/ui/input-group/input-group.module.css +++ b/packages/react/src/components/ui/input-group/input-group.module.css @@ -20,7 +20,7 @@ .group:has([data-slot='input-group-control']:focus-visible) { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .group:has([data-slot][aria-invalid='true']) { diff --git a/packages/react/src/components/ui/input-otp/input-otp.module.css b/packages/react/src/components/ui/input-otp/input-otp.module.css index e314e2bb..71d67d92 100644 --- a/packages/react/src/components/ui/input-otp/input-otp.module.css +++ b/packages/react/src/components/ui/input-otp/input-otp.module.css @@ -80,7 +80,7 @@ .slot[data-active='true'] { z-index: 10; border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .slot[data-active='true'][aria-invalid='true'] { diff --git a/packages/react/src/components/ui/input/input.module.css b/packages/react/src/components/ui/input/input.module.css index 858f779c..26c0d291 100644 --- a/packages/react/src/components/ui/input/input.module.css +++ b/packages/react/src/components/ui/input/input.module.css @@ -21,7 +21,7 @@ .input:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .input:disabled { diff --git a/packages/react/src/components/ui/item/item.module.css b/packages/react/src/components/ui/item/item.module.css index de192362..b98cdf6e 100644 --- a/packages/react/src/components/ui/item/item.module.css +++ b/packages/react/src/components/ui/item/item.module.css @@ -33,7 +33,7 @@ .item:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .item a { diff --git a/packages/react/src/components/ui/native-select/native-select.module.css b/packages/react/src/components/ui/native-select/native-select.module.css index 132c9bfb..507487f2 100644 --- a/packages/react/src/components/ui/native-select/native-select.module.css +++ b/packages/react/src/components/ui/native-select/native-select.module.css @@ -37,7 +37,7 @@ .select:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .select:disabled { diff --git a/packages/react/src/components/ui/navigation-menu/navigation-menu.module.css b/packages/react/src/components/ui/navigation-menu/navigation-menu.module.css index 2e766d70..fa940c0d 100644 --- a/packages/react/src/components/ui/navigation-menu/navigation-menu.module.css +++ b/packages/react/src/components/ui/navigation-menu/navigation-menu.module.css @@ -49,7 +49,7 @@ } .trigger:focus-visible { - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); outline: 1px solid transparent; } @@ -144,7 +144,7 @@ } .link:focus-visible { - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); outline: 1px solid transparent; } diff --git a/packages/react/src/components/ui/radio-group/radio-group.module.css b/packages/react/src/components/ui/radio-group/radio-group.module.css index 3080751c..13d92ff5 100644 --- a/packages/react/src/components/ui/radio-group/radio-group.module.css +++ b/packages/react/src/components/ui/radio-group/radio-group.module.css @@ -24,7 +24,7 @@ .item:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .item:disabled { diff --git a/packages/react/src/components/ui/scroll-area/scroll-area.module.css b/packages/react/src/components/ui/scroll-area/scroll-area.module.css index 66071904..ec5c6f69 100644 --- a/packages/react/src/components/ui/scroll-area/scroll-area.module.css +++ b/packages/react/src/components/ui/scroll-area/scroll-area.module.css @@ -13,7 +13,7 @@ } .viewport:focus-visible { - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); outline: 1px solid var(--ring); } diff --git a/packages/react/src/components/ui/select/select.module.css b/packages/react/src/components/ui/select/select.module.css index cfb5c6c8..13c2992f 100644 --- a/packages/react/src/components/ui/select/select.module.css +++ b/packages/react/src/components/ui/select/select.module.css @@ -40,7 +40,7 @@ .trigger:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .trigger:disabled { diff --git a/packages/react/src/components/ui/slider/slider.module.css b/packages/react/src/components/ui/slider/slider.module.css index a1813a82..87d378fe 100644 --- a/packages/react/src/components/ui/slider/slider.module.css +++ b/packages/react/src/components/ui/slider/slider.module.css @@ -82,11 +82,11 @@ } .thumb:hover { - box-shadow: 0 0 0 4px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 4px color-mix(in oklch, var(--ring) 32%, transparent); } .thumb:focus-visible { - box-shadow: 0 0 0 4px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 4px color-mix(in oklch, var(--ring) 32%, transparent); } .thumb:disabled { diff --git a/packages/react/src/components/ui/switch/switch.module.css b/packages/react/src/components/ui/switch/switch.module.css index 4c604a5d..cd44183a 100644 --- a/packages/react/src/components/ui/switch/switch.module.css +++ b/packages/react/src/components/ui/switch/switch.module.css @@ -28,7 +28,7 @@ .switch:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .switch[aria-invalid='true'] { diff --git a/packages/react/src/components/ui/tabs/tabs.module.css b/packages/react/src/components/ui/tabs/tabs.module.css index 6022a7eb..2c3bb32e 100644 --- a/packages/react/src/components/ui/tabs/tabs.module.css +++ b/packages/react/src/components/ui/tabs/tabs.module.css @@ -78,7 +78,7 @@ .trigger:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); outline: 1px solid var(--ring); } diff --git a/packages/react/src/components/ui/textarea/textarea.module.css b/packages/react/src/components/ui/textarea/textarea.module.css index 7a9150df..e4b6f1e2 100644 --- a/packages/react/src/components/ui/textarea/textarea.module.css +++ b/packages/react/src/components/ui/textarea/textarea.module.css @@ -22,7 +22,7 @@ .textarea:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .textarea:disabled { diff --git a/packages/react/src/components/ui/toggle/toggle.module.css b/packages/react/src/components/ui/toggle/toggle.module.css index 9029cf5c..49cf6c58 100644 --- a/packages/react/src/components/ui/toggle/toggle.module.css +++ b/packages/react/src/components/ui/toggle/toggle.module.css @@ -23,7 +23,7 @@ .toggle:focus-visible { border-color: var(--ring); - box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } .toggle:disabled { From 03e10206f7ace40bce920bdf70aafe2f5004c979 Mon Sep 17 00:00:00 2001 From: Anneke Sinnema Date: Mon, 12 Oct 2026 18:22:11 +0200 Subject: [PATCH 2/3] feat: split focus and focus-visible styling Signed-off-by: Anneke Sinnema --- .changeset/focus-border-split.md | 6 ++++++ .../src/lib/ui/accordion/src/lib/hlm-accordion.css | 7 +++++-- .../angular/src/lib/ui/badge/src/lib/hlm-badge.css | 5 ++++- .../angular/src/lib/ui/button/src/lib/hlm-button.css | 10 ++++++++-- .../src/lib/ui/checkbox/src/lib/hlm-checkbox.css | 7 +++++-- .../angular/src/lib/ui/input/src/lib/hlm-input.css | 5 ++++- packages/angular/src/lib/ui/item/src/lib/hlm-item.css | 5 ++++- .../lib/ui/native-select/src/lib/hlm-native-select.css | 5 ++++- .../src/lib/ui/radio-group/src/lib/hlm-radio-group.css | 5 ++++- .../angular/src/lib/ui/select/src/lib/hlm-select.css | 5 ++++- .../angular/src/lib/ui/switch/src/lib/hlm-switch.css | 5 ++++- packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css | 5 ++++- .../src/lib/ui/textarea/src/lib/hlm-textarea.css | 5 ++++- .../angular/src/lib/ui/toggle/src/lib/hlm-toggle.css | 5 ++++- .../src/components/ui/accordion/accordion.module.css | 5 ++++- .../react/src/components/ui/badge/badge.module.css | 5 ++++- .../react/src/components/ui/button/button.module.css | 10 ++++++++-- .../src/components/ui/checkbox/checkbox.module.css | 5 ++++- .../react/src/components/ui/input/input.module.css | 5 ++++- packages/react/src/components/ui/item/item.module.css | 5 ++++- .../ui/native-select/native-select.module.css | 5 ++++- .../components/ui/radio-group/radio-group.module.css | 5 ++++- .../react/src/components/ui/select/select.module.css | 5 ++++- .../react/src/components/ui/switch/switch.module.css | 5 ++++- packages/react/src/components/ui/tabs/tabs.module.css | 5 ++++- .../src/components/ui/textarea/textarea.module.css | 5 ++++- .../react/src/components/ui/toggle/toggle.module.css | 5 ++++- 27 files changed, 120 insertions(+), 30 deletions(-) create mode 100644 .changeset/focus-border-split.md diff --git a/.changeset/focus-border-split.md b/.changeset/focus-border-split.md new file mode 100644 index 00000000..a884c883 --- /dev/null +++ b/.changeset/focus-border-split.md @@ -0,0 +1,6 @@ +--- +'@surfnet/curve-react': patch +'@surfnet/curve-angular': patch +--- + +Split focus styling: `:focus` now gives the primary (`--ring`) border, and `:focus-visible` adds the 3px ring shadow on top. Mouse-focused controls show the border change only; keyboard focus shows both. Applies to accordion, badge, button, checkbox, input, item, native select, radio group, select, switch, tabs, textarea and toggle. diff --git a/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css b/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css index cca100cd..5351ef7a 100644 --- a/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css +++ b/packages/angular/src/lib/ui/accordion/src/lib/hlm-accordion.css @@ -39,12 +39,15 @@ text-decoration-line: underline; } -.curve-accordion-trigger:focus-visible { +.curve-accordion-trigger:focus { border-color: var(--ring); +} + +.curve-accordion-trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } -.curve-accordion-trigger:focus-visible::after { +.curve-accordion-trigger:focus::after { content: ''; border-color: var(--ring); } diff --git a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css index e962d718..b306d1c8 100644 --- a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css +++ b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.css @@ -22,8 +22,11 @@ transition: all 150ms ease; } -.curve-badge:focus-visible { +.curve-badge:focus { border-color: var(--ring); +} + +.curve-badge:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/angular/src/lib/ui/button/src/lib/hlm-button.css b/packages/angular/src/lib/ui/button/src/lib/hlm-button.css index d0c9bb5a..4f40f99a 100644 --- a/packages/angular/src/lib/ui/button/src/lib/hlm-button.css +++ b/packages/angular/src/lib/ui/button/src/lib/hlm-button.css @@ -30,8 +30,11 @@ transform: translateY(1px); } -.curve-button:focus-visible { +.curve-button:focus { border-color: var(--ring); +} + +.curve-button:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } @@ -134,8 +137,11 @@ background-color: color-mix(in oklch, var(--destructive) 90%, transparent); } -.curve-button--variant-destructive:focus-visible { +.curve-button--variant-destructive:focus { border-color: color-mix(in oklch, var(--destructive) 40%, transparent); +} + +.curve-button--variant-destructive:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--destructive) 20%, transparent); } diff --git a/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css b/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css index b2181c0a..185078e5 100644 --- a/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css +++ b/packages/angular/src/lib/ui/checkbox/src/lib/hlm-checkbox.css @@ -24,8 +24,11 @@ background-color: color-mix(in oklab, var(--input) 30%, transparent); } -.curve-checkbox:focus-visible { +.curve-checkbox:focus { border-color: var(--ring); +} + +.curve-checkbox:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); @@ -58,7 +61,7 @@ /* Invalid via the control state (forceInvalid or form validation). */ .curve-checkbox--invalid, -.curve-checkbox--invalid:focus-visible { +.curve-checkbox--invalid:focus { border-color: var(--destructive); } diff --git a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css index 069dd270..fb987bff 100644 --- a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css +++ b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css @@ -24,8 +24,11 @@ color: var(--muted-foreground); } -.curve-input:focus-visible { +.curve-input:focus { border-color: var(--ring); +} + +.curve-input:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/angular/src/lib/ui/item/src/lib/hlm-item.css b/packages/angular/src/lib/ui/item/src/lib/hlm-item.css index a29b352c..3eea492d 100644 --- a/packages/angular/src/lib/ui/item/src/lib/hlm-item.css +++ b/packages/angular/src/lib/ui/item/src/lib/hlm-item.css @@ -19,8 +19,11 @@ a.curve-item:hover { background-color: var(--muted); } -.curve-item:focus-visible { +.curve-item:focus { border-color: var(--ring); +} + +.curve-item:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } diff --git a/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css b/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css index 39b6e6d3..676f2f06 100644 --- a/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css +++ b/packages/angular/src/lib/ui/native-select/src/lib/hlm-native-select.css @@ -51,8 +51,11 @@ background-color: color-mix(in oklab, var(--input) 50%, transparent); } -.curve-native-select:focus-visible { +.curve-native-select:focus { border-color: var(--ring); +} + +.curve-native-select:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css b/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css index bc6dba64..a5dde15a 100644 --- a/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css +++ b/packages/angular/src/lib/ui/radio-group/src/lib/hlm-radio-group.css @@ -47,8 +47,11 @@ background-color: color-mix(in oklab, var(--input) 30%, transparent); } -.curve-radio:has(:focus-visible) .curve-radio-indicator { +.curve-radio:has(:focus) .curve-radio-indicator { border-color: var(--ring); +} + +.curve-radio:has(:focus-visible) .curve-radio-indicator { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css index 5ae36ba0..de83ee5c 100644 --- a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css +++ b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css @@ -45,8 +45,11 @@ background-color: color-mix(in oklab, var(--input) 50%, transparent); } -.curve-select-trigger:focus-visible { +.curve-select-trigger:focus { border-color: var(--ring); +} + +.curve-select-trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css b/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css index ff9de1bb..f1f981df 100644 --- a/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css +++ b/packages/angular/src/lib/ui/switch/src/lib/hlm-switch.css @@ -36,8 +36,11 @@ background-color: var(--primary); } -.curve-switch:focus-visible { +.curve-switch:focus { border-color: var(--ring); +} + +.curve-switch:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css b/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css index ea4d332b..1fd570b0 100644 --- a/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css +++ b/packages/angular/src/lib/ui/tabs/src/lib/hlm-tabs.css @@ -83,8 +83,11 @@ justify-content: flex-start; } -.curve-tabs-trigger:focus-visible { +.curve-tabs-trigger:focus { border-color: var(--ring); +} + +.curve-tabs-trigger:focus-visible { outline: 1px solid var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } diff --git a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css index d1faacb3..5157849c 100644 --- a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css +++ b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css @@ -21,8 +21,11 @@ color: var(--muted-foreground); } -.curve-textarea:focus-visible { +.curve-textarea:focus { border-color: var(--ring); +} + +.curve-textarea:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent), var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css b/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css index e0cb95bb..3836fd7c 100644 --- a/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css +++ b/packages/angular/src/lib/ui/toggle/src/lib/hlm-toggle.css @@ -44,8 +44,11 @@ color: var(--secondary-foreground); } -.curve-toggle:focus-visible { +.curve-toggle:focus { border-color: var(--ring); +} + +.curve-toggle:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/accordion/accordion.module.css b/packages/react/src/components/ui/accordion/accordion.module.css index 45cbe144..1065ef08 100644 --- a/packages/react/src/components/ui/accordion/accordion.module.css +++ b/packages/react/src/components/ui/accordion/accordion.module.css @@ -32,8 +32,11 @@ text-decoration: underline; } -.trigger:focus-visible { +.trigger:focus { border-color: var(--ring); +} + +.trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/badge/badge.module.css b/packages/react/src/components/ui/badge/badge.module.css index e65d00a0..6c7e600d 100644 --- a/packages/react/src/components/ui/badge/badge.module.css +++ b/packages/react/src/components/ui/badge/badge.module.css @@ -17,8 +17,11 @@ transition: all 150ms ease; } -.badge:focus-visible { +.badge:focus { border-color: var(--ring); +} + +.badge:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/button/button.module.css b/packages/react/src/components/ui/button/button.module.css index cdba4cdf..831ca245 100644 --- a/packages/react/src/components/ui/button/button.module.css +++ b/packages/react/src/components/ui/button/button.module.css @@ -20,8 +20,11 @@ -webkit-tap-highlight-color: transparent; } -.button:focus-visible { +.button:focus { border-color: var(--ring); +} + +.button:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } @@ -131,8 +134,11 @@ background-color: color-mix(in oklch, var(--destructive) 90%, transparent); } -.variantDestructive:focus-visible { +.variantDestructive:focus { border-color: color-mix(in oklch, var(--destructive) 40%, transparent); +} + +.variantDestructive:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--destructive) 20%, transparent); } diff --git a/packages/react/src/components/ui/checkbox/checkbox.module.css b/packages/react/src/components/ui/checkbox/checkbox.module.css index 9bd6b671..554ac8cd 100644 --- a/packages/react/src/components/ui/checkbox/checkbox.module.css +++ b/packages/react/src/components/ui/checkbox/checkbox.module.css @@ -23,8 +23,11 @@ opacity: 0.5; } -.checkbox:focus-visible { +.checkbox:focus { border-color: var(--ring); +} + +.checkbox:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/input/input.module.css b/packages/react/src/components/ui/input/input.module.css index 26c0d291..0c5e3927 100644 --- a/packages/react/src/components/ui/input/input.module.css +++ b/packages/react/src/components/ui/input/input.module.css @@ -19,8 +19,11 @@ color: var(--muted-foreground); } -.input:focus-visible { +.input:focus { border-color: var(--ring); +} + +.input:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/item/item.module.css b/packages/react/src/components/ui/item/item.module.css index b98cdf6e..783bbe58 100644 --- a/packages/react/src/components/ui/item/item.module.css +++ b/packages/react/src/components/ui/item/item.module.css @@ -31,8 +31,11 @@ outline: none; } -.item:focus-visible { +.item:focus { border-color: var(--ring); +} + +.item:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/native-select/native-select.module.css b/packages/react/src/components/ui/native-select/native-select.module.css index 507487f2..5ffa7234 100644 --- a/packages/react/src/components/ui/native-select/native-select.module.css +++ b/packages/react/src/components/ui/native-select/native-select.module.css @@ -35,8 +35,11 @@ color: var(--muted-foreground); } -.select:focus-visible { +.select:focus { border-color: var(--ring); +} + +.select:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/radio-group/radio-group.module.css b/packages/react/src/components/ui/radio-group/radio-group.module.css index 13d92ff5..993ba096 100644 --- a/packages/react/src/components/ui/radio-group/radio-group.module.css +++ b/packages/react/src/components/ui/radio-group/radio-group.module.css @@ -22,8 +22,11 @@ inset: -0.5rem -0.75rem; } -.item:focus-visible { +.item:focus { border-color: var(--ring); +} + +.item:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/select/select.module.css b/packages/react/src/components/ui/select/select.module.css index 13c2992f..bd02b6dc 100644 --- a/packages/react/src/components/ui/select/select.module.css +++ b/packages/react/src/components/ui/select/select.module.css @@ -38,8 +38,11 @@ height: calc(var(--spacing, 0.25rem) * 8); } -.trigger:focus-visible { +.trigger:focus { border-color: var(--ring); +} + +.trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/switch/switch.module.css b/packages/react/src/components/ui/switch/switch.module.css index cd44183a..02248b08 100644 --- a/packages/react/src/components/ui/switch/switch.module.css +++ b/packages/react/src/components/ui/switch/switch.module.css @@ -26,8 +26,11 @@ width: 24px; } -.switch:focus-visible { +.switch:focus { border-color: var(--ring); +} + +.switch:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/tabs/tabs.module.css b/packages/react/src/components/ui/tabs/tabs.module.css index 2c3bb32e..92b65397 100644 --- a/packages/react/src/components/ui/tabs/tabs.module.css +++ b/packages/react/src/components/ui/tabs/tabs.module.css @@ -76,8 +76,11 @@ color: var(--foreground); } -.trigger:focus-visible { +.trigger:focus { border-color: var(--ring); +} + +.trigger:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); outline: 1px solid var(--ring); } diff --git a/packages/react/src/components/ui/textarea/textarea.module.css b/packages/react/src/components/ui/textarea/textarea.module.css index e4b6f1e2..9c940e02 100644 --- a/packages/react/src/components/ui/textarea/textarea.module.css +++ b/packages/react/src/components/ui/textarea/textarea.module.css @@ -20,8 +20,11 @@ color: var(--muted-foreground); } -.textarea:focus-visible { +.textarea:focus { border-color: var(--ring); +} + +.textarea:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } diff --git a/packages/react/src/components/ui/toggle/toggle.module.css b/packages/react/src/components/ui/toggle/toggle.module.css index 49cf6c58..bfc8539a 100644 --- a/packages/react/src/components/ui/toggle/toggle.module.css +++ b/packages/react/src/components/ui/toggle/toggle.module.css @@ -21,8 +21,11 @@ color: var(--foreground); } -.toggle:focus-visible { +.toggle:focus { border-color: var(--ring); +} + +.toggle:focus-visible { box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); } From 6338247f1b76e7fa9af7dd1066ac7786cf36eb5e Mon Sep 17 00:00:00 2001 From: Anneke Sinnema Date: Mon, 12 Oct 2026 18:52:39 +0200 Subject: [PATCH 3/3] feat(192): hover color for input fields Signed-off-by: Anneke Sinnema --- .changeset/hover-border-strong.md | 6 ++++++ .../angular/src/lib/ui/combobox/src/lib/hlm-combobox.css | 4 ++++ .../src/lib/ui/input-group/src/lib/hlm-input-group.css | 5 +++++ .../src/lib/ui/input-otp/src/lib/hlm-input-otp.css | 9 +++++++++ packages/angular/src/lib/ui/input/src/lib/hlm-input.css | 4 ++++ .../angular/src/lib/ui/select/src/lib/hlm-select.css | 4 ++++ .../angular/src/lib/ui/textarea/src/lib/hlm-textarea.css | 4 ++++ .../react/src/components/ui/combobox/combobox.module.css | 4 ++++ .../src/components/ui/input-group/input-group.module.css | 5 +++++ .../src/components/ui/input-otp/input-otp.module.css | 8 ++++---- packages/react/src/components/ui/input/input.module.css | 4 ++++ .../react/src/components/ui/select/select.module.css | 4 ++++ .../react/src/components/ui/textarea/textarea.module.css | 4 ++++ 13 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 .changeset/hover-border-strong.md diff --git a/.changeset/hover-border-strong.md b/.changeset/hover-border-strong.md new file mode 100644 index 00000000..7beeaf40 --- /dev/null +++ b/.changeset/hover-border-strong.md @@ -0,0 +1,6 @@ +--- +'@surfnet/curve-react': minor +'@surfnet/curve-angular': minor +--- + +Form fields now show a `--border-strong` border on hover: Combobox (chips), Input, Input Group, Input OTP, Select and Textarea. Focus, active and invalid states still take precedence, and disabled fields don't react to hover. diff --git a/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css b/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css index 78bc0ac8..59cdabc8 100644 --- a/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css +++ b/packages/angular/src/lib/ui/combobox/src/lib/hlm-combobox.css @@ -80,6 +80,10 @@ background-color: color-mix(in oklab, var(--input) 30%, transparent); } +.curve-combobox-chips:hover:where(:not(:has(:disabled))) { + border-color: var(--border-strong); +} + .curve-combobox-chips:focus-within { border-color: var(--ring); box-shadow: diff --git a/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css b/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css index 335bd00e..47f1f40b 100644 --- a/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css +++ b/packages/angular/src/lib/ui/input-group/src/lib/hlm-input-group.css @@ -24,6 +24,10 @@ background-color: color-mix(in oklab, var(--input) 30%, transparent); } +.curve-input-group:hover:where(:not(:has(:disabled))) { + border-color: var(--border-strong); +} + .curve-input-group:has([data-slot='input-group-control']:focus-visible) { border-color: var(--ring); box-shadow: @@ -45,6 +49,7 @@ } /* Inside a combobox popup the search field shows no focus ring. */ +[data-slot='combobox-content'] .curve-input-group:hover, [data-slot='combobox-content'] .curve-input-group:focus-within { border-color: inherit; box-shadow: var(--shadow-xs, 0 1px 2px 0 rgb(0 0 0 / 0.05)); diff --git a/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css b/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css index 1e8d0602..bf83559b 100644 --- a/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css +++ b/packages/angular/src/lib/ui/input-otp/src/lib/hlm-input-otp.css @@ -42,6 +42,10 @@ transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1); } +.curve-input-otp-slot:disabled { + cursor: not-allowed; +} + .curve-input-otp-slot:first-child { border-inline-start-width: 1px; border-start-start-radius: var(--radius-md, calc(var(--radius, 0.625rem) * 0.8)); @@ -61,6 +65,11 @@ border-color: var(--destructive); } +/* Hover; the active state below overrides it. */ +.curve-input-otp-slot:hover:not([data-matches-spartan-invalid='true']) { + border-color: var(--border-strong); +} + /* The slot the next character goes into. */ .curve-input-otp-slot:has(brn-input-otp-slot[data-active='true']) { z-index: 10; diff --git a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css index fb987bff..479f947a 100644 --- a/packages/angular/src/lib/ui/input/src/lib/hlm-input.css +++ b/packages/angular/src/lib/ui/input/src/lib/hlm-input.css @@ -24,6 +24,10 @@ color: var(--muted-foreground); } +.curve-input:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .curve-input:focus { border-color: var(--ring); } diff --git a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css index de83ee5c..8a5adb99 100644 --- a/packages/angular/src/lib/ui/select/src/lib/hlm-select.css +++ b/packages/angular/src/lib/ui/select/src/lib/hlm-select.css @@ -45,6 +45,10 @@ background-color: color-mix(in oklab, var(--input) 50%, transparent); } +.curve-select-trigger:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .curve-select-trigger:focus { border-color: var(--ring); } diff --git a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css index 5157849c..ff2e2812 100644 --- a/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css +++ b/packages/angular/src/lib/ui/textarea/src/lib/hlm-textarea.css @@ -21,6 +21,10 @@ color: var(--muted-foreground); } +.curve-textarea:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .curve-textarea:focus { border-color: var(--ring); } diff --git a/packages/react/src/components/ui/combobox/combobox.module.css b/packages/react/src/components/ui/combobox/combobox.module.css index 7968a137..a7b578a6 100644 --- a/packages/react/src/components/ui/combobox/combobox.module.css +++ b/packages/react/src/components/ui/combobox/combobox.module.css @@ -158,6 +158,10 @@ box-shadow 150ms ease; } +.chips:hover:where(:not(:has(:disabled))) { + border-color: var(--border-strong); +} + .chips:focus-within { border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); diff --git a/packages/react/src/components/ui/input-group/input-group.module.css b/packages/react/src/components/ui/input-group/input-group.module.css index 6b760c1e..4b6e0a74 100644 --- a/packages/react/src/components/ui/input-group/input-group.module.css +++ b/packages/react/src/components/ui/input-group/input-group.module.css @@ -18,6 +18,10 @@ background-color: color-mix(in oklch, var(--input) 30%, transparent); } +.group:hover:where(:not(:has(:disabled))) { + border-color: var(--border-strong); +} + .group:has([data-slot='input-group-control']:focus-visible) { border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring) 32%, transparent); @@ -42,6 +46,7 @@ height: auto; } +:global([data-slot='combobox-content']) .group:hover, :global([data-slot='combobox-content']) .group:focus-within { border-color: inherit; box-shadow: none; diff --git a/packages/react/src/components/ui/input-otp/input-otp.module.css b/packages/react/src/components/ui/input-otp/input-otp.module.css index 71d67d92..0287a412 100644 --- a/packages/react/src/components/ui/input-otp/input-otp.module.css +++ b/packages/react/src/components/ui/input-otp/input-otp.module.css @@ -20,10 +20,6 @@ opacity: 0.5; } -.input { - cursor: not-allowed; -} - .input:disabled { cursor: not-allowed; } @@ -77,6 +73,10 @@ background-color: color-mix(in oklch, var(--input) 30%, transparent); } +.slot:hover:not([aria-invalid='true']) { + border-color: var(--border-strong); +} + .slot[data-active='true'] { z-index: 10; border-color: var(--ring); diff --git a/packages/react/src/components/ui/input/input.module.css b/packages/react/src/components/ui/input/input.module.css index 0c5e3927..e63ed331 100644 --- a/packages/react/src/components/ui/input/input.module.css +++ b/packages/react/src/components/ui/input/input.module.css @@ -19,6 +19,10 @@ color: var(--muted-foreground); } +.input:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .input:focus { border-color: var(--ring); } diff --git a/packages/react/src/components/ui/select/select.module.css b/packages/react/src/components/ui/select/select.module.css index bd02b6dc..ce76c968 100644 --- a/packages/react/src/components/ui/select/select.module.css +++ b/packages/react/src/components/ui/select/select.module.css @@ -38,6 +38,10 @@ height: calc(var(--spacing, 0.25rem) * 8); } +.trigger:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .trigger:focus { border-color: var(--ring); } diff --git a/packages/react/src/components/ui/textarea/textarea.module.css b/packages/react/src/components/ui/textarea/textarea.module.css index 9c940e02..b1cc7b5a 100644 --- a/packages/react/src/components/ui/textarea/textarea.module.css +++ b/packages/react/src/components/ui/textarea/textarea.module.css @@ -20,6 +20,10 @@ color: var(--muted-foreground); } +.textarea:hover:where(:not(:disabled)) { + border-color: var(--border-strong); +} + .textarea:focus { border-color: var(--ring); }