diff --git a/src/shared/versions.ts b/src/shared/versions.ts index 895c0cc..492caad 100644 --- a/src/shared/versions.ts +++ b/src/shared/versions.ts @@ -1,6 +1,6 @@ export const HARBOR_VERSIONS = Object.freeze({ - macClient: '0.26.3', - gatewayClient: '0.27.3', + macClient: '0.26.4', + gatewayClient: '0.27.4', gatewayBackend: '0.27.0', }); diff --git a/src/web/features/devices/DevicesFeature.tsx b/src/web/features/devices/DevicesFeature.tsx index 6d62ac5..a420dc4 100644 --- a/src/web/features/devices/DevicesFeature.tsx +++ b/src/web/features/devices/DevicesFeature.tsx @@ -245,11 +245,12 @@ export function DevicesToggle({ ; } diff --git a/src/web/features/diagnostics/DiagnosticsFeature.tsx b/src/web/features/diagnostics/DiagnosticsFeature.tsx index df3a00e..044c04a 100644 --- a/src/web/features/diagnostics/DiagnosticsFeature.tsx +++ b/src/web/features/diagnostics/DiagnosticsFeature.tsx @@ -60,11 +60,13 @@ export function DiagnosticsToggle({ onClick={onToggle} > ; diff --git a/src/web/features/instructions/InstructionsFeature.tsx b/src/web/features/instructions/InstructionsFeature.tsx index bdd59f3..9303c68 100644 --- a/src/web/features/instructions/InstructionsFeature.tsx +++ b/src/web/features/instructions/InstructionsFeature.tsx @@ -249,9 +249,13 @@ export function InstructionsToggle({ onClick={onToggle} > ; } diff --git a/src/web/features/routing/RoutingFeature.tsx b/src/web/features/routing/RoutingFeature.tsx index 8d094ea..890460d 100644 --- a/src/web/features/routing/RoutingFeature.tsx +++ b/src/web/features/routing/RoutingFeature.tsx @@ -832,10 +832,12 @@ export function RoutingToggle({ > ); diff --git a/src/web/styles/primitives.css b/src/web/styles/primitives.css index 38f5393..0dc0589 100644 --- a/src/web/styles/primitives.css +++ b/src/web/styles/primitives.css @@ -76,16 +76,26 @@ .client-rail-subscription-back, .client-rail-subscription-front, -.client-rail-info-ring, -.client-rail-info-mark, -.client-rail-device-monitor, -.client-rail-device-phone, +.client-rail-book-page-position, +.client-rail-book-spine, +.client-rail-device-link, .client-rail-device-bridge, +.client-rail-diagnostics-position, +.client-rail-rule-knob-position { + transform-box: fill-box; + transform-origin: center; + transition: transform var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1), opacity 260ms ease, stroke-dasharray var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1), stroke-dashoffset var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1); +} + +.client-rail-book-page, .client-rail-diagnostics-glass, .client-rail-rule-knob { transform-box: fill-box; transform-origin: center; - transition: transform var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1), opacity 260ms ease, stroke-dasharray var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1), stroke-dashoffset var(--client-rail-state-duration) cubic-bezier(0.16, 1, 0.3, 1); +} + +.client-rail-book-page.is-right { + transform-origin: left center; } .client-rail-action .client-rail-subscription-card, @@ -105,17 +115,20 @@ transform: translate(-2px, 1px); } -.client-rail-info-ring { - stroke-dasharray: 1 0; - stroke-dashoffset: 0.1; +.client-instructions-toggle.is-open .client-rail-book-page-position.is-left { + transform: translateX(-1.25px) rotate(-2.5deg); } -.client-instructions-toggle.is-open .client-rail-info-ring { - stroke-dasharray: 0.9 0.1; +.client-instructions-toggle.is-open .client-rail-book-page-position.is-right { + transform: translateX(1.25px) rotate(2.5deg); } -.client-instructions-toggle.is-open .client-rail-info-mark { - transform: translateY(-1px); +.client-instructions-toggle.is-open .client-rail-book-spine { + transform: scaleY(1.06); +} + +.client-rail-device-link { + opacity: 0.68; } .client-rail-device-bridge { @@ -124,10 +137,8 @@ } .client-rail-subscription-scan, -.client-rail-info-sweep, .client-rail-device-packet, -.client-rail-diagnostics-scan, -.client-rail-rule-scan { +.client-rail-diagnostics-scan { stroke-width: 2.4; opacity: 0; stroke-dasharray: 0.18 0.82; @@ -138,12 +149,8 @@ stroke-dasharray: 0.36 0.64; } -.client-devices-toggle.is-open .client-rail-device-monitor { - transform: translateX(1px); -} - -.client-devices-toggle.is-open .client-rail-device-phone { - transform: translateX(-1px); +.client-devices-toggle.is-open .client-rail-device-link { + opacity: 1; } .client-devices-toggle.is-open .client-rail-device-bridge { @@ -151,28 +158,42 @@ transform: scaleX(1); } -.client-diagnostics-toggle.is-open .client-rail-diagnostics-glass { - transform: translate(1px, -1px) rotate(-4deg); +.client-rail-diagnostics-trace { + opacity: 0.72; } -.client-local-rules-toggle.is-open .client-rail-rule-knob.is-top { - transform: translateX(2px); +.client-diagnostics-toggle.is-open .client-rail-diagnostics-position { + transform: translate(2px, -1px) rotate(-7deg); } -.client-local-rules-toggle.is-open .client-rail-rule-knob.is-bottom { - transform: translateX(-2px); +.client-local-rules-toggle.is-open .client-rail-rule-knob-position.is-top { + transform: translateX(4px); +} + +.client-local-rules-toggle.is-open .client-rail-rule-knob-position.is-bottom { + transform: translateX(-4px); } .client-subscription-toggle.is-open .client-rail-subscription-scan, -.client-instructions-toggle.is-open .client-rail-info-sweep, .client-devices-toggle.is-open .client-rail-device-packet, -.client-diagnostics-toggle.is-open .client-rail-diagnostics-scan, -.client-local-rules-toggle.is-open .client-rail-rule-scan { +.client-diagnostics-toggle.is-open .client-rail-diagnostics-scan { animation: client-rail-ambient-trace 10s 1.1s linear infinite; } -.client-local-rules-toggle.is-open .client-rail-rule-scan.is-bottom { - animation: client-rail-ambient-trace 10s 1.32s linear infinite; +.client-instructions-toggle.is-open .client-rail-book-page.is-right { + animation: client-rail-book-turn 10s 1.1s ease-in-out infinite; +} + +.client-diagnostics-toggle.is-open .client-rail-diagnostics-glass { + animation: client-rail-glass-scan 10s 1.1s ease-in-out infinite; +} + +.client-local-rules-toggle.is-open .client-rail-rule-knob.is-top { + animation: client-rail-rule-tune-top 10s 1.1s ease-in-out infinite; +} + +.client-local-rules-toggle.is-open .client-rail-rule-knob.is-bottom { + animation: client-rail-rule-tune-bottom 10s 1.28s ease-in-out infinite; } @keyframes client-rail-ambient-trace { @@ -182,6 +203,28 @@ 10%, 100% { opacity: 0; stroke-dashoffset: 0; } } +@keyframes client-rail-book-turn { + 0%, 2%, 10%, 100% { transform: translateX(0) scaleX(1); } + 5% { transform: translateX(-1px) scaleX(0.18); } + 7% { transform: translateX(-0.5px) scaleX(0.55); } +} + +@keyframes client-rail-glass-scan { + 0%, 2%, 10%, 100% { transform: translateX(0) rotate(0); } + 4% { transform: translateX(-3px) rotate(6deg); } + 7% { transform: translateX(1.5px) rotate(-3deg); } +} + +@keyframes client-rail-rule-tune-top { + 0%, 2%, 10%, 100% { transform: translateX(0); } + 6% { transform: translateX(-2px); } +} + +@keyframes client-rail-rule-tune-bottom { + 0%, 2%, 10%, 100% { transform: translateX(0); } + 6% { transform: translateX(2px); } +} + .client-local-rules-toggle:disabled { cursor: default; color: var(--client-muted); diff --git a/test/web/responsive-layout-contract.test.js b/test/web/responsive-layout-contract.test.js index eadff38..73c5914 100644 --- a/test/web/responsive-layout-contract.test.js +++ b/test/web/responsive-layout-contract.test.js @@ -140,31 +140,34 @@ test('secondary menus share one right rail and switch equal drawers as a vertica assert.match(disabledRulesLabel, /filter:\s*blur\(5px\)/); assert.match(styles, /\.client-local-rules-toggle:disabled:hover span\s*\{[\s\S]*opacity:\s*1/); assert.match(subscription, /client-rail-subscription-back[\s\S]*client-rail-subscription-front[\s\S]*client-rail-subscription-lines[\s\S]*client-rail-subscription-scan/); - assert.match(instructions, /client-rail-info-ring[\s\S]*client-rail-info-sweep[\s\S]*client-rail-info-mark/); + assert.match(instructions, /client-rail-book-page-position is-left[\s\S]*client-rail-book-page is-left[\s\S]*client-rail-book-page-position is-right[\s\S]*client-rail-book-page is-right[\s\S]*client-rail-book-spine/); assert.match(component, / { const witnesses = readStyleWitnesses(root); - assert.equal(witnesses.length, 859); + assert.equal(witnesses.length, 863); assert.equal(witnesses.filter((witness) => witness.unknown || witness.ancestorUnknown).length, 0); const ledger = createStyleLedger(readStyleSource(root), { witnesses }); assert.deepEqual(ledger.counts, acceptedLedger.counts); @@ -405,8 +405,8 @@ test('main owns one public stylesheet and the regrouped production CSS is determ assert.equal((main.match(/import ['"][^'"]+\.css['"]/g) || []).length, 1); const assets = fs.readdirSync(path.join(root, 'dist/assets')).filter((file) => file.endsWith('.css')); - assert.deepEqual(assets, ['index-CAi7iXH5.css']); + assert.deepEqual(assets, ['index-BlKS5cQQ.css']); const built = fs.readFileSync(path.join(root, 'dist/assets', assets[0])); - assert.equal(built.byteLength, 135653); - assert.equal(sha256(built), '15cb8f4597c16fd8ba119395b1246e3cf9362fc24988aecd6a08a0666fb53d46'); + assert.equal(built.byteLength, 136693); + assert.equal(sha256(built), '3486f1e09a97e1293d7cdd4c7661b994bda1f388c1560518657da1b3a8318d6e'); });