Merge the reviewed settings pill border correction

# Conflicts:
#	wolfskin-design/tokens.sha256
This commit is contained in:
justinzeus 2026-11-05 16:44:52 +01:00
commit b24c404cc8
6 changed files with 58 additions and 8 deletions

View file

@ -77,6 +77,11 @@ resolves consistently in native captures; the approved JSON weights stay unchang
Nav, picker names, labels and pill weights use that same mapping. Nav label colour Nav, picker names, labels and pill weights use that same mapping. Nav label colour
fades for 200 ms ease-out; the blob retains its critically damped spring. fades for 200 ms ease-out; the blob retains its critically damped spring.
Settings pills have a separate 1 dp stroke (2 px on the stage), not a focus ring.
The stroke is inset within the fixed 20 dp / 40 px height; horizontal border-box
padding includes it. The 6 px dash / 4 px gap follows the browser's 3:2 stroke-width
ratios. Resting borders are white at 22% opacity; focused borders use ink at 40%.
The small gear under the final person opens Settings with Requests focused. The small gear under the final person opens Settings with Requests focused.
Settings groups hand off to existing upstream pages; the Requests entry explicitly Settings groups hand off to existing upstream pages; the Requests entry explicitly
has no request data yet. **Advanced settings → Wolfskin screens** is the persistent has no request data yet. **Advanced settings → Wolfskin screens** is the persistent

View file

@ -215,6 +215,32 @@
"dp": 20.0, "dp": 20.0,
"source": "locked index.html:71-92, 256-263, 303-328; spec 6.1 and nav-shell measured bounds" "source": "locked index.html:71-92, 256-263, 303-328; spec 6.1 and nav-shell measured bounds"
}, },
"settingsPillStroke": {
"$type": "dimension",
"px": 2,
"dp": 1.0,
"source": "index.html:122; pill border 2 px inside its 40 px border-box"
},
"settingsPillDashRatio": {
"$type": "number",
"$value": 3,
"source": "st-091 frozen browser top border: 6 px dashes at 2 px stroke width"
},
"settingsPillDashGapRatio": {
"$type": "number",
"$value": 2,
"source": "st-091 frozen browser top border: 4 px gaps at 2 px stroke width"
},
"settingsPillBorder": {
"$type": "color",
"$value": "#ffffff38",
"source": "index.html:122; white at 22 percent opacity, rounded to 8-bit alpha"
},
"settingsPillFocusedBorder": {
"$type": "color",
"$value": "#0b0b1066",
"source": "index.html:328; focused pill ink at 40 percent opacity"
},
"settingsPillPadding": { "settingsPillPadding": {
"$type": "dimension", "$type": "dimension",
"px": 16, "px": 16,

View file

@ -24,8 +24,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
@ -108,10 +110,19 @@ fun SettingsRow(group: SettingsGroup, focused: Boolean, openRequests: Int?, modi
@Composable @Composable
private fun SettingsPill(label: String, focused: Boolean) { private fun SettingsPill(label: String, focused: Boolean) {
val foreground = if (focused) C.onFocus else C.dim val foreground = if (focused) C.onFocus else C.dim
Box(Modifier.height(S.settingsPillHeight).drawBehind { val border = if (focused) S.settingsPillFocusedBorder else S.settingsPillBorder
val stroke = WolfskinTokens.Focus.ringButtonRing.toPx() Box(Modifier.height(S.settingsPillHeight).drawWithCache {
drawRoundRect(foreground.copy(alpha = .4f), cornerRadius = CornerRadius(WolfskinTokens.Radius.pill.toPx()), style = Stroke(stroke, pathEffect = PathEffect.dashPathEffect(floatArrayOf(stroke * 2, stroke * 2)))) val stroke = S.settingsPillStroke.toPx()
}.padding(horizontal = S.settingsPillPadding), contentAlignment = Alignment.Center) { val inset = Offset(stroke / 2, stroke / 2)
val bounds = Size(size.width - stroke, size.height - stroke)
val outline = Stroke(stroke, pathEffect = PathEffect.dashPathEffect(
floatArrayOf(stroke * S.settingsPillDashRatio, stroke * S.settingsPillDashGapRatio),
))
val radius = CornerRadius(WolfskinTokens.Radius.pill.toPx())
onDrawBehind {
drawRoundRect(border, topLeft = inset, size = bounds, cornerRadius = radius, style = outline)
}
}.padding(horizontal = S.settingsPillPadding + S.settingsPillStroke), contentAlignment = Alignment.Center) {
Text(label, color = foreground, style = WolfskinTokens.Type.caption.copy(fontWeight = WolfskinTokens.Type.label.fontWeight)) Text(label, color = foreground, style = WolfskinTokens.Type.caption.copy(fontWeight = WolfskinTokens.Type.label.fontWeight))
} }
} }

View file

@ -266,6 +266,11 @@ object WolfskinTokens {
val settingsRowGap = 12.0.dp val settingsRowGap = 12.0.dp
val settingsIcon = 18.0.dp val settingsIcon = 18.0.dp
val settingsPillHeight = 20.0.dp val settingsPillHeight = 20.0.dp
val settingsPillStroke = 1.0.dp
const val settingsPillDashRatio = 3.0f
const val settingsPillDashGapRatio = 2.0f
val settingsPillBorder = ComposeColor(0x38FFFFFF)
val settingsPillFocusedBorder = ComposeColor(0x660B0B10)
val settingsPillPadding = 8.0.dp val settingsPillPadding = 8.0.dp
val settingsPillGap = 6.0.dp val settingsPillGap = 6.0.dp
val settingsChevron = 15.0.dp val settingsChevron = 15.0.dp

View file

@ -163,6 +163,9 @@
--shell-settingsRowGap: 24.0px; --shell-settingsRowGap: 24.0px;
--shell-settingsIcon: 36.0px; --shell-settingsIcon: 36.0px;
--shell-settingsPillHeight: 40.0px; --shell-settingsPillHeight: 40.0px;
--shell-settingsPillStroke: 2.0px;
--shell-settingsPillBorder: #ffffff38;
--shell-settingsPillFocusedBorder: #0b0b1066;
--shell-settingsPillPadding: 16.0px; --shell-settingsPillPadding: 16.0px;
--shell-settingsPillGap: 12.0px; --shell-settingsPillGap: 12.0px;
--shell-settingsChevron: 30.0px; --shell-settingsChevron: 30.0px;

View file

@ -1,5 +1,5 @@
1438f7ca4a2b6f951c9e643ab0afacbf2f7fc98e57905295d518c6225e054de4 generate_tokens.py 1438f7ca4a2b6f951c9e643ab0afacbf2f7fc98e57905295d518c6225e054de4 generate_tokens.py
2d98b185e68c2f964cb744bb640dea94d3c5eaad183816d422646806b41327a3 shell-tokens.json 1052c79be79e0fb85e64ba5b48a77e7e9dddd114c656e5572f39c0a85e09b9f5 shell-tokens.json
965e802974d8fd440c65a1178f49e7824e986648c49f4068efcc587f9b5b384f src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt f380580c85d518e70f76991632b1c0be394f2d237c07097b2eec362950a14d20 src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt
3db2663abf8fc15dc8ddee8adb18ad411065aff5ca8486b533c344596514e1d9 tokens.css 900a8d995b74083cdf911fc4055c1c90827384fb1b0f5799c8823a8d0f0e48b2 tokens.css
5b939f1f3eb90b428008fda75720f6e3a4e844c486668931db3d52bffb987b53 tokens.json 5b939f1f3eb90b428008fda75720f6e3a4e844c486668931db3d52bffb987b53 tokens.json