diff --git a/docs/current-readiness.md b/docs/current-readiness.md index 81448986..dbaf82af 100644 --- a/docs/current-readiness.md +++ b/docs/current-readiness.md @@ -1,19 +1,125 @@ # Current daily-use readiness -The named accepted-main and verified delivery checkpoint is -[`912074f1`](https://github.com/xandreeddev/desktop-lab/commit/912074f1678b67b789b75217ea253d40dd327e73), -through [PR115](https://github.com/xandreeddev/desktop-lab/pull/115). -[Pages40414422493](https://github.com/xandreeddev/desktop-lab/actions/runs/40414422493) +The current accepted-main delivery checkpoint is +[`c3007cc5`](https://github.com/xandreeddev/desktop-lab/commit/c3007cc5cefc5faab36f751a28542898ecefac0d), +through [PR116](https://github.com/xandreeddev/desktop-lab/pull/116). +[Pages40418504442](https://github.com/xandreeddev/desktop-lab/actions/runs/40418504442) passes three exact public HTML artifact matches and the native manifest/PNG: -**118 producer inputs and 480 captures from source 3640bd86** (public receipt -`695a4c42b0f018eaf0339d947bf2814c8c1440deb1437bea55a22c133e8e23ea`). -Twenty same-artifact LAN HTTP checks pass, retaining the 64/128 MiB static-server -limits (receipt `7f47d1a2d4c22760cdc8b337d65d581a2e4d424387dd73b659493042067833db`). -Earlier 9d42/PR114/Pages40396627106 served 4a0f932a's **117** producers; -ca88/Pages40392718403 served b3c91fab's **116**. Those checkpoints remain historical. -This later focus-investigation, CI and delivery reconciliation still needs its own -final build, protected-main merge and publication. Delivery establishes no native -keyboard fix or performance acceptance. +**118 producer inputs and 480 captures from source 3640bd86**. Twenty +same-artifact LAN HTTP checks pass with the 64/128 MiB static-server limits. +These are delivery checks, not native keyboard or performance acceptance. +Earlier 912/PR115, 9d42/PR114 and ca88 checkpoints remain historical. + +The latest recorded coherent VM release is source **d77f3d0b2caf**, built by +[hosted Arch run40448216820](https://github.com/xandreeddev/desktop-lab/actions/runs/40448216820). +It passes 17 qualification stages, 885 targeted tests and 99 required named +regressions, fresh software-Vulkan export and static compatibility for all ten +ELF consumers. The independent ABI review and coherent six-client/root-greeter +deployment pass without restarting greetd or writing settings/themes. Its +[sanitized source-specific report](../reports/measurements/lucent-keyboard-control-flush-d77.json) +keeps this installation separate from accepted main and PR117's ba5 source. + +The d77 input results are mixed. The held-button case still sends the first key +to the browser. A completed click delivers the first key to Notes, with native +focus, a visible caret and ordinary undo. The corrected complete-flow trial then +fails the outside handoff: the browser receives trusted pointer down/up/click, +but the following key reaches Notes. All nine restorations pass in each of the +three trials. Reacquisition remains unattempted. Host command order does not prove +guest delivery order across the VM's USB tablet and PS/2 keyboard; that chronology +and the failure cause remain unmeasured. A finite read-only guest-input diagnostic +is being prepared. The later [original canonical d77 URI trial](../reports/measurements/lucent-cold-default-uri-d77.json) +passes both pointer and Tab/Enter routes, including one trusted unmodified +nonrepeat KeyA and all three feature/nine cleanup checks per route. It preserves +the same normal desktop lifetime and uses independent cold browser births. This +new execution accepts that controlled handoff; no widget focus fix, lock/login +regression or performance acceptance is inherited from the earlier source. + +The subsequent [closed V10 input-order diagnostic](../reports/measurements/lucent-widget-input-order-d77.json) +shows the guest receiving the outside KeyA **4.332 ms before** the tablet press, +despite the host sending click commands first. The cursor also remains at the +previous Notes point, so the intended browser target is not reached. The first +Notes key arrives 33.278 ms after its guest press and ordinary undo passes. The +observer closes both descriptors with balanced complete packets and no drop. +Eight restoration checks pass; cursor restoration fails because the owned move +was not confirmed. The normal desktop/settings are restored, but the original +cursor point was not persisted and no later cursor recovery is claimed. This +case establishes a test-transport problem, not a Lucent focus failure. Correct +physical-pointer preparation and guest delivery ordering need a separate trial; +compositor processing and earlier trials' guest order remain unknown. + +The earlier coherent VM release is source **ba5b8a51f960**, built by +[hosted Arch run40433468095](https://github.com/xandreeddev/desktop-lab/actions/runs/40433468095). +Its **17 qualification stages, 880 targeted tests and 94 required named +regressions pass**. All ten ELF consumers pass static import compatibility; +the separate review of 134 FFmpeg public headers finds 129 identical files and +five version-literal changes, with no unresolved header/layout issue for this +trial. Deployment verifies all six user clients and the root greeter beyond +the startup deadline, preserves settings/security and does not restart greetd +or write settings/themes. The verified b2 cohort remains the rollback baseline. +See the [sanitized release report](../reports/measurements/lucent-keyboard-intent-ba5-release.json). + +The same build produces a fresh **CPU software-Vulkan** catalogue: llvmpipe, +121 producer inputs, nine stories, five palettes and 480 PNGs. The committed +catalogue preserves the actual ba5 manifest. All 480 PNG hashes differ from the +older RADV captures; 18 paired examples across all nine stories at 1×/2× show a +maximum normalized peak error of about 2/255. Four visual pairs show no visible +layout, caret or clipping regression. This sampled comparison does not establish +all-480 decoded-pixel parity, native GPU behavior or performance. PR117 carries +these captures; their new Pages publication is not yet verified. + +The first Notes controller attempt stops before typing with a bounded-command +harness failure and no feature checks. All nine restoration checks pass, +including guarded settings/source restoration and a 35-second normal restart. +Its earlier normal process is intentionally retired. A fresh identity was then +bound for the original [canonical cold URI trial](../reports/measurements/lucent-cold-default-uri-ba5.json): +both pointer and Tab/Enter routes pass all three feature checks, each exact cold +document receives one trusted, unmodified, nonrepeat `KeyA`, and each case passes +all nine cleanup checks. No forced focus, prewarming or cursor workaround is used. +This accepts the controlled cold URI handoff on one FHD virtual output. +The corrected [V7 first-key trial](../reports/measurements/lucent-widget-first-key-ba5.json) +fails immediate Notes input. Notes gains logical focus and one native Enter with +requested and committed `OnDemand`, but the first trusted `KeyA` reaches the +owned browser. The host down-to-key transport interval is 31.625 ms; guest +callback and request timing were not measured. All nine restoration checks pass. +Outside-click and reacquisition were not attempted. Earlier V4–V6 failures remain +recorded, but their combined down/up QMP call did not publish a pressed USB +report. The later [V8 trial](../reports/measurements/lucent-widget-completed-click-ba5.json) +completes the click before sending KeyA and also fails: Notes gains logical/native +focus, while the owned browser receives the first key. Its host down-to-key +interval is 66.634 ms, including release transport; all nine restorations pass. +The V7 held-button result remains unchanged. No outside-click or reacquisition +result is accepted. The later d77 candidate and its mixed native results are recorded above; +whole-flow keyboard acceptance remains open. Eligible memory and FPS acceptance +remain separate. + +The [separate native lock trial](../reports/measurements/lucent-native-lock-ba5.json) +observes a new compositor acknowledgement, the exact native locker, wallpaper +pause and one ordinary authenticated unlock. Its exit-status assertion fails; +the later systemd code is zero and the native exit status remains unavailable. +A separate read-only check verifies the same normal desktop, unchanged file and +security fingerprints, restored playback and all tracing OFF. The original failed +result remains unchanged. + +The new [V3 lock/PAM regression](../reports/measurements/lucent-native-lock-ba5-v3.json) +passes all six checks. A private unit reference retains the exact native +invocation through normal exit, with exit status0 and positive execution history. +The same notifier connection observes lock acknowledgement and unlock; the +reference is released, and the normal runtime, files, security, playback, idle +policy and geometry remain unchanged. An intervening V2 preflight fails before +any lock or password because an empty initial InvocationID was misread. Both +earlier failures remain recorded. This scoped pass does not establish login, +secure-client pixels, suspend, physical hardware or performance. + +The historical [actual b2 cold-browser trial](../reports/measurements/lucent-cold-default-uri-b2.json) +passes canonical pointer opening and trusted document input, while Tab/Enter +still fails browser focus/key delivery. All nine cleanup checks pass in each +case. The new native observer sees Clock regain keyboard focus after history +closes; Clock/Calendar had committed `None` during history and subsequently +restored `OnDemand`. The candidate [explicit widget-focus implementation](keyboard-focus.md) +separates capability, demand and native ownership. Its source qualification, +visual export and coherent candidate deployment pass. The new original canonical +cold URI trial accepts pointer and keyboard handoff in that controlled scope; +first-click widget, secure-session and broader application checks remain separate. Archived resource and earlier feature observations below retain `eb3481f4` and their other named sources. At the earlier [PR110](https://github.com/xandreeddev/desktop-lab/pull/110) @@ -24,8 +130,8 @@ Earlier checkpoints remain in [the ledger](implementation-status.json). The core Wi-Fi repair, safe display editing, international text and explicit application-opening paths are implemented with scoped native evidence. The -seven-gap goal is **not complete**: cold keyboard handoff, eligible ≤300 MiB and -source-rate presentation acceptance, physical devices and broader application +seven-gap goal is **not complete**: eligible ≤300 MiB and source-rate presentation +acceptance, physical devices and broader application interoperability remain open. Delivery and a green test suite do not establish those results. @@ -34,9 +140,9 @@ Candidate `3640bd86c6ec` implements the typed keyboard policy described in [default-handler activation](default-uri-activation.md). Its coherent build completes **17 stages and 823 targeted test passes**. A separate actual AMD RADV offscreen export covers **118 producers, nine stories, five -palettes and 480 PNGs**, all byte-identical to the prior RADV reference. The -candidate is now coherently deployed: all six user clients and the root greeter -are verified, with user/settings/security state preserved and no greetd restart. +palettes and 480 PNGs**, all byte-identical to the prior RADV reference. That +candidate's deployment verified all six user clients and the root greeter, +with user/settings/security state preserved and no greetd restart. The actual [cold-browser source 3640 run](../reports/measurements/lucent-cold-default-uri-3640.json) passes pointer opening and one trusted `KeyA`; the separate Tab/Enter route still fails browser focus/key delivery. Both owned cleanups pass all nine checks. The @@ -59,14 +165,16 @@ member-aware widget suppression and read-only native keyboard diagnostics. Exact b2 passes the Ubuntu [Rust job](https://github.com/xandreeddev/desktop-lab/actions/runs/40411820911/job/121884163923) in [CI run40411820911](https://github.com/xandreeddev/desktop-lab/actions/runs/40411820911): workspace/protocol/software-Vulkan suites and all 17 individually verified new -tests pass. A coherent Arch release, candidate VM deployment and native keyboard -acceptance remain pending. See +tests pass. The later coherent Arch release and deployment now pass as recorded +above; the actual b2 canonical keyboard trial still fails. See [the activation guide](default-uri-activation.md#focus-geometry-and-cursor-only-diagnostic) for the requested-versus-committed ordering limitation. The seven-gap goal stays open. -The 118 source3640 capture inputs are now published at main912, separate from -historical 9d42's 117 inputs and ca88/b3's 116 inputs. This does not deploy the b2 -widget policy or diagnostic runtime to the VM. +The 118 source3640 capture inputs are published at the c300 delivery checkpoint, +separate from historical 9d42's 117 inputs and ca88/b3's 116 inputs. The b2 runtime +was deployed in a separate verified transaction. PR117 now commits the actual +ba5 catalogue with 121 inputs; its deployment is another separately verified +transaction. Publishing captures does not perform either deployment. The recent changes add: @@ -155,6 +263,33 @@ I/O pressure and null targets. Separate driver/restore receipts verify original source/security/settings and return to normal profiling OFF. This adds no eligible 60 FPS or causal CPU-reuse gain and leaves the original memory matrix unchanged. +## Isolated decoder retarget experiment + +The [f26 hosted experiment](../reports/measurements/lucent-decoder-retarget-f26.json) +compares reopening with one retargeted decoder, using the same genuine imported +4K60 H.264 asset and backend source `1aebe2e3`. Actual source gates pass +37 domain, 67 video and 21 observer tests, plus 15 experiment-consumer tests. +Four fresh nonoverlapping processes pass the original PTS, aspect, revision, +12-second phase and cancellation/join checks. Allocator snapshots are taken only +while playback is stopped. + +| End-of-hold restored FHD RSS | Reopen | Retarget | +| --- | ---: | ---: | +| Cold FHD → 4K → FHD | 197.38 MiB | 176.13 MiB | +| Source size → FHD → 4K → FHD | 229.21 MiB | 269.34 MiB | + +The result is mixed. After the final source-size frame is dropped, retarget still +uses 8.98 MiB more RSS. Accounted in-use bytes are nearly equal, while its free +arena total is 10.63 MiB higher. This is consistent with additional arena +retention; it does not prove the complete allocation cause. The latest FHD frame +capacity is exactly 8,294,400 bytes in both paths. Old-last-good and in-flight +ownership are not separately instrumented. + +These are finite decoder-only observations on a hosted CPU, with no compositor, +renderer or whole desktop. They establish functional one-worker retargeting but +**no general memory improvement**, ≤300 MiB desktop acceptance or display FPS. +Production target-only client wiring remains disabled pending further work. + ## Read-only host service observations The [host observer report](../reports/measurements/lucent-host-service-observations-6f9.json) @@ -441,7 +576,7 @@ ledger's requirement history remains useful for the broader backlog. | Safe display settings | Native whole-layout drafts, Apply → Keep/Revert and independent 15-second/UI-crash EOF rollback. Seven earlier one-output flows and the historical four-flow two-output run retain their results. The later [nine-flow run](../reports/measurements/lucent-native-two-output-displays-26d-nine.json), harness `1774fa87` on runtime `26d03adf`, also covers rotation, disable/re-enable, fractional scale Keep and native pointer/keyboard input on a scale-1.25 Displays panel. Five positive preservation checks, one explicit ctime/link-count scope marker, three cursor checks and independent later normal-OFF verification pass. | Physical displays/cable hotplug, suspend/resume, compositor restart, secure-output changes and pacing remain open. Monitor ctime, link count and parent entry timestamps are not claimed unchanged. Earlier failed attempts remain failed; their separate recoveries are not feature passes. The Keep-to-file-identity-capture host-loss interval retains manual recovery. | | Resources and animation | The new [same-runtime eb348 matrix](../reports/measurements/lucent-output-resource-matrix-eb348.json) completes cold FHD →4K →restored warm FHD with preservation/all tracing OFF. Mean/peak RSS is 229.181/230.875, 494.683/526.516 and 435.063/435.063 MiB respectively; all host-pressure-ineligible. Earlier 9eb/26d/35ed and shape/presentation reports retain their own values and limitations. | Warm FHD memory remains elevated even after current-frame/prepared-image payloads return to FHD values. Isolate pool/codec/staging/allocator/driver ownership; collect eligible resource and presentation evidence. Overlapping payload/RSS counters, same-runtime sequencing and VMA labels do not establish cause, leak, CPU-reuse gain, visible pixels or physical scanout. Preserve earlier failed attempts and independent recoveries. | | International text | Merged `8e6d074b` implements script shaping, hard-paragraph context across soft wraps, exact row-bound visual source/caret maps, tab separator projection, deterministic fallback and opt-in text-input-v3 composition. Five owned native feature checks pass: visible preedit/caret advance, CJK commit/delete/history, masked-focus retirement, multiline composition and RTL navigation. | The fresh owned native suite passes all five feature and five restoration checks; earlier cleanup failures retain their original results. Third-party IME, broader native pixel/scroll details, delayed clipboard/focus races, physical/cross-output text and broader GUI clipboard coverage remain pending. The later Chromium/Notes test passes both directions with nine interaction and twelve restoration checks on one virtual output. Exact merged `8e6d074b` passes six CI checks, full workspace, six controlled service-protocol filters and 832 Vulkan desktop cases; those checks retain their own scope. | -| Application integration | Accepted main includes fresh input-bound context, explicit file/URI Open, expanded XDG parsing and the canonical default-handler `UriPort::open(target, context)` path. Notification links use the SDK's optional app ID and revalidate their revision/link around token delivery; `XdgUri` forwards that context through the shared application-unit policy. Earlier local-file `8e` and HTTP `%U` `9b` results keep their original scope. The `4c9a4739` harness on coherent `35ed` passes **twelve singular HTTP `%u` feature and nine restoration checks**: pointer, socket and CLI Open each create exactly one fresh owned HTTP document; the declared Action still creates two local documents. The later [R9 default-route run](../reports/measurements/lucent-default-uri-native-26d.json), harness `563781a2` on `26d03adf`, passes five scoped checks and nine cleanup checks: native pointer and Tab/Enter each load one exact selected document through the temporary default handler with fresh context, using an already warm real browser. PR105 accepts source fix `194c0c57`; the later [9eb run](../reports/measurements/lucent-runtime-9eb-native-trial.json) separately passes five route/nine cleanup checks and both trusted browser KeyA cases after natural history close, using the same controlled warm-browser scope. The coherently deployed unmerged [source 3640 trial](../reports/measurements/lucent-cold-default-uri-3640.json) passes the cold pointer route but fails the separate keyboard route; all nine cleanup checks per route pass. | The current cold keyboard route fails browser focus/trusted KeyA delivery despite the last pre-key history/input/frame guards passing. Its missing event and post-event observations remain null, and the cause and a fix are unestablished. Historical warm-browser delivery and the older R9 active-window observation keep their own scopes. Direct protocol-token consumption, external navigation, other handlers/applications and broader workflows remain open. Historical explicit-application and failed default-route reports keep their source/input/cleanup outcomes. Application acceptance does not accept performance. | +| Application integration | Accepted main includes fresh input-bound context, explicit file/URI Open, expanded XDG parsing and the canonical default-handler `UriPort::open(target, context)` path. Notification links use the SDK's optional app ID and revalidate their revision/link around token delivery; `XdgUri` forwards that context through the shared application-unit policy. Earlier local-file `8e` and HTTP `%U` `9b` results keep their original scope. The `4c9a4739` harness on coherent `35ed` passes **twelve singular HTTP `%u` feature and nine restoration checks**: pointer, socket and CLI Open each create exactly one fresh owned HTTP document; the declared Action still creates two local documents. The later [R9 default-route run](../reports/measurements/lucent-default-uri-native-26d.json), harness `563781a2` on `26d03adf`, passes five scoped checks and nine cleanup checks: native pointer and Tab/Enter each load one exact selected document through the temporary default handler with fresh context, using an already warm real browser. PR105 accepts source fix `194c0c57`; the later [9eb run](../reports/measurements/lucent-runtime-9eb-native-trial.json) separately passes five route/nine cleanup checks and both trusted browser KeyA cases after natural history close, using the same controlled warm-browser scope. The coherently deployed unmerged [source 3640 trial](../reports/measurements/lucent-cold-default-uri-3640.json) passes the cold pointer route but fails the separate keyboard route; all nine cleanup checks per route pass. | The later [ba5 canonical trial](../reports/measurements/lucent-cold-default-uri-ba5.json) passes both original cold routes, one trusted nonrepeat KeyA and all nine cleanup checks per case on one FHD virtual output. It supersedes the blanket cold-keyboard blocker only for that source and controlled workflow. Historical missing events remain null; first-click widgets and secure-session checks remain separate. Historical warm-browser delivery and the older R9 active-window observation keep their own scopes. Direct protocol-token consumption, external navigation, other handlers/applications and broader workflows remain open. Historical explicit-application and failed default-route reports keep their source/input/cleanup outcomes. Application acceptance does not accept performance. | | Real-world validation | [Two virtual outputs](../reports/measurements/lucent-native-multi-output.json) pass sixteen native checks on `8e`; [nine Display workflows](../reports/measurements/lucent-native-two-output-displays-26d-nine.json) pass on `26d`, including fractional-panel input. Unchanged `8e` passes [genuine wired-only tray](../reports/measurements/lucent-native-third-party-tray-8e.json) five interaction/four cleanup/thirteen preservation checks, [Chromium–Notes clipboard](../reports/measurements/lucent-native-gui-clipboard-2044.json) nine interaction/twelve restoration checks, and [owned mapped-peer IME](../reports/measurements/lucent-international-text.json) five feature/five restoration checks. Earlier software-HCI Bluetooth and virtual audio control results keep their sources. | Physical monitors/cable hotplug, actual sleep/secure resume, physical keyboard/radio/pairing and audible output/microphone/routing remain open. Additional tray apps/menus, third-party IMEs, other GUI clipboard apps/rich content, delayed-provider/focus races and cross-output text/clipboard need execution. [Suspend inspection](../reports/measurements/lucent-suspend-prerequisites.json) issued no sleep request; [host counts](../reports/measurements/lucent-host-service-observations-6f9.json) sent no input/controls. Historical passes do not accept candidate `3640` or performance. | | Documentation accuracy | Named accepted main `9d42c20e`/PR114, [Pages40396627106](https://github.com/xandreeddev/desktop-lab/actions/runs/40396627106) and same-artifact LAN receipt `dbd81b26…` verify three HTML pages, native manifest/PNG, **117 inputs/480 captures from `4a0f932a`**, and twenty HTTP checks. Prior ca88/b3/116 delivery remains historical. Active evidence separates virtual outputs, genuine applications, owned peers and physical devices; failed reports keep their flags. | This later framework/text/URI/ledger reconciliation needs its own final build/link/Pages checks and protected-main delivery. Publication supplies no extra native controls, physical interoperability, eligible performance or full-goal acceptance. | diff --git a/docs/daily-use-completion.json b/docs/daily-use-completion.json index 4de84dfe..4f1f0d34 100644 --- a/docs/daily-use-completion.json +++ b/docs/daily-use-completion.json @@ -155,9 +155,16 @@ "sha256": "602bf9bc5613fd20bdb6a22ce574215cc3fec4d9a12459202ca90761c1b293b3", "source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", "scope": "Source 3640 completes 17 build stages and 823 targeted tests and coherent six-client/root-greeter VM deployment with state/security preservation. The actual canonical cold pointer route passes; the separate Tab/Enter route fails browser focus/trusted KeyA delivery. Last pre-key history/input/frame guards and all nine cleanup checks per route pass. This is no keyboard fix, accepted-main promotion, broader-handler or performance acceptance." + }, + { + "kind": "coherent-candidate-original-canonical-cold-URI-native-result", + "path": "reports/measurements/lucent-cold-default-uri-ba5.json", + "sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "scope": "Both original pointer and Tab/Enter routes pass three feature checks, one trusted unmodified nonrepeat KeyA and nine cleanup checks per case on one FHD virtual output, with independent cold browser births. No forced focus/cursor workaround, broader handler, widget, secure-session, hardware or performance acceptance." } ], - "current_scope": "Historical build-only and warm-route entries retain their original source scopes. The deployed unmerged source 3640 candidate passes the canonical cold pointer route but still fails keyboard focus/KeyA delivery. Missing keyboard event/post-event observations remain null; both cleanups pass. Protocol/client tests and coherent deployment establish no keyboard fix or failure cause. Broader real-application workflows remain open." + "current_scope": "Historical failures and warm-route entries retain their source scopes. The deployed ba5 candidate now passes both original canonical cold routes and every owned cleanup. Native input-release observation remains distinct from destination-focus and direct token-consumption guarantees; first-click widget behavior, secure sessions and broader real-application workflows require separate evidence." }, { "id": "real-world-validation", @@ -391,6 +398,77 @@ "scope": "Named ca88 Pages artifact/public bytes and same-artifact LAN checkpoint. Accepted main has advanced to9d42/PR114; its publication and this later reconciliation require their own exact delivery proof. This does not establish native/device/performance acceptance." } ], - "last_evidence_update_utc": "2026-10-26T21:36:25.415700+00:00" + "last_evidence_update_utc": "2026-10-26T21:36:25.415700+00:00", + "keyboard_focus_intent_ba5_canonical_URI": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "global_seat_owner_observed": false, + "direct_protocol_token_consumption_established": false, + "broader_widget_secure_hardware_or_performance_acceptance": false, + "accepted_main_at_capture": false + }, + "keyboard_focus_intent_ba5_first_key": { + "report": "reports/measurements/lucent-widget-first-key-ba5.json", + "report_sha256": "a95916d4d1cb4082984475378ca27157bac68a021979b0ce4a60efc3f0582828", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "status": "corrected_native_first_key_delivery_failed", + "host_down_to_key_transport_ms": 31.62471897667274, + "Notes_logical_and_native_focus_observed_after_input": true, + "controlled_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "control_flush_candidate_native_verified": false + }, + "keyboard_focus_intent_ba5_native_lock": { + "report": "reports/measurements/lucent-native-lock-ba5.json", + "report_sha256": "af160b848c92e1d0a9453be672656f2b1e8f5c21e39df97db5fb078c103b9f61", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": false, + "native_lock_and_authenticated_unlock_observed": true, + "exit_status_assertion_failed": true, + "native_exit_status": null, + "later_same_runtime_files_security_and_playback_preserved": true + }, + "keyboard_focus_intent_ba5_completed_click_V8": { + "report": "reports/measurements/lucent-widget-completed-click-ba5.json", + "report_sha256": "9cc6005267544dd4c8a8b33ef7741b148ef9ac949a521ea955a61d7062e34465", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "first_key_delivery_passed": false, + "gesture_contract": "completed-click-then-immediate-key", + "host_down_to_key_transport_ms": 66.63447699975222, + "Notes_logical_and_native_focus_observed_after_input": true, + "owned_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "native_control_flush_fix_accepted": false, + "V7_held_button_result_unchanged": true + }, + "keyboard_focus_intent_ba5_native_lock_V3": { + "report": "reports/measurements/lucent-native-lock-ba5-v3.json", + "report_sha256": "c39c4a2d1b8d87935b809b95388858832b6f557132024c51806e2c18e50cd1b9", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": true, + "checks_passed": 6, + "same_connection_new_locked_ACK_and_one_PAM_unlock": true, + "retained_same_invocation_exited_normally": true, + "exit_status": 0, + "reference_released": true, + "same_runtime_files_security_playback_idle_and_geometry_preserved": true, + "login_pixels_suspend_hardware_or_performance_accepted": false, + "V1_and_V2_failures_unchanged": true + } } } diff --git a/docs/default-uri-activation.md b/docs/default-uri-activation.md index 56c3bb48..2787c40a 100644 --- a/docs/default-uri-activation.md +++ b/docs/default-uri-activation.md @@ -128,8 +128,10 @@ passes its coherent 17-stage build and 823 targeted tests, including the protoco and client regressions, and is coherently deployed as an unmerged VM candidate. Its [cold-browser trial](../reports/measurements/lucent-cold-default-uri-3640.json) passes pointer opening and trusted document `KeyA`, but the separate Tab/Enter -route still fails browser focus and key delivery. The new ordering has no verified -keyboard fix. Earlier native outcomes and cleanup flags remain unchanged. +route still fails browser focus and key delivery. That source's input-release +ordering alone has no verified keyboard fix. The later ba5 result below accepts +the original cold routes after explicit widget-demand ownership; earlier native +outcomes and cleanup flags remain unchanged. ## Separate cold-browser acceptance @@ -264,3 +266,50 @@ and twenty same-artifact LAN checks verify publication, including source3640's 118 producer inputs and 480 native catalogue captures. This named delivery checkpoint does not publish this later investigation/CI reconciliation or establish candidate VM deployment. See [current readiness](current-readiness.md). + + +## Actual b2 native observation and proposed focus ownership + +The [b2 native report](../reports/measurements/lucent-cold-default-uri-b2.json) +adds actual native keyboard observation to the original independent pointer and +Tab/Enter routes. Pointer passes. Keyboard still fails, and both cases pass all +nine cleanup checks. During history, Clock and Calendar both request and commit +`None`. After history closes, `OnDemand` returns; the keyboard route observes +Clock as the current Lucent native keyboard owner while the browser document +lacks focus. These client observations are not an atomic global seat-owner query. +They establish the observed reacquisition; they do not establish every compositor +ordering detail. + +The new [keyboard-focus guide](keyboard-focus.md) follows the proposed correction: +capability alone creates no widget demand, a genuine prepared control press +creates exact member/output intent, and the optional native backend acknowledges +one-shot acquisition only after real Enter and teardown synchronization. Closing +history does not recreate widget demand. This focus API leaves URI-opening policy +in `UriPort` and notification lifetime policy in the client. The original +canonical URI checks now pass as recorded below. First-click, outside-click and +secure-session checks retain their separate acceptance requirements. + +## Original canonical cold trial on ba5 + +The [ba5 native report](../reports/measurements/lucent-cold-default-uri-ba5.json) +records the original pointer and Tab/Enter routes against the coherently deployed +ba5 release. Each route starts a separate cold owned Chromium birth through the +real temporary default handler. Each opens its exact declared document and +receives exactly one trusted, unmodified, nonrepeat `KeyA`; all three feature +checks and all nine cleanup checks pass in each case. Keyboard navigation sends +two Tab events before Enter. No forced compositor focus, browser prewarming, +extra browser click, hiding or diagnostic cursor reposition is used. + +The sampled Clock and Calendar policies stay requested and committed `None` +after history closes. At browser-map and before/after the key, the owned document +reports focus and the Lucent observer has no current own-client Native. These +are sequential read-only client/DOM observations: an absent Lucent observation +does not identify the compositor's global keyboard owner. Direct input-release +callback timing is unavailable. When the notification surface is absent, the +reported native-frame advancement remains `null` rather than becoming zero. + +This closes the recorded cold-handler keyboard case on one 1920×1080 scale-1 +virtual output. It does not establish direct protocol-token consumption, +arbitrary handlers, first-click Notes or outside-click acquisition, lock/login, +physical hardware, memory targets or animation performance. Earlier b2, 3640 and +eb348 failures remain historical; the cursor-only diagnostic remains a diagnostic. diff --git a/docs/implementation-status.json b/docs/implementation-status.json index 4e5610ca..a17963fa 100644 --- a/docs/implementation-status.json +++ b/docs/implementation-status.json @@ -4,12 +4,12 @@ "status": "in_progress", "completion_rule": "An item is verified only when its behavior, boundary checks, documentation and applicable native integration checks have evidence. Implemented without verification remains incomplete.", "current_rollup": { - "snapshot_source_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", - "snapshot_date": "2026-10-26", + "snapshot_source_commit": "c3007cc5cefc5faab36f751a28542898ecefac0d", + "snapshot_date": "2026-10-27", "status": "in_progress", "all_seven_requested_gaps_closed": false, "guide": "docs/current-readiness.md", - "scope": "Accepted main 9d42 / PR114 has verified Pages 40396627106 and twenty same-artifact LAN checks with 117 producer inputs/480 captures from 4a. Those checkpoints do not publish this later reconciliation. Source 3640 passes 17 build stages and 823 targeted tests, an actual AMD RADV export with 118 producer inputs and 480 PNGs and coherent six-client/root-greeter candidate VM deployment with settings/user/security state preserved. Its canonical cold pointer route passes, but Tab/Enter still fails browser focus/trusted KeyA delivery after history/input/frame guards pass; all nine cleanup checks per route pass. The cause and keyboard fix remain unestablished. This is an unmerged candidate trial, with original archive flags unchanged. Historical eb348/8e/26d evidence retains exact sources and limitations. Physical controls/sleep, broader IME/tray/clipboard/applications, eligible memory at or below 300 MiB and source-rate or 60 FPS animation acceptance remain open; all seven gaps are not closed.", + "scope": "Accepted main c300/PR116 and its published118-input source3640 catalogue remain the delivery checkpoint. Unmerged PR117 sourceba5 has hosted17-stage/880-test qualification,121-input/480-capture CPU software-Vulkan export and coherent candidate deployment. Original canonical cold URI pointer and Tab/Enter pass. Immediate first Notes key fails in separate V7 held-button and V8 completed-click cases despite later logical/native focus; all nine restorations pass per case. V3 passes six scoped native lock/PAM/retained-exit and preservation checks. V1/V2 failures remain unchanged; no login/pixel/suspend, broader application, memory or FPS acceptance follows.", "history_policy": "Requirements, chronological progress and evidence below retain their original source, result and limitations. A later scoped result can supersede an earlier pending summary without rewriting the historical record. This rollup does not repeat older native tests on the snapshot binary.", "evidence_definitions": { "implemented": "Production code path exists; no complete behavior or acceptance claim follows from that label alone.", @@ -635,9 +635,9 @@ }, { "id": "application-integration", - "status": "historical_native_paths_verified_current_cold_keyboard_failed", - "implemented": "Accepted main 6b50bd5e includes catalog/pins, ordinary activation, declared actions and Application bb304907 shipped in merged 8e: fresh input-bound context, explicit file/URI Open and expanded XDG parsing/observation. A later real Chromium run with the independent d1 consumer, now merged through PR89, and b6323e9 harness passes all nine feature checks, including observed first-launch focus, and all eight restoration checks; deployed desktop/CLI remain unchanged. The separate coherent 9b trial passes eleven native HTTP URI and nine restoration checks; pointer, socket and CLI Open each load two fresh exact HTTP targets while the declared Action retains local files. A later 4c harness on coherent 35ed passes 12 singular HTTP %u native feature and 9 restoration checks; pointer/socket/CLI Open each load exactly one fresh owned HTTP document, and the declared Action still loads two local documents. PR102/main 6e471005 now includes canonical UriPort.open(target, ApplicationLaunchContext), optional SDK app ID, revision-bound notification-link completion and shared-policy XdgUri forwarding. R9 harness 563781a2 on runtime 26d passes five scoped warm-browser default-route checks and all nine cleanup checks: temporary MIME selection, native pointer and Tab/Enter input with fresh context, exact one-document delivery and bounded notification expiry. Independent later normal-OFF facts verify the same desktop lifetime and unchanged 14 source/43 security entries. PR105/main 6322 accepts current-session history release. Later source 9eb with harness04432 passes five default-route checks/nine cleanup checks and both actual trusted document KeyA cases after natural notification-history close, without focus/hide intervention; the handler/browser remain controlled and already warm. PR106/main bdffd424 subsequently accepts the complete runtime code by exact Rust/design/configs/scripts tree equality with archived 9eb; this is not another native run. The later unmerged source 3640 adds the typed native input-release effect and passive-toast keyboard policy. Its build/protocol-client tests and coherent VM deployment pass, but the actual canonical cold trial passes pointer and fails keyboard focus/KeyA delivery.", - "remaining": "Historical controlled warm-browser 9eb natural release and trusted-key results retain their source scope. The actual cold source 3640 keyboard route still fails browser focus and trusted KeyA delivery despite passing the pre-key history/modal-release/frame-advance guards; both owned cleanups pass. Establish the cause and a verified fix, then broaden fresh handlers, direct token-consumption and real-application workflows. Cleanup, offscreen rendering and protocol tests establish no performance or hardware target.", + "status": "scoped_ba5_canonical_cold_URI_native_passed_broader_workflows_pending", + "implemented": "Accepted main 6b50bd5e includes catalog/pins, ordinary activation, declared actions and Application bb304907 shipped in merged 8e: fresh input-bound context, explicit file/URI Open and expanded XDG parsing/observation. A later real Chromium run with the independent d1 consumer, now merged through PR89, and b6323e9 harness passes all nine feature checks, including observed first-launch focus, and all eight restoration checks; deployed desktop/CLI remain unchanged. The separate coherent 9b trial passes eleven native HTTP URI and nine restoration checks; pointer, socket and CLI Open each load two fresh exact HTTP targets while the declared Action retains local files. A later 4c harness on coherent 35ed passes 12 singular HTTP %u native feature and 9 restoration checks; pointer/socket/CLI Open each load exactly one fresh owned HTTP document, and the declared Action still loads two local documents. PR102/main 6e471005 now includes canonical UriPort.open(target, ApplicationLaunchContext), optional SDK app ID, revision-bound notification-link completion and shared-policy XdgUri forwarding. R9 harness 563781a2 on runtime 26d passes five scoped warm-browser default-route checks and all nine cleanup checks: temporary MIME selection, native pointer and Tab/Enter input with fresh context, exact one-document delivery and bounded notification expiry. Independent later normal-OFF facts verify the same desktop lifetime and unchanged 14 source/43 security entries. PR105/main 6322 accepts current-session history release. Later source 9eb with harness04432 passes five default-route checks/nine cleanup checks and both actual trusted document KeyA cases after natural notification-history close, without focus/hide intervention; the handler/browser remain controlled and already warm. PR106/main bdffd424 subsequently accepts the complete runtime code by exact Rust/design/configs/scripts tree equality with archived 9eb; this is not another native run. The later unmerged source 3640 adds the typed native input-release effect and passive-toast keyboard policy. Its build/protocol-client tests and coherent VM deployment pass, but the actual canonical cold trial passes pointer and fails keyboard focus/KeyA delivery. The separate coherent ba5 trial passes both original canonical cold pointer and Tab/Enter routes: three feature checks, one trusted unmodified nonrepeat document KeyA and all nine cleanup checks per case, without forced focus or cursor workaround.", + "remaining": "Broaden real handlers/applications and direct protocol-token consumption. Inline-widget first-click/outside-click and secure-session regression are separate from this accepted controlled cold URI workflow. Earlier failed-source and warm-handler outcomes remain unchanged; cleanup and source qualification accept no hardware or performance target.", "guides": [ "docs/application-activation.md", "docs/application-catalog.md", @@ -907,6 +907,24 @@ "scope": "Separate client source validation only. The recorded R9 route result used runtime26d and does not validate this later fix; the prior routes, failures, activewindow observations and cleanup scopes remain unchanged." }, "latest_cold_default_handler_native_attempt": { + "source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "report": "reports/measurements/lucent-cold-default-uri-b2.json", + "overall_passed": false, + "pointer_route_passed": true, + "keyboard_route_passed": false, + "cleanup_checks_passed_each": 9, + "scope": "Historical completed b2 trial; ba5 native focus acceptance is pending." + }, + "current_focus_candidate": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "coherent_deployment_verified": true, + "source_tests_passed": 880, + "canonical_native_pointer_or_keyboard_on_candidate_accepted": false, + "first_Notes_feature_result": null, + "remaining": "Immediate Notes key, ordinary first outside click, reacquisition, canonical cold pointer/TabEnter and secure-session regressions." + }, + "historical_cold_default_handler_native_attempt_3640": { "source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", "report": "reports/measurements/lucent-cold-default-uri-3640.json", "report_sha256": "602bf9bc5613fd20bdb6a22ce574215cc3fec4d9a12459202ca90761c1b293b3", @@ -916,6 +934,23 @@ "cleanup_checks_passed_each": 9, "failure_cause_established": false, "accepted_main_at_trial": false + }, + "latest_canonical_cold_URI_trial": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "global_seat_owner_observed": false, + "direct_protocol_token_consumption_established": false, + "broader_widget_secure_hardware_or_performance_acceptance": false, + "accepted_main_at_capture": false } }, { @@ -929,7 +964,15 @@ "id": "documentation-accuracy", "status": "reconciled_source_evidence_new_revision_delivery_pending", "implemented": "Named 9d42/PR114, Pages 40396627106 and LAN receipt dbd81b26 verify three HTML pages, native manifest/PNG, 117 producer inputs/480 captures from 4a and twenty HTTP responses. Earlier ca88/b3/116 delivery remains historical. The active checklist links 8e/26d virtual outputs, genuine tray/clipboard and owned IME evidence; Bluetooth separates software-HCI controls from physical/profile gaps. Candidate 3640 build/offscreen results retain their own source, without deployment/handoff acceptance.", - "remaining": "This reconciliation/staged guides and later accepted main need their own exact final checks, Astro/root/Pages/link build and protected-main delivery receipts. Prior publication proves only its named source. Physical/native/performance and the full goal remain open." + "remaining": "This reconciliation/staged guides and later accepted main need their own exact final checks, Astro/root/Pages/link build and protected-main delivery receipts. Prior publication proves only its named source. Physical/native/performance and the full goal remain open.", + "latest_reconciliation": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "actual_source_and_deployment_recorded": true, + "actual121_480_catalog_committed": true, + "new_revision_CI_and_Pages_verified": false, + "scope": "Keeps accepted-main delivery, candidate release, offscreen export and native/performance results separate." + } } ], "scoped_native_evidence": [ @@ -1345,13 +1388,46 @@ "physical_hardware_accepted": false, "performance_accepted": false, "scope": "Actual source 3640 candidate cold/default route: pointer receives one trusted KeyA; keyboard reaches its exact document but fails focus/key delivery. Both final pre-key release/frame guards and all nine cleanup checks per case pass. No broader handler, hardware or performance acceptance." + }, + { + "milestone": "ba5-original-canonical-cold-default-URI-accepted", + "status": "both_original_routes_and_each_owned_cleanup_passed", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "summary": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "global_seat_owner_observed": false, + "direct_protocol_token_consumption_established": false, + "broader_widget_secure_hardware_or_performance_acceptance": false, + "accepted_main_at_capture": false + }, + "historical_b2_keyboard_failure_unchanged": true, + "mixed_f26_performance_result_unchanged": true, + "pending": [ + "immediate first Notes key and first outside-click native trial", + "secure lock/login regression", + "broader handlers and direct protocol token consumption", + "eligible desktop resources and source-rate/animation performance", + "protected-main and exact Pages delivery" + ] } ], "deferred_scope": "Accessibility remains deferred by the user; international text and the seven requested gaps are not deferred.", - "validation": "This reconciliation reads exact source3640 build, offscreen export, coherent deployment and cold pointer/keyboard receipts, plus the named9d42 Pages/LAN checkpoint. The current keyboard failure remains a failure, with null missing-event fields and successful cleanup recorded separately. This documentation change adds no native/device/VM action or Node/Cargo build. Local JSON, report-link, privacy and history-preservation checks cover these edits; final source CI, protected-main delivery and publication remain separate.", + "validation": "Actual corrected hosted949/run40433468095 passes17stages/880tests/94required names, fresh3x4500MiB capture admission and121/480 offscreen CPU-Vulkan validation. All10 target ELF imports resolve; concrete134-header review leaves only5version literals. V8 coherent deployment verifies all6user clients/root greeter and state/security preservation. FirstNotes harness stops before typing with0feature checks and9restoration passes; no focus outcome is inferred. Current docs/catalogue need their own exact-headCI/Pages delivery. Historical b2 keyboardFAIL, failed ac07 export and mixed f26 resource results remain unchanged.", "accepted_main_base_commit": "9b52666ba39b2ea2718e72424c37dc8b341051e2", "documentation_harness_base_commit": "c4eb922ca423dfbe255630e8717dc9cb2836a4c2", - "runtime_compilation_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", + "runtime_compilation_source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", "historical_gpu_candidate_preservation_rejection": { "status": "hardware_initialization_observed_preservation_rejected_software_restored", "driver_install_rollback_verified": true, @@ -1393,23 +1469,32 @@ "scope": "This trial remains actual older-a7f guest hardware-path liveness, without sustained FPS, cadence, animation/RSS/GPU-memory/hardware-decoding acceptance. Later coherent 8e deployment and its host-pressure-ineligible resource observation are recorded separately; the prior rejection remains unchanged." }, "coherent_release_build": { - "source_commit": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2", - "manifest_sha256": "e48716b0d7b797292032fec62e3c19219f39184b75221e3249b85633e3812183", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "raw_manifest_sha256": "c3417f557490b0d348dcc7446f881095c13f7e03d9fe0dcbcfa35f2c812e4788", + "localized_manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", "passed": true, - "completed_stages": 15, - "targeted_tests_passed": 786, + "completed_stages": 17, + "targeted_tests_passed": 880, + "required_named_regressions_passed": 94, + "hosted_run": 40433468095, + "workflow_head": "949cc8c954f3de70e91b59c5926b992dad545838", "archive_classification_at_build": { "accepted_main": false, "vm_deployed": false, - "native_activated": false + "native_activated": false, + "runtime_ABI_accepted": false }, - "source_code_equivalent_to_accepted_main": true, - "private_build_receipt_sha256": "6bed8454b64bbcb9513500eea075ee51c0b7ea2ae3955f5ce0f4022234bda170" + "source_code_equivalent_to_accepted_main": false, + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "report_sha256": "a043c857208559e253154e129e26b817043b68347dd1bbc02e6d94f33b0d45c5", + "report_snapshot_commit": "8266efb669d5776f09f43fc288f637cf24a920b2", + "scope": "Actual hosted release and source qualification; original capture-time flags stay unchanged after the separate candidate deployment." }, "coherent_runtime_deployment": { - "source_commit": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2", - "report": "reports/measurements/lucent-output-resource-matrix-eb348.json", - "private_receipt_sha256": "1ec5728696604a528b496d9675249d777c2d7868aaf968aa7c0de33858ff98b2", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "private_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", "success": true, "managed_user_clients_verified": 6, "root_greeter_verified": true, @@ -1419,8 +1504,10 @@ "secure_configuration_preserved": true, "greetd_restarted": false, "settings_or_theme_written": false, - "current_source_equivalent_to_accepted_main": true, - "scope": "Source-specific coherent deployment, separate from measured workflows or staging-only examples." + "current_source_equivalent_to_accepted_main": false, + "native_focus_or_performance_accepted": false, + "fallback_source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "scope": "Coherent candidate deployment and security/configuration preservation only; no actual lock/login or focus/FPS acceptance." }, "accepted_main_merge": { "pull_request": 110, @@ -1519,37 +1606,21 @@ } ], "documentation_delivery": { - "accepted_main_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", - "published_workflow_run": 40396627106, + "accepted_main_commit": "c3007cc5cefc5faab36f751a28542898ecefac0d", + "published_workflow_run": 40418504442, "published_workflow_status": "SUCCESS", - "public_http_status": 200, - "current_published_source_links": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", - "current_publication_valid": true, "public_artifact_bytes_match": true, - "delivery_receipt_sha256": "bfb2cfab2dae89a1fac1e7423c71b51953463503c91ab8a3a1531c5df017cfc7", - "archive_sha256": "3a7a7c5b24628c24cdcf96e69ca43bcbbd3af36a691a9004ac35b2241110702b", - "verified_pages": [ - "docs/desktop/", - "docs/library/", - "component-lab/" - ], - "verified_native_assets": [ - "component-lab/manifest.json", - "component-lab/images/menu-ocean-populated-narrow-1x.png" - ], - "rendering_producer_inputs_verified": 117, + "delivery_receipt_sha256": "75c4da355aa9975fc25f87ca96ccdde9fdfdc89dd55ac3c4682e00895919c8f3", + "archive_sha256": "3f11260ebb62733833ba32286575ff0bd3c69c147cfe748ef86b9af9d8101b87", + "rendering_producer_inputs_verified": 118, "native_catalogue_captures_verified": 480, - "capture_source_commit": "4a0f932a7c82ac0459715007bdbd314d145a4ae4", - "latest_verified_lan_source_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "capture_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", "latest_verified_lan_http_checks_passed": 20, - "latest_verified_lan_receipt_sha256": "dbd81b2611a8ad809093f30518bf07d1b0fb5f79fa282943882b0bc3b65a335e", - "latest_verified_lan_output_manifest_sha256": "e547f085550b5969a410f15ae179148c869890cd60d8b818b1da67dca7ab6264", - "verification_is_source_specific": true, - "this_later_reconciliation_published": false, - "scope": "Named 9d42/PR114 Pages artifact/public-byte and same-artifact LAN checkpoint: 117 producer inputs/480 captures from 4a. This publication predates the later reconciliation and candidate 3640. It adds no native device/control, deployment, focus-fix or performance acceptance." + "latest_verified_lan_receipt_sha256": "3af175696ab1bdd3789a98fc44612c807920fe80ba9197c724b2714928bdbbb0", + "scope": "Source-specific accepted-main delivery; new focus source/captures are not yet published." }, - "accepted_main_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", - "current_vm_trial_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", + "accepted_main_commit": "c3007cc5cefc5faab36f751a28542898ecefac0d", + "current_vm_trial_source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", "current_vm_trial_performance_accepted": false, "historical_documentation_delivery_8ca": { "accepted_main_commit": "8ca4e82015ad07d77fe873c0dc827b6b82cc8164", @@ -1916,7 +1987,7 @@ "remaining": "Site checks, exact-head CI and publication for this newer CPU-shape/two-output follow-up remain separate gates. Four owned two-output Display flows now have source-specific native evidence; physical, secure-output, hotplug/suspend, fractional-panel input and pacing acceptance remain unverified. Continue source-specific updates after later merges; historical reports remain unchanged and a documentation edit executes no native test." } }, - "current_vm_observation": "The latest recorded coherent candidate deployment and canonical cold-browser trial use source 3640. Pointer passes and keyboard focus/key delivery fails, with both cleanups complete. This is a dated source-specific record, not a live graphical-session or process-identity guarantee.", + "current_vm_observation": "The dated ba5 canonical URI trial records both original routes and each nine-check cleanup passing on its bound normal desktop lifetime. Subsequent Notes cleanup may intentionally restart that process; this evidence does not assert a live PID/session or replace fresh native bindings.", "recent_deliveries": [ { "pull_request": 98, @@ -2035,7 +2106,24 @@ "scope": "Independent local-state Lab, one prepared 1280x800/1x output, AMD Vulkan. Events/focus/submissions are measured separately from values/pixels/timing. Whole owned unit and exact dead socket retire; runtime lock inode remains. Existing shell/settings/wallpaper/output/focus/cursor are preserved. No production desktop service adapter is exercised.", "native_harness_source_file": "vm/test-component-lab.py", "native_harness_source_file_sha256": "a8cf098d12715e54ba5b966d19dcfb496e3bd70e93d81bfe60ed2555bcdbc377", - "harness_identity_scope": "Recorded executed helper bytes correspond to the file at efeaf6d1; this does not relabel the separately identified native Lab binary as a build of that commit." + "harness_identity_scope": "Recorded executed helper bytes correspond to the file at efeaf6d1; this does not relabel the separately identified native Lab binary as a build of that commit.", + "latest_offscreen_catalog": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "rendering_producer_inputs": 121, + "captures": 480, + "stories": 9, + "palettes": 5, + "adapter": "llvmpipe CPU Vulkan", + "actual_manifest_sha256": "8b168eb75057e90b19362d7c7170fb6abf8cea384e4d74196903425ea364c2ad", + "committed_catalogue_revision": "d0e863f37fc053edf9c1c6788264cc557052880f", + "all480_file_hashes_changed_from_prior_RADV": true, + "paired_pixel_samples": 18, + "manual_visual_pairs": 4, + "native_retested_by_export": false, + "publication_verified": false, + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "scope": "New actual same-source software-Vulkan captures. Original native Lab feature results remain historical; no all480pixel/native/performance parity claim." + } }, "runtime_candidate_26d": { "source_commit": "26d03adf476af44c97fb7dcdbfb75cbdc2112770", @@ -3085,7 +3173,7 @@ "private_merge_receipt_sha256": "aa9747e89b05e474e1e0ab00eb12c079ad6991188162aa9b297055f5ed1e7a73" } }, - "accepted_main_merge_scope": "The retained accepted_main_merge object describes the historical PR110 source-equivalence checkpoint. Current accepted and verified publication checkpoint is 9d42/PR114; capture-time raw merge/report flags stay unchanged.", + "accepted_main_merge_scope": "Retained accepted_main_merge describes historical PR110. Current verified delivery checkpoint is c300/PR116; raw earlier merge and capture flags remain historical.", "input_release_candidate_3640": { "source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", "status_at_capture": "coherent_deployed_cold_pointer_passed_keyboard_failed", @@ -3251,8 +3339,393 @@ "verification_is_source_specific": true, "scope": "Named ca88 Pages artifact/public bytes and same-artifact LAN checkpoint. Accepted main has advanced to9d42/PR114; its publication and this later reconciliation require their own exact delivery proof. This does not establish native/device/performance acceptance." }, - "source_identity_policy": "Retained coherent release/build/deployment, accepted_runtime_cohorts and accepted_main_merge fields describe their named historical checkpoints. Current verified delivery is documentation_delivery at 9d42; candidate 3640 has separate build/offscreen evidence and no deployed/native-handoff acceptance. No field here is a live VM observation.", - "historical_runtime_compilation_source_before_3640": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2" + "source_identity_policy": "Historical coherent_release_build/coherent_runtime_deployment/accepted_runtime_cohorts/accepted_main_merge retain their named sources. Latest b2 qualification/deployment/native trial is explicit in runtime_candidate_b2; current verified site delivery is c300, with source3640 component captures. Separately built/deployed d77 is the latest recorded VM trial; its native input handoff remains unresolved. PR117 still carries ba5 source and captures; d77 results do not accept or rewrite those earlier trials.", + "historical_runtime_compilation_source_before_3640": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2", + "historical_rollup_checkpoint_before_b2_native": { + "snapshot_source_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "snapshot_date": "2026-10-26", + "scope": "Accepted main 9d42 / PR114 has verified Pages 40396627106 and twenty same-artifact LAN checks with 117 producer inputs/480 captures from 4a. Those checkpoints do not publish this later reconciliation. Source 3640 passes 17 build stages and 823 targeted tests, an actual AMD RADV export with 118 producer inputs and 480 PNGs and coherent six-client/root-greeter candidate VM deployment with settings/user/security state preserved. Its canonical cold pointer route passes, but Tab/Enter still fails browser focus/trusted KeyA delivery after history/input/frame guards pass; all nine cleanup checks per route pass. The cause and keyboard fix remain unestablished. This is an unmerged candidate trial, with original archive flags unchanged. Historical eb348/8e/26d evidence retains exact sources and limitations. Physical controls/sleep, broader IME/tray/clipboard/applications, eligible memory at or below 300 MiB and source-rate or 60 FPS animation acceptance remain open; all seven gaps are not closed.", + "validation": "This reconciliation reads exact source3640 build, offscreen export, coherent deployment and cold pointer/keyboard receipts, plus the named9d42 Pages/LAN checkpoint. The current keyboard failure remains a failure, with null missing-event fields and successful cleanup recorded separately. This documentation change adds no native/device/VM action or Node/Cargo build. Local JSON, report-link, privacy and history-preservation checks cover these edits; final source CI, protected-main delivery and publication remain separate.", + "accepted_main_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "runtime_compilation_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", + "current_vm_trial_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", + "current_vm_observation": "The latest recorded coherent candidate deployment and canonical cold-browser trial use source 3640. Pointer passes and keyboard focus/key delivery fails, with both cleanups complete. This is a dated source-specific record, not a live graphical-session or process-identity guarantee.", + "documentation_delivery": { + "accepted_main_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "published_workflow_run": 40396627106, + "published_workflow_status": "SUCCESS", + "public_http_status": 200, + "current_published_source_links": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "current_publication_valid": true, + "public_artifact_bytes_match": true, + "delivery_receipt_sha256": "bfb2cfab2dae89a1fac1e7423c71b51953463503c91ab8a3a1531c5df017cfc7", + "archive_sha256": "3a7a7c5b24628c24cdcf96e69ca43bcbbd3af36a691a9004ac35b2241110702b", + "verified_pages": [ + "docs/desktop/", + "docs/library/", + "component-lab/" + ], + "verified_native_assets": [ + "component-lab/manifest.json", + "component-lab/images/menu-ocean-populated-narrow-1x.png" + ], + "rendering_producer_inputs_verified": 117, + "native_catalogue_captures_verified": 480, + "capture_source_commit": "4a0f932a7c82ac0459715007bdbd314d145a4ae4", + "latest_verified_lan_source_commit": "9d42c20ec255e96d2bfd0f6bf5ef57d6bc8bad24", + "latest_verified_lan_http_checks_passed": 20, + "latest_verified_lan_receipt_sha256": "dbd81b2611a8ad809093f30518bf07d1b0fb5f79fa282943882b0bc3b65a335e", + "latest_verified_lan_output_manifest_sha256": "e547f085550b5969a410f15ae179148c869890cd60d8b818b1da67dca7ab6264", + "verification_is_source_specific": true, + "this_later_reconciliation_published": false, + "scope": "Named 9d42/PR114 Pages artifact/public-byte and same-artifact LAN checkpoint: 117 producer inputs/480 captures from 4a. This publication predates the later reconciliation and candidate 3640. It adds no native device/control, deployment, focus-fix or performance acceptance." + } + }, + "runtime_candidate_b2": { + "source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "hosted_build_run": 40415443527, + "qualification_stages_passed": 17, + "targeted_tests_passed": 840, + "target_elf_consumers_compatible": 10, + "manifest_sha256": "ba2a89b036ad00fde7fca82cce9a1647ab91247e2b59a90874bf87f587fb48b2", + "coherent_user_clients_verified": 6, + "root_greeter_verified": true, + "greetd_restarted": false, + "settings_or_theme_written": false, + "user_security_state_preserved": true, + "native_report": "reports/measurements/lucent-cold-default-uri-b2.json", + "native_report_sha256": "6a3f14d05b69fe0b361117b84b3dae411adb4e7401b60bb9dc3e357d2173a767", + "canonical_pointer_passed": true, + "canonical_keyboard_passed": false, + "cleanup_checks_passed_each": 9, + "performance_accepted": false + }, + "proposed_keyboard_focus_intent": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "pr": 117, + "guide": "docs/keyboard-focus.md", + "source_authored_targeted_test_expectation": 880, + "native_fix_accepted": false, + "visual_export_pending": false, + "status": "canonical_URI_and_scoped_lock_passed_first_Notes_key_failed", + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "report_sha256": "334a25e7c8d747e424911d600682a348bf458332b5dfe104487df6091d0fc433", + "historical_failed_export_40430392734": { + "run": 40430392734, + "workflow_head": "ac07aa5d7090c2869038f1d8001311a451c66940", + "stages_passed": 17, + "targeted_tests_passed": 880, + "required_names_passed": 94, + "whole_workflow_passed": false, + "failure": "fresh_remote_4500MiB_admission_required_before_export", + "refused_sample_available": false, + "export_started": false, + "release_archive_produced": false, + "native_fix_accepted": false, + "private_qualification_sha256": "da2b9092460fb69d52c7835c88553a3e3f133202d28bce4d064d0652590f9df9" + }, + "actual_qualification": { + "run": 40433468095, + "workflow_head": "949cc8c954f3de70e91b59c5926b992dad545838", + "stages_passed": 17, + "targeted_tests_passed": 880, + "required_names_passed": 94, + "whole_workflow_passed": true, + "export_started": true, + "release_archive_produced": true, + "native_fix_accepted": false + }, + "actual_component_catalog": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "stories": 9, + "palettes": 5, + "captures": 480, + "rendering_inputs": 121, + "backend": "Vulkan", + "adapter": "llvmpipe", + "device_type": "Cpu", + "LLVM_version": "23.1.3", + "Mesa_version": "26.2.5-arch1.1", + "export_seconds": 5.195773642999939, + "strict_checker_passed": true, + "manifest_sha256": "8b168eb75057e90b19362d7c7170fb6abf8cea384e4d74196903425ea364c2ad", + "standalone_lab_sha256": "e3ba40f645c03fe0ccb7c873fda8e30e9db39ab82793929a05534df5a0530835", + "promotion_commit": "d0e863f37fc053edf9c1c6788264cc557052880f", + "catalogue_git_tree": "88b05f01146530ae4394c0353fdbbae7fffde6f8", + "PNG_hashes_changed": 480, + "PNG_hashes_identical": 0, + "sampled_pixel_comparison": { + "paired_examples": 18, + "stories": 9, + "densities": [ + 1, + 2 + ], + "palette": "dark", + "viewport": "regular", + "maximum_normalized_peak_error": 0.00784314, + "approximately_8bit_channel_steps": 2, + "manual_visual_pairs_reviewed": 4, + "visible_layout_caret_or_clipping_regression_observed": false, + "all480_decoded_pixel_parity_established": false + }, + "actual_CPU_software_export": true, + "RADV_capture_claimed": false, + "Wayland_compositor_tested_by_export": false, + "VM_native_or_physical_GPU_performance_accepted_by_export": false, + "publication_of_this_revision_verified": false, + "prior_RADV_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9" + }, + "actual_deployment": { + "success": true, + "managed_user_clients_verified": 6, + "root_greeter_verified": true, + "supervised_beyond_initial_startup_deadline": true, + "user_state_preserved": true, + "secure_configuration_preserved": true, + "greetd_restarted": false, + "settings_or_theme_written": false, + "fresh_readonly_normal_proof_recorded": true, + "normal_profiling_flags_off_at_that_checkpoint": true, + "ongoing_live_session_state_guaranteed": false, + "fallback_source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "fallback_release_manifest_sha256": "ba2a89b036ad00fde7fca82cce9a1647ab91247e2b59a90874bf87f587fb48b2", + "scope": "Coherent candidate installation and a dated normal-state checkpoint; no new lock/login interaction, native focus fix or performance acceptance.", + "normal_checkpoint_later_retired_by_expected_Notes_cleanup": true + }, + "first_Notes_attempt": { + "status": "harness_failed_before_typing", + "failure_class": "bounded_command_failed", + "feature_checks_executed": 0, + "actual_key_attempt": false, + "restoration_checks_passed": 9, + "original_settings_source_exports_and_cursor_restored": true, + "guarded_normal_restart_and35second_supervision_verified": true, + "focus_feature_result": null, + "fresh_later_normal_proof_required_before_next_trial": true, + "scope": "A pre-input controller failure is not evidence that focus acquisition passed or failed." + }, + "pending_acceptance": { + "immediate_first_Notes_key": "failed_in_separate_V7_and_V8_native_trials", + "first_same_workspace_outside_click_and_key": "pending", + "Notes_reacquisition_and_caret_visuals": "pending", + "canonical_cold_URI_pointer_and_Tab_Enter_on_ba5": "passed_in_original_canonical_native_trial", + "lock_and_login_security_regression": "scoped_native_lock_PAM_exit_passed_login_pixels_and_other_secure_regressions_pending", + "eligible_normal_RSS_at_or_below300MiB": "pending", + "eligible_source_rate_or60FPS_and_launcher_animation": "pending", + "physical_devices_and_broader_applications": "pending" + }, + "canonical_cold_URI_native_fix_accepted": true, + "native_fix_acceptance_scope": "Only the original controlled pointer/TabEnter cold URI routes on one FHD virtual output; broader acquisition and secure-session checks remain separate.", + "canonical_cold_URI_trial": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "global_seat_owner_observed": false, + "direct_protocol_token_consumption_established": false, + "broader_widget_secure_hardware_or_performance_acceptance": false, + "accepted_main_at_capture": false + }, + "first_key_native_trial": { + "report": "reports/measurements/lucent-widget-first-key-ba5.json", + "report_sha256": "a95916d4d1cb4082984475378ca27157bac68a021979b0ce4a60efc3f0582828", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "status": "corrected_native_first_key_delivery_failed", + "host_down_to_key_transport_ms": 31.62471897667274, + "Notes_logical_and_native_focus_observed_after_input": true, + "controlled_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "control_flush_candidate_native_verified": false + }, + "native_lock_trial": { + "report": "reports/measurements/lucent-native-lock-ba5.json", + "report_sha256": "af160b848c92e1d0a9453be672656f2b1e8f5c21e39df97db5fb078c103b9f61", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": false, + "native_lock_and_authenticated_unlock_observed": true, + "exit_status_assertion_failed": true, + "native_exit_status": null, + "later_same_runtime_files_security_and_playback_preserved": true + } + }, + "isolated_decoder_retarget_f26": { + "backend_source": "1aebe2e3ffa88416791f122d9fbf01bb0f66f91f", + "tools_source": "f26f8a26b880eeb8ac01da9e57cb8a7cc4d76322", + "run": 40429866532, + "report": "reports/measurements/lucent-decoder-retarget-f26.json", + "report_sha256": "f1082bd40d59b0a809ec9ed9c787695654e9a99f704f49db51b1ded8a886cf1e", + "actual_test_counts": { + "domain": 37, + "video": 67, + "observer": 21, + "consumer": 15 + }, + "four_canonical_cases_qualified": true, + "known_target_warm_FHD_retarget_less_RSS_mib": 21.24, + "source_target_warm_FHD_retarget_more_RSS_mib": 40.13, + "general_memory_gain_proven": false, + "production_client_wiring_enabled": false, + "whole_shell_performance_accepted": false + }, + "historical_rollup_checkpoint_before_ba5": { + "snapshot_source_commit": "c3007cc5cefc5faab36f751a28542898ecefac0d", + "snapshot_date": "2026-10-27", + "scope": "Accepted main c300/PR116 has verified Pages40418504442 and twenty same-artifact LAN checks with118 source3640 producers/480captures. A separate coherent b2 Arch build/deployment and canonical native input trial are now recorded. New focus acquisition remains unaccepted.", + "validation": "Actual hosted b2 qualification17stages/840tests, concrete target ELF/header compatibility and coherent deployment pass. Canonical pointer passes, Tab/Enter fails, nine cleanup checks pass each. New one-shot focus source needs actual release, visual export and native tests. Earlier capture flags/results remain historical.", + "runtime_compilation_source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "current_vm_trial_source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "current_vm_observation": "Latest recorded b2 coherent release is normal profiling OFF. Actual canonical pointer succeeds while Tab/Enter fails; native Clock focus is observed after history closes despite prior committed None. Both cleanups pass. This dated source-specific record is not an ongoing live-session guarantee.", + "coherent_release_build": { + "source_commit": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2", + "manifest_sha256": "e48716b0d7b797292032fec62e3c19219f39184b75221e3249b85633e3812183", + "passed": true, + "completed_stages": 15, + "targeted_tests_passed": 786, + "archive_classification_at_build": { + "accepted_main": false, + "vm_deployed": false, + "native_activated": false + }, + "source_code_equivalent_to_accepted_main": true, + "private_build_receipt_sha256": "6bed8454b64bbcb9513500eea075ee51c0b7ea2ae3955f5ce0f4022234bda170" + }, + "coherent_runtime_deployment": { + "source_commit": "eb3481f4c75da9e0783975ad9c3e920ad8833ce2", + "report": "reports/measurements/lucent-output-resource-matrix-eb348.json", + "private_receipt_sha256": "1ec5728696604a528b496d9675249d777c2d7868aaf968aa7c0de33858ff98b2", + "success": true, + "managed_user_clients_verified": 6, + "root_greeter_verified": true, + "acceptance_examples_staged_only": 3, + "supervised_beyond_startup_deadline": true, + "user_state_preserved": true, + "secure_configuration_preserved": true, + "greetd_restarted": false, + "settings_or_theme_written": false, + "current_source_equivalent_to_accepted_main": true, + "scope": "Source-specific coherent deployment, separate from measured workflows or staging-only examples." + }, + "proposed_keyboard_focus_intent": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "pr": 117, + "guide": "docs/keyboard-focus.md", + "source_authored_targeted_test_expectation": 880, + "native_fix_accepted": false, + "visual_export_pending": true, + "actual_qualification": { + "run": 40430392734, + "workflow_head": "ac07aa5d7090c2869038f1d8001311a451c66940", + "stages_passed": 17, + "targeted_tests_passed": 880, + "required_names_passed": 94, + "whole_workflow_passed": false, + "failure": "fresh_remote_4500MiB_admission_required_before_export", + "refused_sample_available": false, + "export_started": false, + "release_archive_produced": false, + "native_fix_accepted": false, + "private_qualification_sha256": "da2b9092460fb69d52c7835c88553a3e3f133202d28bce4d064d0652590f9df9" + } + } + }, + "pending_documentation_delivery_pr117": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "pull_request": 117, + "rendering_inputs": 121, + "captures": 480, + "capture_source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "catalogue_commit": "d0e863f37fc053edf9c1c6788264cc557052880f", + "exact_head_CI_passed": false, + "published": false, + "scope": "Candidate report and actual capture refresh; source/build/deployment are distinct from protected-main and Pages delivery." + }, + "ba5_completed_click_V8": { + "report": "reports/measurements/lucent-widget-completed-click-ba5.json", + "report_sha256": "9cc6005267544dd4c8a8b33ef7741b148ef9ac949a521ea955a61d7062e34465", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "first_key_delivery_passed": false, + "gesture_contract": "completed-click-then-immediate-key", + "host_down_to_key_transport_ms": 66.63447699975222, + "Notes_logical_and_native_focus_observed_after_input": true, + "owned_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "native_control_flush_fix_accepted": false, + "V7_held_button_result_unchanged": true + }, + "ba5_native_lock_V3": { + "report": "reports/measurements/lucent-native-lock-ba5-v3.json", + "report_sha256": "c39c4a2d1b8d87935b809b95388858832b6f557132024c51806e2c18e50cd1b9", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": true, + "checks_passed": 6, + "same_connection_new_locked_ACK_and_one_PAM_unlock": true, + "retained_same_invocation_exited_normally": true, + "exit_status": 0, + "reference_released": true, + "same_runtime_files_security_playback_idle_and_geometry_preserved": true, + "login_pixels_suspend_hardware_or_performance_accepted": false, + "V1_and_V2_failures_unchanged": true + }, + "candidate_keyboard_control_flush": { + "source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", + "report": "reports/measurements/lucent-keyboard-control-flush-d77.json", + "report_sha256": "2af4c21b30f012b4f99b097349831360a805a47d7cdffa253634d680fac3d838", + "status": "coherent_deployment_and_canonical_URI_passed_widget_handoff_unresolved_test_transport_problem_observed", + "hosted_release_run": 40448216820, + "actual_qualification_stages": 17, + "actual_targeted_tests": 885, + "actual_required_named_tests": 99, + "actual_producer_inputs": 121, + "actual_PNGs": 480, + "static_ELF_consumers_passed": 10, + "native_focus_fix_accepted": false, + "guest_input_order_measured": false, + "failure_cause_established": false, + "canonical_URI_and_lock_on_this_source": "original_canonical_pointer_and_TabEnter_passed;lock_not_executed", + "all9restoration_per_native_trial": true, + "reacquisition": "unattempted", + "eligible_memory_and_source_rate_pacing": "pending", + "code_promoted_into_PR117": false, + "component_catalogue_promoted": false, + "accepted_main": false, + "canonical_cold_URI": { + "report": "reports/measurements/lucent-cold-default-uri-d77.json", + "report_sha256": "5bcebe0e218e118a5fd7861330c85dc6e4419a0c1297c672e46ba0aaefcbb0d1", + "both_original_routes_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_unmodified_nonrepeat_KeyA_per_case": 1 + }, + "input_order_diagnostic": { + "report": "reports/measurements/lucent-widget-input-order-d77.json", + "report_sha256": "8727381070ebfe8681ace45481d7b36c76954adf3d020bbfee1f28986edd28eb", + "guest_outside_key_precedes_mouse_DOWN_ms": 4.332, + "outside_browser_pointer_target_reached": false, + "first_Notes_key_and_undo_passed": true, + "observer_FDs_closed": true, + "restoration_passed": 8, + "restoration_total": 9, + "original_cursor_restored": false, + "original_cursor_not_persisted": true, + "focus_cause_established": false, + "earlier_guest_order_inferred": false, + "next": "correct_input_transport_then_retest;no_product_focus_patch_from_this_trace" + } + } }, "requirements": [ { @@ -5226,6 +5699,113 @@ "Cross-output keyboard/text/clipboard, arbitrary applications and broader workspace routing.", "Presentation/scanout FPS, distinct video-frame cadence, animation smoothness, GPU memory and normal RSS targets. Submission counters are not presentation FPS." ] + }, + { + "milestone": "explicit-widget-keyboard-intent-ba5-release", + "status": "source_qualified_software_catalog_exported_candidate_deployed_native_acceptance_pending", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "pull_request": 117, + "report": "reports/measurements/lucent-keyboard-intent-ba5-release.json", + "report_sha256": "a043c857208559e253154e129e26b817043b68347dd1bbc02e6d94f33b0d45c5", + "report_snapshot_commit": "8266efb669d5776f09f43fc288f637cf24a920b2", + "checks": { + "hosted_stages": 17, + "targeted_tests": 880, + "required_named_regressions": 94, + "offscreen_captures": 480, + "rendering_inputs": 121, + "ELF_consumers_static_imports_resolve": 10, + "managed_user_clients_verified": 6, + "root_greeter_verified": true + }, + "pending": [ + "immediate first Notes key and outside click", + "canonical cold URI keyboard focus", + "secure lock/login regression", + "eligible desktop resources and source-rate/60FPS animations", + "protected-main and Pages delivery" + ], + "historical_b2_keyboard_failure_unchanged": true, + "mixed_f26_performance_result_unchanged": true + }, + { + "milestone": "ba5-original-canonical-cold-default-URI-accepted", + "status": "both_original_routes_and_each_owned_cleanup_passed", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "summary": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "feature_checks_per_case": 3, + "cleanup_checks_per_case": 9, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "global_seat_owner_observed": false, + "direct_protocol_token_consumption_established": false, + "broader_widget_secure_hardware_or_performance_acceptance": false, + "accepted_main_at_capture": false + }, + "historical_b2_keyboard_failure_unchanged": true, + "mixed_f26_performance_result_unchanged": true, + "pending": [ + "immediate first Notes key and first outside-click native trial", + "secure lock/login regression", + "broader handlers and direct protocol token consumption", + "eligible desktop resources and source-rate/animation performance", + "protected-main and exact Pages delivery" + ] + }, + { + "milestone": "ba5-completed-click-first-key-native-result", + "status": "first_key_delivery_failed_cleanup_passed", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-widget-completed-click-ba5.json", + "report_sha256": "9cc6005267544dd4c8a8b33ef7741b148ef9ac949a521ea955a61d7062e34465", + "summary": { + "report": "reports/measurements/lucent-widget-completed-click-ba5.json", + "report_sha256": "9cc6005267544dd4c8a8b33ef7741b148ef9ac949a521ea955a61d7062e34465", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "first_key_delivery_passed": false, + "gesture_contract": "completed-click-then-immediate-key", + "host_down_to_key_transport_ms": 66.63447699975222, + "Notes_logical_and_native_focus_observed_after_input": true, + "owned_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "native_control_flush_fix_accepted": false, + "V7_held_button_result_unchanged": true + }, + "old_failures_unchanged": true + }, + { + "milestone": "ba5-native-lock-PAM-retained-exit", + "status": "six_scoped_native_checks_passed", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "report": "reports/measurements/lucent-native-lock-ba5-v3.json", + "report_sha256": "c39c4a2d1b8d87935b809b95388858832b6f557132024c51806e2c18e50cd1b9", + "summary": { + "report": "reports/measurements/lucent-native-lock-ba5-v3.json", + "report_sha256": "c39c4a2d1b8d87935b809b95388858832b6f557132024c51806e2c18e50cd1b9", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": true, + "checks_passed": 6, + "same_connection_new_locked_ACK_and_one_PAM_unlock": true, + "retained_same_invocation_exited_normally": true, + "exit_status": 0, + "reference_released": true, + "same_runtime_files_security_playback_idle_and_geometry_preserved": true, + "login_pixels_suspend_hardware_or_performance_accepted": false, + "V1_and_V2_failures_unchanged": true + }, + "old_failures_unchanged": true } ], "performance_targets": { diff --git a/docs/keyboard-focus.md b/docs/keyboard-focus.md new file mode 100644 index 00000000..2803f21f --- /dev/null +++ b/docs/keyboard-focus.md @@ -0,0 +1,227 @@ +# Keyboard focus: intent, native ownership and painting + +A text box can remember its caret while another application receives the +keyboard. Lucent keeps those facts separate. This guide follows the implemented +one-shot focus API in compiled and deployed candidate `ba5b8a51f960`. +The original canonical cold URI interaction now passes in its recorded scope; +inline-widget and secure-session acceptance remain separate. + +## Four different states + +| State | Owner | Meaning | +| --- | --- | --- | +| Capability | Client widget catalog | This widget contains keyboard controls. Capability alone requests no focus. | +| User demand | Client `widgets::keyboard_demand::Demand` | A genuine press selected a focusable member on one output. Demand is transient, never a saved preference. | +| Native ownership | Wayland runtime | A real keyboard Enter was observed for one exact native surface lifetime. Leave, removal or seat loss ends ownership. | +| Logical selection and caret | Framework `Interaction` and client field state | Which control is selected and where editing would resume. Losing native ownership need not erase it. | + +`Keyboard::OnDemand` expresses eligibility. It does not mean the compositor has +given the surface a keyboard. A frame submission also does not prove keyboard +ownership. + +The distinction matters when several widgets share a native surface. A passive +clock must not request keys merely because its surface also contains media +buttons. The actual pressed control supplies the intent. + +## From one press to editing + +```mermaid +sequenceDiagram + participant W as Compositor / Wayland + participant R as Framework runtime + participant U as Prepared UI tree + participant C as Desktop widget host + W->>R: Physical primary press, exact native surface + R->>U: Hit test the last prepared scene + U-->>R: Subtree observer, then control action + R->>C: PressMember(member, keyboard_focusable) + C->>C: Create transient demand for this member/output + C->>R: Effects::request_keyboard_focus + R->>W: Commit keyboard eligibility, acquire temporary focus scope + W-->>R: Actual wl_keyboard Enter + R->>W: Destroy temporary scope, request bounded sync + W-->>R: Sync completion + R-->>C: Focused(exact native token) or typed failure + W->>R: Ordinary keyboard events + R->>C: TextEdit or control message +``` + +The prepared hit carries `keyboard_focusable`; the runtime does not infer it +from whichever field happened to be selected earlier. The nearest +`Element::on_pointer_press` observer receives its message before the control's +ordinary action. That lets the host establish demand before editing starts. +Drag capture keeps its existing lifetime and routing. + +The client describes the desired surface policy and issues a generic effect: + +```rust,ignore +effects.request_keyboard_focus(address, cancellation, move |outcome| { + Message::KeyboardResolved(request_id, outcome) +}); +``` + +This is an API excerpt, not a complete application. The client retains the +request identity, cancellation and exact target. A completion from an earlier +request cannot grant a later request ownership. + +## What happens underneath + +`lucent-wayland` validates that the effect belongs to the current real primary +press, a focusable prepared hit, an ordinary opted-in client and the same native +surface lifetime. A socket command cannot manufacture that authority. Secure +lock and login clients remain opted out. + +The backend can use the compositor's optional +`hyprland_focus_grab_manager_v1` protocol. The public API exposes no Hyprland +objects. Unsupported compositors return a typed unavailable outcome. + +When eligibility needs changing, a keyboard-only commit preserves the last +successfully presented geometry, scale, viewport and input regions. It does not +commit an unrelated pending resize or claim a new rendered frame. Acquiring keys +therefore does not wait for a GPU image to become available. + +The temporary native focus scope is destroyed after real Enter. A bounded +`wl_display.sync` then checks that the same surface remains eligible and focused +after that teardown. Only then does the request report `Focused(token)`. +If teardown loses focus, it reports `NotRetained`. The implementation neither +pulses exclusive keyboard policy nor promotes the surface's layer. + +The scope is not held throughout editing. Keeping it alive could make an inline +widget behave like a modal popup and interfere with clicks elsewhere. Native +first-click typing and the first outside click still require compositor tests. +Focus after teardown depends on compositor policy; a successful request cannot +promise future global ownership. + +## Losing focus and repainting + +`Event::KeyboardFocus` carries Entered, Left, Retired or Unavailable for an opaque +native lifetime token. The client clears acknowledged demand on matching loss; +old native events cannot clear a replacement owner's demand. Opening a +foreground shell panel clears widget intent. Closing that panel does not +recreate it. + +The framework's native keyboard-active state controls the caret, selection and +keyboard-focus paint. Logical focus, selection offsets, scrolling and hover +survive independently. A native ownership change invalidates the affected +surface and normal frame scheduling repaints it. Vulkan draws the resulting +scene; Vulkan does not choose focus or route key presses. + +The runtime also rejects key dispatch once the client withdraws keyboard +eligibility, even if compositor Leave has not arrived yet. Pending requests +have a two-second dispatch deadline and bounded native cleanup. Cancellation, +native retirement and seat removal cannot complete an obsolete request as +focused. + +## Where to read the implementation + +Paths below are relative to `lucent/`: + +| Layer | Source | Responsibility | +| --- | --- | --- | +| Framework contract | `crates/lucent-api/src/keyboard_focus.rs` | Request, typed outcome, cancellation and opaque lifetime identity. | +| Prepared input | `crates/lucent-ui/src/press_observation.rs` | Nearest subtree observation and actual hit capability. | +| Native backend | `crates/lucent-wayland/src/focus_request.rs` | Admission, optional native protocol, teardown verification and lifecycle. | +| Native commits | `crates/lucent-wayland/src/keyboard_control.rs` | Preserve presented geometry while updating eligibility. | +| Native painting state | `crates/lucent-ui/src/focus_presentation.rs` | Keyboard-active paint without destroying logical editing state. | +| Client policy | `apps/lucent-desktop/src/widgets/keyboard_demand.rs` | Member/output demand, request ownership and stale-result rejection. | +| Composition | `apps/lucent-desktop/src/desktop.rs` | Foreground policy and routing between widget hosts and runtime. | + +This feature belongs to the presentation framework and client. Domain service +contracts remain **ports**, and operating-system implementations remain +**adapters**. Neither needs native keyboard objects. Notification URI opening +continues to use `UriPort`; widget focus acquisition does not invoke that port. + +## What the existing VM evidence establishes + +The [source b2 native report](../reports/measurements/lucent-cold-default-uri-b2.json) +records pointer success and Tab/Enter failure, with all nine cleanup checks +passing in each case. It observes Clock regaining native keyboard focus after +notification history closes; the browser document then lacks focus. Clock and +Calendar had actually committed `None` while history was open, so that run does +not support a missed-demotion explanation. + +That report predates this new demand/acquisition implementation. Authored +regressions, successful compilation, visual captures, native interaction and +performance acceptance are separate checks. In particular, the new source must +pass immediate first-key delivery, an ordinary first outside click, canonical +pointer and Tab/Enter URI opening, and secure-session regression tests before +this focus fix is accepted. + + +### Source qualification and coherent candidate deployment + +Source `ba5b8a51f960` passes its full Ubuntu Rust, controlled service-protocol +and software-Vulkan regression job in +[CI40428709862](https://github.com/xandreeddev/desktop-lab/actions/runs/40428709862). +The later [Arch40430392734 job](https://github.com/xandreeddev/desktop-lab/actions/runs/40430392734) +passes all 17 qualification stages, 880 targeted tests and 94 required named +regressions. Its subsequent fresh-memory admission refuses the catalogue export; +no capture export or release archive is produced. The rejected sample was not +recorded, so host pressure versus cgroup cache cannot be inferred from that run. +That failed workflow remains a historical result; it produced neither a native +fix nor a new catalogue or deployment. + +The corrected [Arch40433468095 run](https://github.com/xandreeddev/desktop-lab/actions/runs/40433468095) +passes the same 17 stages, 880 tests and 94 named regressions. After verifying +all copied payload hashes, it removes only its freshly owned private Cargo +target. Recorded effective available memory rises from 3,795 to 6,402 MiB; +three fresh capture admissions pass at 6,402 MiB with the unchanged 4,500 MiB +floor. These are hosted build facts, not desktop memory acceptance or proof of +the earlier unrecorded failure cause. + +The actual llvmpipe CPU-Vulkan export passes strict validation of 121 producers +and 480 captures. Concrete target ELF/header review and coherent six-client/ +root-greeter deployment also pass, with settings/security preserved and no +greetd restart. The [source-specific release report](../reports/measurements/lucent-keyboard-intent-ba5-release.json) +keeps original archive flags separate from the later deployment receipt. + +The first Notes controller attempt fails before any typing or feature check; +all nine restoration checks pass, including its expected guarded restart. +This is a harness failure, not a passed or failed native focus result. A fresh +normal identity must be bound before another attempt. Later V4–V6 failures retain +their original outcomes and cleanup results; their combined down/up QMP call did +not publish a pressed USB report. +A separately rebound original [canonical cold URI trial](../reports/measurements/lucent-cold-default-uri-ba5.json) +now passes both pointer and Tab/Enter routes. Each fresh owned document receives +one trusted, unmodified, nonrepeat `KeyA`; each case passes all three feature and +nine cleanup checks, without forced focus, prewarming or a cursor workaround. +That closes only this controlled URI workflow on one FHD virtual output. +Source tests, offscreen pictures and installation alone do not accept interactions; +first-click widget and secure-session results require their own evidence. + +### Corrected pointer transport and first-key timing + +The [V7 native trial](../reports/measurements/lucent-widget-first-key-ba5.json) +sends DOWN and UP in separate QMP synchronizations, with `KeyA` immediately after +DOWN and balanced UP before diagnostic reads. There is no focus command, wait or +retry. Notes gains logical focus and one native Enter with requested/committed +`OnDemand`, but the first trusted nonrepeat key reaches the owned browser and +Notes remains unchanged. The host down-to-key transport interval is 31.625 ms. +All nine restoration checks pass; outside-click and reacquisition are unattempted. + +These sequential checkpoints do not measure callback entry, socket flush, server +processing or the exact Enter/KeyA dispatch order. Missing timing, keyboard-active +state and completed request outcomes remain unavailable. The proposed nonblocking +flush of the complete native control transaction removes a possible queue-drain +delay; it grants no focus and is not a verified fix. A newly compiled runtime and +the corrected native trial are required. The original cold URI workflow remains +accepted in its separate recorded scope. + +The additional [V8 trial](../reports/measurements/lucent-widget-completed-click-ba5.json) +completes DOWN and UP in separate synchronizations before immediate KeyA, with no +focus wait or retry. It also fails first-key delivery at a 66.634 ms host interval +from DOWN start, including UP transport. Notes gains logical/native focus, while +the owned browser receives the key; all nine restorations pass. Outside-click +and reacquisition remain unattempted. This case does not overwrite V7's failure. + +The [V1 lock trial](../reports/measurements/lucent-native-lock-ba5.json) retains its +exit-status assertion failure. V2 refuses before lock/password because systemd +serializes an initially null InvocationID as an empty array. The new +[V3 regression](../reports/measurements/lucent-native-lock-ba5-v3.json) passes all +six checks using one private unit reference: live nonzero invocation identity, +exact native PID and positive start are retained through normal status0 exit. +The same connection observes compositor lock acknowledgement and authenticated +unlock; references and original state are preserved. No default Code0 is accepted +as exit proof. This accepts the recorded lock/PAM cycle, not login, secure pixels, +suspend, hardware or performance. Secure clients remain opted out of the ordinary +layer-surface acquisition API. diff --git a/docs/lucent-framework.md b/docs/lucent-framework.md index 4753d310..b724afff 100644 --- a/docs/lucent-framework.md +++ b/docs/lucent-framework.md @@ -209,7 +209,12 @@ its 823 targeted tests, then passes coherent VM deployment. Its [cold-browser report](../reports/measurements/lucent-cold-default-uri-3640.json) passes pointer handoff but still fails the separate keyboard route after the history/input-release guards pass. A callback acknowledgement establishes no -destination focus or trusted-key guarantee; the keyboard defect remains open. +destination focus or trusted-key guarantee. A later [source ba5 canonical trial](../reports/measurements/lucent-cold-default-uri-ba5.json) +passes both original cold routes and trusted nonrepeat document `KeyA` with full +owned cleanup after explicit widget-demand ownership is introduced. That scoped +result does not strengthen the `after_input_release` API into a destination-focus +guarantee; inline-widget acquisition and secure-session behavior have separate +acceptance requirements. Runtime ingress is a shared FIFO with capacity for 64 waiting messages from subscriptions, effect completions and local IPC. When full, background producers @@ -455,8 +460,13 @@ selection. Buttons support Tab / Shift+Tab traversal and Enter / Space activatio lets a composite input field draw the focus outline around all its contents. `tab_stop(false)` lets composite clients own keyboard navigation. `Theme::apply` provides semantic focus color, outline width and caret width. Text, placeholder -and caret share the renderer's line metrics. A long input scrolls to keep its -end caret visible. General caret movement and IME are still future work. +and caret share the renderer's line metrics. Ordinary fields support caret and +selection editing, shaped/bidirectional text, font fallback and opted-in native +IME; see [text shaping](text-shaping.md) for source-specific acceptance. Logical +field focus is separate from native keyboard ownership. The proposed +[one-shot focus path](keyboard-focus.md) gates native caret/focus painting and +keeps widget capability separate from explicit user demand; its new native +interaction checks remain pending. The launcher owns Tab / Shift+Tab to cycle Apps → Commands → Wallpapers → Themes → Widgets. Arrows change selection, Enter activates it, Escape closes. This is diff --git a/lucent/Cargo.lock b/lucent/Cargo.lock index c2f2b8dc..a7681b54 100644 --- a/lucent/Cargo.lock +++ b/lucent/Cargo.lock @@ -1567,6 +1567,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-protocols", + "wayland-scanner", ] [[package]] diff --git a/lucent/apps/lucent-desktop/src/desktop.rs b/lucent/apps/lucent-desktop/src/desktop.rs index 6eaf192b..98ff6852 100644 --- a/lucent/apps/lucent-desktop/src/desktop.rs +++ b/lucent/apps/lucent-desktop/src/desktop.rs @@ -109,13 +109,9 @@ fn widget_surface_specs( width: source.rect.w.ceil() as u32, height: source.rect.h.ceil() as u32, exclusive_zone: -1, - // A native group can be named after a passive first member while - // also painting Notes or other keyboard-operable controls. - keyboard: if keyboard_available - && (host.editing() - || source.members.iter().any(|id| { - widgets::catalog::find(id).is_some_and(|entry| entry.keyboard_interactive) - })) { + // Capability remains catalog metadata. A passive sibling sharing + // this native group never grants another member keyboard ownership. + keyboard: if keyboard_available && host.keyboard_requested(&source, instance.as_ref()) { Keyboard::OnDemand } else { Keyboard::None @@ -939,12 +935,56 @@ impl Desktop { let selected = self.monitors.active.clone(); self.update_widgets_on(selected.as_ref(), message, effects); } + fn clear_widget_keyboard_demand(&mut self, effects: &mut Effects) { + let mut changed = self.widgets.clear_keyboard_demand(); + for monitor in self.monitors.connected.values_mut() { + changed |= monitor.widgets.clear_keyboard_demand(); + } + if changed { + effects.redraw("widgets"); + } + } + fn reconcile_widget_keyboard_demand(&mut self, effects: &mut Effects) { + if self.panel_surface().is_some() { + self.clear_widget_keyboard_demand(effects); + return; + } + let mut changed = if self.monitors.legacy() { + self.widgets + .reconcile_keyboard(&self.settings.layout, self.viewport, None) + } else { + // The dormant fallback Host must not retain intent across a later + // transition back from named outputs to legacy native surfaces. + self.widgets.clear_keyboard_demand() + }; + for (id, monitor) in &mut self.monitors.connected { + let layout = self + .settings + .monitor_layouts + .get(id) + .unwrap_or(&self.settings.layout); + changed |= monitor.widgets.reconcile_keyboard( + layout, + monitor.viewport, + Some(&monitor.instance), + ); + } + if changed { + effects.redraw("widgets"); + } + } fn update_widgets_on( &mut self, id: Option<&MonitorId>, message: widgets::Message, effects: &mut Effects, ) { + // A new physical member press replaces ownership across every output, + // even if the pressed member is passive or shares another native group. + if matches!(&message, widgets::Message::PressMember(_, press) if press.button == MouseButton::Primary) + { + self.clear_widget_keyboard_demand(effects); + } if let (Some(id), widgets::Message::Tick(now)) = (id, &message) { let layout = self .settings @@ -1410,6 +1450,8 @@ impl Component for Desktop { widgets::Message::EditNotes(TextEdit::ClipboardReply(..)) | widgets::Message::Tick(_) | widgets::Message::CancelDrags + | widgets::Message::KeyboardResolved(..) + | widgets::Message::KeyboardNative(..) ) { self.explicitly_select_monitor(&route.id, effects); } @@ -2065,9 +2107,14 @@ impl Component for Desktop { }), ); self.refresh_previews(effects); + self.reconcile_widget_keyboard_demand(effects); } } impl api::Application for Desktop { + fn keyboard_focus_requests_enabled(&self) -> bool { + true + } + fn input_method_enabled(&self) -> bool { true } @@ -2159,11 +2206,9 @@ impl api::Application for Desktop { ] } fn surfaces(&self) -> Vec { - // Use foreground lifetime, not current input ownership: notification - // history stays open while yielding input and dispatching a URI. - // This requests widget suppression; a matching native commit may still - // wait for that widget's frame callback or render retry. It does not - // acknowledge release of other surfaces or promise destination focus. + // Foreground ownership also clears transient demand during update. + // Closing a panel only permits a future physical press; it cannot + // resurrect keyboard eligibility from a widget's catalog capability. let widget_keyboard_available = self.panel_surface().is_none(); let mut surfaces = vec![ SurfaceSpec { @@ -2763,6 +2808,7 @@ impl api::Application for Desktop { let role = match native_event { Event::PointerInside { surface, .. } | Event::PointerButton { surface, .. } + | Event::KeyboardFocus { surface, .. } | Event::FrameSubmitted { surface, .. } | Event::Resize { surface, .. } | Event::Key { surface, .. } @@ -2784,6 +2830,13 @@ impl api::Application for Desktop { }; } match event { + Event::KeyboardFocus { + surface, + native, + change, + } if widgets::catalog::find(surface).is_some() => Some(Message::Widgets( + widgets::Message::KeyboardNative(native, change), + )), Event::Key { surface: "weather-controls", key: Key::Escape, @@ -2817,6 +2870,13 @@ impl api::Application for Desktop { .surfaces(self.widget_layout(Some(&route.id)), monitor.viewport) }; let message = match *event { + Event::KeyboardFocus { + surface, + native, + change, + } if widgets::catalog::find(surface).is_some() => Some(Message::Widgets( + widgets::Message::KeyboardNative(native, change), + )), Event::PointerInside { surface: "bar", inside: true, diff --git a/lucent/apps/lucent-desktop/src/desktop/system_tests.rs b/lucent/apps/lucent-desktop/src/desktop/system_tests.rs index b02b561a..f5f03e31 100644 --- a/lucent/apps/lucent-desktop/src/desktop/system_tests.rs +++ b/lucent/apps/lucent-desktop/src/desktop/system_tests.rs @@ -3,7 +3,8 @@ use super::{Desktop, Message}; use crate::widgets; use lucent_api::{ ActivationOutcome, Application, Component, DisplayOutput, DragEvent, Effects, - InputReleaseOutcome, Keyboard, OutputName, SurfaceAddress, SurfaceInstance, SurfaceSpec, + InputReleaseOutcome, Keyboard, KeyboardFocusChange, KeyboardFocusOutcome, MouseButton, + NativeSurfaceToken, OutputName, PointerPress, SurfaceAddress, SurfaceInstance, SurfaceSpec, }; use lucent_domain::{ DomainError, MonitorId, Notification, NotificationSnapshot, NotificationTarget, Placement, @@ -379,9 +380,9 @@ fn system_named_capture_updates_only_the_host_that_paints_system() { assert!(monitor.widgets.preview_position("system").is_some()); } -// These assertions inspect requested client policy only. A widget with a -// pending compositor callback can retain older committed input state; native -// committed-state/focus observations are required to establish a handoff fix. +// These assertions establish client intent, request cancellation and routing. +// Native first-click/immediate-key and same-click outside delivery require the +// compositor trial; constructing an effect is not a focus acknowledgement. fn widget_specs(app: &Desktop) -> Vec { app.surfaces() .into_iter() @@ -400,6 +401,30 @@ fn widget_host<'a>(app: &'a Desktop, monitor: Option<&str>) -> &'a widgets::Host None => &app.widgets, } } +fn press_member( + app: &mut Desktop, + monitor: Option<&str>, + member: &str, + focusable: bool, +) -> Effects { + let message = Message::Widgets(widgets::Message::PressMember( + member.into(), + PointerPress { + button: MouseButton::Primary, + keyboard_focusable: focusable, + }, + )); + let message = match monitor { + Some(name) => Message::OnMonitor( + app.monitors.connected[&id(name)].route(&id(name)), + Box::new(message), + ), + None => message, + }; + let mut effects = Effects::default(); + app.update(message, &mut effects); + effects +} fn assert_suppressed_widgets(app: &Desktop, baseline: &[SurfaceSpec]) { let expected: Vec<_> = baseline .iter() @@ -494,45 +519,66 @@ fn begin_link(app: &mut Desktop, target: NotificationTarget) -> Effects #[test] fn widget_keyboard_defaults_preserve_controls_and_exclude_passive_content() { - for (widget, keyboard) in [ - ("clock", Keyboard::None), - ("system", Keyboard::None), - ("notes", Keyboard::OnDemand), - ("calendar", Keyboard::OnDemand), - ("timer", Keyboard::OnDemand), - ("media", Keyboard::OnDemand), - ("weather", Keyboard::OnDemand), - ] { + for definition in widgets::catalog::WIDGETS.iter() { + let widget = definition.id; let mut app = desktop(); app.settings.layout = layout(&[(widget, 64., 64.)]); assert_eq!( widget_keyboard(&app), - BTreeMap::from([(address(widget, None), keyboard)]), + BTreeMap::from([(address(widget, None), Keyboard::None)]), + "capability is not intent: {widget}" + ); + let effects = press_member(&mut app, None, widget, definition.keyboard_interactive); + assert_eq!( + effects.keyboard_focus.len(), + usize::from(definition.keyboard_interactive) + ); + assert_eq!( + widget_keyboard(&app), + BTreeMap::from([( + address(widget, None), + if definition.keyboard_interactive { + Keyboard::OnDemand + } else { + Keyboard::None + } + )]), "{widget}" ); } } #[test] -fn widget_keyboard_uses_every_merged_member_and_rechecks_after_hide() { +fn widget_keyboard_uses_pressed_merged_member_and_rechecks_after_hide() { let mut app = desktop(); app.settings.layout = layout(&[("clock", 64., 64.), ("notes", 64., 64.)]); let groups = app.widgets.surfaces(&app.settings.layout, app.viewport); assert_eq!(groups.len(), 1); assert_eq!(groups[0].members, ["clock", "notes"]); + let effects = press_member(&mut app, None, "notes", true); + assert_eq!(effects.keyboard_focus.len(), 1); assert_eq!( widget_keyboard(&app), BTreeMap::from([(address("clock", None), Keyboard::OnDemand)]) ); - app.update( - Message::Widgets(widgets::Message::Toggle("notes".into())), - &mut Effects::default(), + // Same native group, different actual member: a passive clock press clears + // Notes instead of borrowing its retained component focus or capability. + assert!( + press_member(&mut app, None, "clock", false) + .keyboard_focus + .is_empty() ); assert_eq!( widget_keyboard(&app), BTreeMap::from([(address("clock", None), Keyboard::None)]) ); - app.settings.layout = layout(&[("clock", 64., 64.), ("system", 64., 64.)]); + let mut effects = press_member(&mut app, None, "notes", true); + let request = effects.keyboard_focus.pop().unwrap(); + app.update( + Message::Widgets(widgets::Message::Toggle("notes".into())), + &mut Effects::default(), + ); + assert!(request.cancellation.cancelled()); assert_eq!( widget_keyboard(&app), BTreeMap::from([(address("clock", None), Keyboard::None)]) @@ -547,29 +593,39 @@ fn widget_keyboard_keeps_edit_controls_available_without_bypassing_foreground() Message::Widgets(widgets::Message::Edit(true)), &mut Effects::default(), ); - let editing = widget_specs(&app); - assert_eq!(editing.len(), 2); assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); + let mut effects = press_member(&mut app, None, "clock", true); + assert_eq!(effects.keyboard_focus.len(), 1); + let cancel = effects.keyboard_focus.pop().unwrap().cancellation; + let editing = widget_specs(&app); + assert_eq!( editing .iter() - .all(|spec| spec.keyboard == Keyboard::OnDemand) + .filter(|spec| spec.keyboard == Keyboard::OnDemand) + .count(), + 1 ); app.update( - Message::Audio(crate::audio::Message::Open), + Message::Widgets(widgets::Message::SizeStep("clock".into(), 1)), &mut Effects::default(), ); - assert_suppressed_widgets(&app, &editing); - app.update(Message::DismissPanels, &mut Effects::default()); - assert_eq!(widget_specs(&app), editing); + assert!( + !cancel.cancelled(), + "keyboard edit action retains explicit ownership" + ); + let editing = widget_specs(&app); app.update( - Message::Widgets(widgets::Message::Edit(false)), + Message::Audio(crate::audio::Message::Open), &mut Effects::default(), ); - assert!( - widget_specs(&app) - .iter() - .all(|spec| spec.keyboard == Keyboard::None) - ); + assert!(cancel.cancelled()); + assert_suppressed_widgets(&app, &editing); + app.update(Message::DismissPanels, &mut Effects::default()); + assert_suppressed_widgets(&app, &editing); } #[test] @@ -577,6 +633,7 @@ fn widget_keyboard_every_foreground_panel_suppresses_the_legacy_host() { for (role, opener) in foreground_openers() { let mut app = desktop(); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); assert_eq!(baseline.len(), 2); app.update(opener, &mut Effects::default()); @@ -584,7 +641,7 @@ fn widget_keyboard_every_foreground_panel_suppresses_the_legacy_host() { assert_suppressed_widgets(&app, &baseline); app.update(Message::DismissPanels, &mut Effects::default()); assert!(app.panel_surface().is_none()); - assert_eq!(widget_specs(&app), baseline); + assert_suppressed_widgets(&app, &baseline); } } @@ -597,6 +654,7 @@ fn widget_keyboard_foreground_suppresses_every_connected_monitor_group() { .monitor_layouts .insert(id("DP-2"), transitive()); connect(&mut app); + press_member(&mut app, Some("DP-2"), "notes", true); let baseline = widget_specs(&app); assert_eq!(baseline.len(), 4); assert!(baseline.iter().all(|spec| spec.instance.is_some())); @@ -604,7 +662,7 @@ fn widget_keyboard_foreground_suppresses_every_connected_monitor_group() { assert_eq!(app.panel_surface(), Some(role)); assert_suppressed_widgets(&app, &baseline); app.update(Message::DismissPanels, &mut Effects::default()); - assert_eq!(widget_specs(&app), baseline); + assert_suppressed_widgets(&app, &baseline); app.update( Message::Outputs(vec![output(Some("DP-2"), 2)]), &mut Effects::default(), @@ -614,6 +672,10 @@ fn widget_keyboard_foreground_suppresses_every_connected_monitor_group() { baseline .into_iter() .filter(|spec| spec.instance.as_ref().unwrap().as_str() == "DP-2") + .map(|mut spec| { + spec.keyboard = Keyboard::None; + spec + }) .collect::>() ); } @@ -623,6 +685,7 @@ fn widget_keyboard_foreground_suppresses_every_connected_monitor_group() { fn widget_keyboard_passive_toasts_do_not_suppress_notes() { let mut app = desktop(); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); app.update( Message::Notifications(crate::notifications::Message::Snapshot(Ok( @@ -676,6 +739,7 @@ fn widget_keyboard_history_suppression_spans_both_ack_orders_and_uri_dispatch() for release_first in [false, true] { let mut app = desktop(); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); let target = show_link_history(&mut app); let mut effects = begin_link(&mut app, target); @@ -711,7 +775,7 @@ fn widget_keyboard_history_suppression_spans_both_ack_orders_and_uri_dispatch() assert_suppressed_widgets(&app, &baseline); app.update(done, &mut effects); assert!(!app.notifications.history_open()); - assert_eq!(widget_specs(&app), baseline); + assert_suppressed_widgets(&app, &baseline); } } @@ -719,6 +783,7 @@ fn widget_keyboard_history_suppression_spans_both_ack_orders_and_uri_dispatch() fn widget_keyboard_cancelled_link_cannot_override_a_new_foreground_panel() { let mut app = desktop(); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); let target = show_link_history(&mut app); let mut effects = begin_link(&mut app, target); @@ -736,7 +801,7 @@ fn widget_keyboard_cancelled_link_cannot_override_a_new_foreground_panel() { assert!(effects.tasks.is_empty()); assert_suppressed_widgets(&app, &baseline); app.update(Message::DismissPanels, &mut effects); - assert_eq!(widget_specs(&app), baseline); + assert_suppressed_widgets(&app, &baseline); } #[test] @@ -744,6 +809,7 @@ fn widget_keyboard_release_failure_keeps_history_suppression_and_skips_uri_dispa for outcome in [InputReleaseOutcome::Timeout, InputReleaseOutcome::Retired] { let mut app = desktop(); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); let target = show_link_history(&mut app); let mut effects = begin_link(&mut app, target); @@ -783,6 +849,7 @@ fn widget_keyboard_uri_adapter_failure_keeps_history_suppression() { adapters.uri = std::sync::Arc::new(RejectedUri); let mut app = Desktop::new(adapters); app.settings.layout = separated(); + press_member(&mut app, None, "notes", true); let baseline = widget_specs(&app); let target = show_link_history(&mut app); let mut effects = begin_link(&mut app, target); @@ -807,3 +874,174 @@ fn widget_keyboard_uri_adapter_failure_keeps_history_suppression() { assert!(!app.notifications.yielding_input()); assert_suppressed_widgets(&app, &baseline); } + +#[test] +fn widget_keyboard_foreground_cancels_queued_focus_ack_without_rearming_on_close() { + let mut app = desktop(); + app.settings.layout = separated(); + let mut effects = press_member(&mut app, None, "notes", true); + let request = effects.keyboard_focus.pop().unwrap(); + let cancel = request.cancellation.clone(); + let queued = request + .finish(KeyboardFocusOutcome::Focused(NativeSurfaceToken::new())) + .unwrap(); + app.update(Message::Audio(crate::audio::Message::Open), &mut effects); + assert!(cancel.cancelled()); + app.update(queued, &mut effects); + app.update(Message::DismissPanels, &mut effects); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); +} + +#[test] +fn widget_keyboard_loss_requires_acknowledged_exact_native_lifetime() { + let mut app = desktop(); + app.settings.layout = separated(); + let mut effects = press_member(&mut app, None, "notes", true); + let old = NativeSurfaceToken::new(); + let native = NativeSurfaceToken::new(); + for change in [KeyboardFocusChange::Left, KeyboardFocusChange::Retired] { + let event = lucent_api::Event::KeyboardFocus { + surface: "notes", + native: old.clone(), + change, + }; + app.update(app.event(event).unwrap(), &mut effects); + assert_eq!( + widget_keyboard(&app)[&address("notes", None)], + Keyboard::OnDemand + ); + } + let focused = effects + .keyboard_focus + .pop() + .unwrap() + .finish(KeyboardFocusOutcome::Focused(native.clone())) + .unwrap(); + app.update(focused, &mut effects); + let event = lucent_api::Event::KeyboardFocus { + surface: "notes", + native, + change: KeyboardFocusChange::Left, + }; + app.update(app.event(event).unwrap(), &mut effects); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); +} + +#[test] +fn widget_keyboard_latest_output_press_replaces_owner_and_retired_route_cannot_rearm() { + let mut app = desktop(); + app.settings.layout = separated(); + connect(&mut app); + let mut first = press_member(&mut app, Some("DP-1"), "notes", true); + let first = first.keyboard_focus.pop().unwrap(); + let mut second = press_member(&mut app, Some("DP-2"), "notes", true); + assert!(first.cancellation.cancelled()); + assert_eq!( + widget_specs(&app) + .iter() + .filter(|spec| spec.keyboard == Keyboard::OnDemand) + .map(SurfaceSpec::address) + .collect::>(), + vec![address("notes", Some("DP-2"))] + ); + let request = second.keyboard_focus.pop().unwrap(); + let cancellation = request.cancellation.clone(); + let queued = request + .finish(KeyboardFocusOutcome::Focused(NativeSurfaceToken::new())) + .unwrap(); + app.update( + Message::Outputs(vec![output(Some("DP-1"), 1)]), + &mut Effects::default(), + ); + assert!(cancellation.cancelled()); + app.update(queued, &mut Effects::default()); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); +} + +#[test] +fn widget_keyboard_unavailable_request_is_visible_and_never_leaves_eligibility_armed() { + let mut app = desktop(); + app.settings.layout = separated(); + let mut effects = press_member(&mut app, None, "notes", true); + let failure = effects + .keyboard_focus + .pop() + .unwrap() + .finish(KeyboardFocusOutcome::Unavailable) + .unwrap(); + app.update(failure, &mut effects); + assert!(app.error.contains("compositor")); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); +} + +#[test] +fn widget_keyboard_delivered_first_notes_edit_keeps_intent_and_programmatic_controls_do_not_arm() { + let mut app = desktop(); + app.settings.layout = separated(); + app.settings.notes.clear(); + let mut effects = press_member(&mut app, None, "notes", true); + app.update( + Message::Widgets(widgets::Message::EditNotes(lucent_api::TextEdit::Insert( + "a".into(), + ))), + &mut effects, + ); + assert_eq!(app.settings.notes, "a"); + assert_eq!( + widget_keyboard(&app)[&address("notes", None)], + Keyboard::OnDemand + ); + assert_eq!(effects.keyboard_focus.len(), 1); + app.update(Message::Audio(crate::audio::Message::Open), &mut effects); + app.update(Message::DismissPanels, &mut effects); + for message in [ + widgets::Message::Month(1), + widgets::Message::TimerToggle, + widgets::Message::TimerReset, + ] { + app.update(Message::Widgets(message), &mut effects); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); + } + // This is controlled message ordering, not proof that a native compositor + // delivered the first physical key; that remains an integration requirement. +} + +#[test] +fn widget_keyboard_named_output_transition_cancels_dormant_legacy_intent() { + let mut app = desktop(); + app.settings.layout = separated(); + let mut effects = press_member(&mut app, None, "notes", true); + let request = effects.keyboard_focus.pop().unwrap(); + connect(&mut app); + assert!(request.cancellation.cancelled()); + app.update( + Message::Outputs(vec![output(None, 99)]), + &mut Effects::default(), + ); + assert!(app.monitors.legacy()); + assert!( + widget_specs(&app) + .iter() + .all(|spec| spec.keyboard == Keyboard::None) + ); +} diff --git a/lucent/apps/lucent-desktop/src/widgets/keyboard_demand.rs b/lucent/apps/lucent-desktop/src/widgets/keyboard_demand.rs new file mode 100644 index 00000000..1082fc1a --- /dev/null +++ b/lucent/apps/lucent-desktop/src/widgets/keyboard_demand.rs @@ -0,0 +1,212 @@ +//! Transient user intent, independent of the catalog's control capabilities. +use super::Message; +use lucent_api::{ + Cancellation, Effects, KeyboardFocusChange, KeyboardFocusOutcome, NativeSurfaceToken, + SurfaceAddress, +}; +use std::{fmt, sync::Arc}; + +/// Identity of a single user request, including across Host replacement. A +/// queued completion cannot establish a later request's native ownership. +#[derive(Clone)] +pub struct RequestId(Arc<()>); +impl PartialEq for RequestId { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} +impl Eq for RequestId {} +impl fmt::Debug for RequestId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("KeyboardRequest(..)") + } +} +struct Owner { + request: RequestId, + member: &'static str, + target: SurfaceAddress, + cancellation: Cancellation, + native: Option, +} +impl Drop for Owner { + fn drop(&mut self) { + self.cancellation.cancel(); + } +} +#[derive(Default)] +pub(super) struct Demand(Option); +impl Demand { + pub fn present(&self) -> bool { + self.0.is_some() + } + pub fn clear(&mut self) -> bool { + self.0.take().is_some() + } + pub fn begin( + &mut self, + member: &'static str, + target: SurfaceAddress, + effects: &mut Effects, + ) { + self.clear(); + let request = RequestId(Arc::new(())); + let cancellation = Cancellation::default(); + let callback_id = request.clone(); + effects.request_keyboard_focus(target.clone(), cancellation.clone(), move |outcome| { + Message::KeyboardResolved(callback_id, outcome) + }); + self.0 = Some(Owner { + request, + member, + target, + cancellation, + native: None, + }); + } + pub fn matches(&self, target: &SurfaceAddress, members: &[&str]) -> bool { + self.0 + .as_ref() + .is_some_and(|owner| &owner.target == target && members.contains(&owner.member)) + } + pub fn resolve( + &mut self, + request: &RequestId, + outcome: KeyboardFocusOutcome, + ) -> Option<&'static str> { + let owner = self.0.as_mut().filter(|owner| owner.request == *request)?; + match outcome { + KeyboardFocusOutcome::Focused(native) => { + owner.native = Some(native); + None + } + outcome => { + self.clear(); + match outcome { + KeyboardFocusOutcome::Unavailable => { + Some("This compositor cannot focus widget controls") + } + KeyboardFocusOutcome::NotRetained => { + Some("The compositor did not retain widget keyboard focus") + } + KeyboardFocusOutcome::Rejected => Some("The widget focus request was rejected"), + KeyboardFocusOutcome::Timeout => { + Some("The widget did not receive keyboard focus") + } + _ => None, + } + } + } + } + pub fn observe(&mut self, native: &NativeSurfaceToken, change: KeyboardFocusChange) -> bool { + // Enter is not a new user request. A pending request must not be + // cancelled by a queued Leave from the previous scope before its Enter. + if change == KeyboardFocusChange::Entered + || !self + .0 + .as_ref() + .is_some_and(|owner| owner.native.as_ref() == Some(native)) + { + return false; + } + self.clear() + } +} +#[cfg(test)] +mod tests { + use super::*; + fn start(demand: &mut Demand) -> (RequestId, Cancellation) { + let mut effects = Effects::default(); + demand.begin("notes", SurfaceAddress::new("clock"), &mut effects); + let request = effects.keyboard_focus.pop().unwrap(); + let cancellation = request.cancellation.clone(); + let Message::KeyboardResolved(id, _) = + request.finish(KeyboardFocusOutcome::Unavailable).unwrap() + else { + panic!("typed completion") + }; + (id, cancellation) + } + #[test] + fn capability_and_foreground_close_do_not_create_keyboard_demand() { + let mut demand = Demand::default(); + assert!(!demand.matches(&SurfaceAddress::new("clock"), &["clock", "notes"])); + let (_, cancel) = start(&mut demand); + assert!(demand.matches(&SurfaceAddress::new("clock"), &["clock", "notes"])); + assert!(!demand.matches(&SurfaceAddress::new("clock"), &["clock", "media"])); + assert!(demand.clear()); + assert!(cancel.cancelled()); + assert!(!demand.matches(&SurfaceAddress::new("clock"), &["clock", "notes"])); + } + #[test] + fn stale_acknowledgement_and_unrelated_native_loss_cannot_change_new_demand() { + let mut demand = Demand::default(); + let (old, old_cancel) = start(&mut demand); + let (current, _) = start(&mut demand); + assert!(old_cancel.cancelled()); + let old_native = NativeSurfaceToken::new(); + assert!( + demand + .resolve(&old, KeyboardFocusOutcome::Focused(old_native.clone())) + .is_none() + ); + assert!(!demand.observe(&old_native, KeyboardFocusChange::Left)); + let current_native = NativeSurfaceToken::new(); + demand.resolve( + ¤t, + KeyboardFocusOutcome::Focused(current_native.clone()), + ); + assert!(!demand.observe(&old_native, KeyboardFocusChange::Retired)); + assert!(demand.observe(¤t_native, KeyboardFocusChange::Left)); + } + #[test] + fn pending_demand_ignores_prior_leave_and_waits_for_exact_focus_ack() { + let mut demand = Demand::default(); + let (request, _) = start(&mut demand); + let native = NativeSurfaceToken::new(); + assert!(!demand.observe(&native, KeyboardFocusChange::Left)); + assert!(!demand.observe(&native, KeyboardFocusChange::Entered)); + demand.resolve(&request, KeyboardFocusOutcome::Focused(native.clone())); + assert!(demand.observe(&native, KeyboardFocusChange::Left)); + } + #[test] + fn every_request_failure_and_host_drop_cancel_owned_request() { + for outcome in [ + KeyboardFocusOutcome::Unavailable, + KeyboardFocusOutcome::NotRetained, + KeyboardFocusOutcome::Rejected, + KeyboardFocusOutcome::Retired, + KeyboardFocusOutcome::Superseded, + KeyboardFocusOutcome::Cleared, + KeyboardFocusOutcome::Timeout, + ] { + let mut demand = Demand::default(); + let (request, cancel) = start(&mut demand); + demand.resolve(&request, outcome); + assert!(cancel.cancelled()); + assert!(!demand.matches(&SurfaceAddress::new("clock"), &["notes"])); + } + let mut demand = Demand::default(); + let (_, cancel) = start(&mut demand); + drop(demand); + assert!(cancel.cancelled()); + } + #[test] + fn demand_is_scoped_to_exact_output_and_member_group() { + let mut demand = Demand::default(); + let output = lucent_api::SurfaceInstance::new("DP-2").unwrap(); + demand.begin( + "notes", + SurfaceAddress::new("clock").instance(output.clone()), + &mut Effects::default(), + ); + assert!(!demand.matches(&SurfaceAddress::new("clock"), &["clock", "notes"])); + assert!(!demand.matches( + &SurfaceAddress::new("notes").instance(output.clone()), + &["notes"] + )); + assert!(demand.matches( + &SurfaceAddress::new("clock").instance(output), + &["clock", "notes"] + )); + } +} diff --git a/lucent/apps/lucent-desktop/src/widgets/mod.rs b/lucent/apps/lucent-desktop/src/widgets/mod.rs index a76870c3..cfc82970 100644 --- a/lucent/apps/lucent-desktop/src/widgets/mod.rs +++ b/lucent/apps/lucent-desktop/src/widgets/mod.rs @@ -1,7 +1,9 @@ //! Widget interaction belongs to this child; persistence and OS actions return //! as intents to the composition root. Views only borrow snapshots and artwork. pub mod catalog; +mod keyboard_demand; mod sizing; +pub use keyboard_demand::RequestId as KeyboardRequestId; pub mod surfaces; mod view; use lucent_api::{ClipboardTarget, DragEvent, Effects, ScrollEvent, TextEdit, TextFieldState}; @@ -22,6 +24,13 @@ pub enum Message { SizeStep(String, i32), Edit(bool), Press, + /// The exact member and prepared target come from the SDK press observer. + PressMember(String, lucent_api::PointerPress), + KeyboardResolved(KeyboardRequestId, lucent_api::KeyboardFocusOutcome), + KeyboardNative( + lucent_api::NativeSurfaceToken, + lucent_api::KeyboardFocusChange, + ), EditNotes(TextEdit), ScrollNotes(ScrollEvent), RetrySave, @@ -62,6 +71,7 @@ enum Drag { Cancelled, } pub struct Host { + keyboard: keyboard_demand::Demand, drags: BTreeMap, resizer: sizing::Resizer, captured_surfaces: Option>, @@ -73,6 +83,7 @@ pub struct Host { impl Default for Host { fn default() -> Self { Self { + keyboard: keyboard_demand::Demand::default(), drags: BTreeMap::new(), resizer: sizing::Resizer::default(), captured_surfaces: None, @@ -84,6 +95,37 @@ impl Default for Host { } } impl Host { + pub fn clear_keyboard_demand(&mut self) -> bool { + self.keyboard.clear() + } + pub fn keyboard_requested( + &self, + source: &surfaces::Surface, + instance: Option<&lucent_api::SurfaceInstance>, + ) -> bool { + let mut address = lucent_api::SurfaceAddress::new(source.id); + address.instance = instance.cloned(); + self.keyboard.matches(&address, &source.members) + } + pub fn reconcile_keyboard( + &mut self, + settings: &WidgetLayout, + viewport: (f32, f32), + instance: Option<&lucent_api::SurfaceInstance>, + ) -> bool { + if !self.keyboard.present() { + return false; + } + if !self + .surfaces(settings, viewport) + .iter() + .any(|source| self.keyboard_requested(source, instance)) + { + self.keyboard.clear() + } else { + false + } + } pub fn grid_visible(&self) -> bool { self.resizer.active() || self @@ -150,6 +192,10 @@ impl Host { } } pub(crate) fn cancel_interactions(&mut self) { + self.keyboard.clear(); + self.cancel_pointer_interactions(); + } + fn cancel_pointer_interactions(&mut self) { self.resizer.cancel(); for drag in self.drags.values_mut() { *drag = Drag::Cancelled; @@ -297,7 +343,7 @@ impl Host { } } Message::Size(id, size) => { - self.cancel_interactions(); + self.cancel_pointer_interactions(); let result = self.resizer.set(&id, size, settings, input.viewport); if !self.grid_visible() { self.captured_surfaces = None; @@ -314,7 +360,7 @@ impl Host { && catalog::find(&id).is_some() && settings.visible_widgets.contains(&id) { - self.cancel_interactions(); + self.cancel_pointer_interactions(); } let result = self.resizer.step(&id, delta, settings, input.viewport); if !self.grid_visible() { @@ -334,6 +380,39 @@ impl Host { effects.redraw("dock"); None } + Message::PressMember(id, press) => { + if press.button != lucent_api::MouseButton::Primary { + return None; + } + self.keyboard.clear(); + let definition = catalog::find(&id)?; + if !press.keyboard_focusable || !(definition.keyboard_interactive || self.editing()) + { + return None; + } + let source = self + .surfaces(settings, input.viewport) + .into_iter() + .find(|source| source.members.contains(&definition.id))?; + let mut target = lucent_api::SurfaceAddress::new(source.id); + target.instance = input.instance.clone(); + self.keyboard.begin(definition.id, target, effects); + effects.redraw("widgets"); + None + } + Message::KeyboardResolved(request, outcome) => { + let error = self.keyboard.resolve(&request, outcome); + effects.redraw("widgets"); + error.map(|error| { + Intent::Error(lucent_domain::DomainError::Unavailable(error.into())) + }) + } + Message::KeyboardNative(native, change) => { + if self.keyboard.observe(&native, change) { + effects.redraw("widgets"); + } + None + } Message::Press => { self.drags.clear(); self.resizer.press(); diff --git a/lucent/apps/lucent-desktop/src/widgets/view.rs b/lucent/apps/lucent-desktop/src/widgets/view.rs index dbe3f726..b775e948 100644 --- a/lucent/apps/lucent-desktop/src/widgets/view.rs +++ b/lucent/apps/lucent-desktop/src/widgets/view.rs @@ -145,6 +145,7 @@ impl View<'_> { } } let drag_id = id.to_owned(); + let press_id = id.to_owned(); Element::stack(children) .size(size.0, size.1 + editor_height) .at(pos.0, pos.1) @@ -156,6 +157,7 @@ impl View<'_> { .radius(radius::WIDGET) .clip() .shadow() + .on_pointer_press(move |press| Message::PressMember(press_id.clone(), press)) .on_drag(move |drag| Message::Move(drag_id.clone(), drag)) .id(format!("widget-{id}")) } diff --git a/lucent/apps/lucent-menu/src/lib.rs b/lucent/apps/lucent-menu/src/lib.rs index d2dbac54..7f632498 100644 --- a/lucent/apps/lucent-menu/src/lib.rs +++ b/lucent/apps/lucent-menu/src/lib.rs @@ -378,7 +378,7 @@ impl Application for Menu { match event { Event::OutputsChanged(_) | Event::Scoped { .. } => None, Event::PointerInside { .. } | Event::PointerButton { .. } => None, - Event::FrameSubmitted { .. } => None, + Event::FrameSubmitted { .. } | Event::KeyboardFocus { .. } => None, Event::Outside { .. } => Some(Message::Cancel), Event::Resize { width, height, .. } => Some(Message::Resize(width, height)), Event::Scroll { lines, .. } => Some(Message::Navigate(if lines > 0. { 1 } else { -1 })), diff --git a/lucent/apps/lucent-session/src/lib.rs b/lucent/apps/lucent-session/src/lib.rs index df33ef45..82fbc4e0 100644 --- a/lucent/apps/lucent-session/src/lib.rs +++ b/lucent/apps/lucent-session/src/lib.rs @@ -535,6 +535,9 @@ mod tests { let app = SessionScreen::new(mode, "identity-fixture".into(), Arc::new(Deny)); assert!(!lucent_api::Application::input_method_enabled(&app)); assert!(!lucent_api::Application::clipboard_enabled(&app)); + assert!(!lucent_api::Application::keyboard_focus_requests_enabled( + &app + )); } } struct Deny; diff --git a/lucent/crates/lucent-api/src/keyboard_focus.rs b/lucent/crates/lucent-api/src/keyboard_focus.rs new file mode 100644 index 00000000..48ca8ecd --- /dev/null +++ b/lucent/crates/lucent-api/src/keyboard_focus.rs @@ -0,0 +1,155 @@ +//! Explicit, one-shot keyboard focus requests for ordinary native surfaces. +use crate::{Cancellation, Effects, SurfaceAddress}; +use std::{fmt, sync::Arc}; + +/// Opaque identity of one native surface lifetime. A clone keeps only an +/// identity alive, never a renderer or protocol object. Logical surface names +/// and profiling generations cannot substitute for this identity. +#[derive(Clone, Default)] +pub struct NativeSurfaceToken(Arc<()>); +impl NativeSurfaceToken { + pub fn new() -> Self { + Self::default() + } +} +impl PartialEq for NativeSurfaceToken { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} +impl Eq for NativeSurfaceToken {} +impl fmt::Debug for NativeSurfaceToken { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("NativeSurfaceToken(..)") + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum KeyboardFocusChange { + /// A dispatched Enter on this client's selected native keyboard. + Entered, + /// A dispatched Leave on this client's selected native keyboard. + Left, + /// The exact native lifetime has been removed or replaced. + Retired, + /// The selected native keyboard or its seat has become unavailable. + Unavailable, +} +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum KeyboardFocusOutcome { + /// Actual Enter was observed for the exact admitted native lifetime. This + /// does not establish global compositor focus after later events. + Focused(NativeSurfaceToken), + /// The native backend observed Enter, but its own temporary acquisition + /// teardown did not retain focus through its bounded synchronization. + NotRetained, + Unavailable, + Rejected, + Retired, + Superseded, + Cleared, + Timeout, +} +pub struct KeyboardFocusRequest { + pub surface: SurfaceAddress, + pub cancellation: Cancellation, + complete: Box M + Send>, +} +impl KeyboardFocusRequest { + pub fn new( + surface: SurfaceAddress, + cancellation: Cancellation, + complete: impl FnOnce(KeyboardFocusOutcome) -> M + Send + 'static, + ) -> Self { + Self { + surface, + cancellation, + complete: Box::new(complete), + } + } + pub fn finish(self, outcome: KeyboardFocusOutcome) -> Option { + (!self.cancellation.cancelled()).then(|| (self.complete)(outcome)) + } + pub fn map( + self, + map: impl FnOnce(M) -> N + Send + 'static, + ) -> KeyboardFocusRequest { + KeyboardFocusRequest { + surface: self.surface, + cancellation: self.cancellation, + complete: Box::new(move |outcome| map((self.complete)(outcome))), + } + } +} +impl Effects { + /// Request keyboard focus from the current genuine primary press on a + /// keyboard-focusable prepared hit. This grants no synthetic input authority: + /// unsupported backends, secure roles, other surfaces and stale lifetimes + /// reject. The target must request OnDemand. The runtime preserves presented + /// geometry when committing eligibility; it never promotes a layer or pulses + /// Exclusive. An optional native adapter may briefly acquire a focus scope, + /// but must release it when Enter is observed, preserving ordinary inline UI + /// behavior rather than holding a persistent pointer/keyboard restriction. + /// + /// Cancellation applies to the pending request only. Focused acknowledges + /// the exact native Enter retained through the backend's own bounded + /// acquisition teardown, never merely a protocol commit, and does not + /// promise continued ownership: normal KeyboardFocus loss events remain + /// authoritative. The client requests None when its intent ends. Immediate + /// first-key and outside-click delivery require compositor integration tests; + /// this API promises no zero wire latency or global compositor ownership. + pub fn request_keyboard_focus( + &mut self, + surface: SurfaceAddress, + cancellation: Cancellation, + complete: impl FnOnce(KeyboardFocusOutcome) -> M + Send + 'static, + ) { + self.keyboard_focus + .push(KeyboardFocusRequest::new(surface, cancellation, complete)); + } +} +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn native_tokens_identify_lifetimes_without_aliasing_replacements() { + let original = NativeSurfaceToken::new(); + assert_eq!(original, original.clone()); + assert_ne!(original, NativeSurfaceToken::new()); + assert_eq!(format!("{original:?}"), "NativeSurfaceToken(..)"); + } + #[test] + fn delegated_focus_request_retains_target_token_and_cancellation() { + let cancel = Cancellation::default(); + let token = NativeSurfaceToken::new(); + let mut parent = Effects::<(u8, KeyboardFocusOutcome)>::default(); + parent.delegate( + |child| { + child.request_keyboard_focus( + SurfaceAddress::new("editor"), + cancel.clone(), + std::convert::identity, + ) + }, + |outcome| (7, outcome), + ); + let request = parent.keyboard_focus.pop().unwrap(); + assert_eq!(request.surface, SurfaceAddress::new("editor")); + assert_eq!( + request.finish(KeyboardFocusOutcome::Focused(token.clone())), + Some((7, KeyboardFocusOutcome::Focused(token))) + ); + parent.request_keyboard_focus(SurfaceAddress::new("editor"), cancel.clone(), |outcome| { + (9, outcome) + }); + cancel.cancel(); + assert!( + parent + .keyboard_focus + .pop() + .unwrap() + .finish(KeyboardFocusOutcome::Timeout) + .is_none() + ); + } +} diff --git a/lucent/crates/lucent-api/src/lib.rs b/lucent/crates/lucent-api/src/lib.rs index dcbf515c..d0234191 100644 --- a/lucent/crates/lucent-api/src/lib.rs +++ b/lucent/crates/lucent-api/src/lib.rs @@ -2,8 +2,12 @@ mod activation; mod clipboard; mod input_release; +mod keyboard_focus; pub use activation::{ActivationOutcome, ActivationRequest, ActivationToken}; pub use input_release::{InputReleaseOutcome, InputReleaseRequest}; +pub use keyboard_focus::{ + KeyboardFocusChange, KeyboardFocusOutcome, KeyboardFocusRequest, NativeSurfaceToken, +}; mod density; mod output; mod surface; @@ -299,6 +303,14 @@ pub type ScrollCallback = Arc M + Send + Sync>; pub type SliderCallback = Arc M + Send + Sync>; pub type DragCallback = Arc M + Send + Sync>; pub type WheelCallback = Arc M + Send + Sync>; +/// A physical press on the actual prepared, clipped pointer target. This is +/// distinct from the component which retained keyboard focus before the press. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct PointerPress { + pub button: MouseButton, + pub keyboard_focusable: bool, +} +pub type PointerPressCallback = Arc M + Send + Sync>; #[derive(Clone)] pub struct Element { pub id: String, @@ -311,6 +323,7 @@ pub struct Element { pub secondary_click: Option, pub middle_click: Option, pub wheel: Option>, + pub pointer_press: Option>, pub submit: Option, pub hover: Option, pub input: Option>, @@ -335,6 +348,7 @@ impl Element { secondary_click: None, middle_click: None, wheel: None, + pointer_press: None, submit: None, hover: None, input: None, @@ -653,6 +667,18 @@ impl Element { self.wheel = Some(Arc::new(callback)); self } + /// Observe a physical press on an existing hit in this subtree. The nearest + /// observer receives one message before the pressed control's action. This + /// adds neither a hit region nor a keyboard traversal stop; rounded clips, + /// transforms, stacking and outside-popover dismissal keep their usual rules. + /// Keyboard activation does not synthesize this user-intent observation. + pub fn on_pointer_press( + mut self, + callback: impl Fn(PointerPress) -> M + Send + Sync + 'static, + ) -> Self { + self.pointer_press = Some(Arc::new(callback)); + self + } pub fn on_hover(mut self, msg: M) -> Self { self.hover = Some(msg); self @@ -865,6 +891,14 @@ pub enum Event { x: f32, y: f32, }, + /// Own-client native keyboard observations/lifecycle. Tokens identify exact + /// native lifetimes, independently of logical names and profiling settings. + /// Absence or loss here does not establish the compositor's global owner. + KeyboardFocus { + surface: &'static str, + native: NativeSurfaceToken, + change: KeyboardFocusChange, + }, /// A successful buffer submission, after view/layout/render. This is not /// scanout or a compositor display acknowledgement. `now` is the view's /// animation time; dimensions are the submitted logical buffer extent. @@ -904,6 +938,12 @@ pub trait Component: 'static { } /// An application supplies surfaces and subscriptions in addition to its component tree. pub trait Application: Component { + /// Opt into explicit ordinary native keyboard requests. Secure clients keep the + /// default disabled; backend availability and physical-gesture checks apply. + fn keyboard_focus_requests_enabled(&self) -> bool { + false + } + /// Compositor input methods require explicit ordinary-client authority. /// Authentication clients leave this disabled, independently of clipboard/IPC. fn input_method_enabled(&self) -> bool { @@ -992,6 +1032,7 @@ pub struct Effects { pub clipboard: Vec>, pub activation: Vec>, pub input_release: Vec>, + pub keyboard_focus: Vec>, } impl Default for Effects { fn default() -> Self { @@ -1005,6 +1046,7 @@ impl Default for Effects { clipboard: vec![], activation: vec![], input_release: vec![], + keyboard_focus: vec![], } } } @@ -1102,6 +1144,11 @@ impl Effects { self.clipboard .push(request.map(move |message| map(message))); } + for request in child.keyboard_focus { + let map = map.clone(); + self.keyboard_focus + .push(request.map(move |message| map(message))); + } for request in child.input_release { let map = map.clone(); self.input_release @@ -1448,6 +1495,10 @@ impl Element { let map = mapper.clone(); Arc::new(move |event| map(callback(event))) as WheelCallback }); + let pointer_press = self.pointer_press.map(|callback| { + let map = mapper.clone(); + Arc::new(move |event| map(callback(event))) as PointerPressCallback + }); Element { id: self.id, kind: self.kind, @@ -1479,6 +1530,7 @@ impl Element { secondary_click: self.secondary_click.map(|m| mapper(m)), middle_click: self.middle_click.map(|m| mapper(m)), wheel, + pointer_press, submit: self.submit.map(|m| mapper(m)), hover: self.hover.map(|m| mapper(m)), input, diff --git a/lucent/crates/lucent-ui/src/focus_presentation.rs b/lucent/crates/lucent-ui/src/focus_presentation.rs new file mode 100644 index 00000000..736b4867 --- /dev/null +++ b/lucent/crates/lucent-ui/src/focus_presentation.rs @@ -0,0 +1,144 @@ +//! Native keyboard ownership gates paint without discarding logical selection. +use crate::Interaction; + +impl Interaction { + /// Runners set actual input-context activity independently from the logical + /// component target and keyboard-versus-pointer focus-decoration modality. + /// Returns whether paint needs invalidation. This never requests native + /// focus, changes selection, resets scroll or cancels pointer capture. + pub fn set_keyboard_active(&mut self, active: bool) -> bool { + let changed = self.keyboard_active != active; + self.keyboard_active = active; + changed + } + pub fn keyboard_active(&self) -> bool { + self.keyboard_active + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{Layout, Paint, Scene}; + use lucent_api::{Element, ScrollSpec, TextEdit, TextSelection}; + use std::sync::Arc; + + fn layout() -> Layout { + let font = crate::text::Font::from_bytes( + include_bytes!("../../../apps/lucent-desktop/assets/LucentSans.ttf") as &[u8], + fontdue::FontSettings::default(), + ) + .unwrap(); + Layout::new(Arc::new(vec![font])) + } + fn decorations(scene: &Scene<()>) -> (usize, usize) { + ( + scene + .paint + .iter() + .filter(|paint| matches!(paint, Paint::Shape { .. })) + .count(), + scene + .paint + .iter() + .filter(|paint| matches!(paint, Paint::Outline { .. })) + .count(), + ) + } + #[test] + fn native_leave_hides_caret_and_outline_but_retains_logical_selection_and_scroll() { + let layout = layout(); + let mut value = "A deliberately long field with a visible caret at its end".to_string(); + let mut selection = TextSelection::default(); + let caret = value.len(); + selection + .apply(&mut value, TextEdit::Select { anchor: 1, caret }, 1024) + .unwrap(); + let field = Element::text_input(value.clone(), selection, "", |_| ()) + .id("field") + .focus_outline(true) + .padding(8.); + let mut interaction = Interaction { + focus: Some("field".into()), + focus_visible: true, + ..Default::default() + }; + let active = layout.build(&field, 140., 48., &interaction, 0.); + assert!(decorations(&active).0 >= 2, "selection and caret paint"); + assert_eq!(decorations(&active).1, 1); + let text = active.hits[0].text.as_ref().unwrap(); + let scroll = text.scroll; + assert!(scroll > 0.); + assert!(interaction.set_keyboard_active(false)); + assert!(!interaction.set_keyboard_active(false)); + let inactive = layout.build(&field, 140., 48., &interaction, 0.); + assert_eq!(decorations(&inactive), (0, 0)); + assert_eq!(interaction.focus.as_deref(), Some("field")); + assert!(interaction.focus_visible, "decoration modality is retained"); + assert_eq!(inactive.hits[0].text.as_ref().unwrap().selection, selection); + assert_eq!(inactive.hits[0].text.as_ref().unwrap().scroll, scroll); + assert!(interaction.set_keyboard_active(true)); + let reacquired = layout.build(&field, 140., 48., &interaction, 0.); + assert_eq!(decorations(&reacquired), decorations(&active)); + assert_eq!( + reacquired.hits[0].text.as_ref().unwrap().selection, + selection + ); + assert_eq!(reacquired.hits[0].text.as_ref().unwrap().scroll, scroll); + } + #[test] + fn multiline_caret_is_inactive_without_losing_ordinary_editor_hit_geometry() { + let layout = layout(); + let field = Element::text_area( + "notes", + TextSelection::at_end("notes"), + "", + ScrollSpec::new(0., 20.).unwrap(), + |_| (), + |_| (), + ) + .id("notes") + .focus_outline(true) + .padding(8.); + let mut interaction = Interaction { + focus: Some("notes".into()), + focus_visible: true, + ..Default::default() + }; + let active = layout.build(&field, 200., 100., &interaction, 0.); + assert_eq!(decorations(&active), (1, 1)); + interaction.set_keyboard_active(false); + let inactive = layout.build(&field, 200., 100., &interaction, 0.); + assert_eq!(decorations(&inactive), (0, 0)); + assert_eq!(inactive.hits.len(), active.hits.len()); + assert_eq!(inactive.hits[0].rect, active.hits[0].rect); + assert_eq!(inactive.hits[0].text.as_ref().unwrap().selection.caret(), 5); + assert!(!interaction.animating(0.)); + assert_eq!(interaction.next_wakeup(&inactive, 0.), None); + } + #[test] + fn inactive_composition_has_no_caret_or_underlines_and_creates_no_idle_deadline() { + let layout = layout(); + let field = + Element::text_input("abc", TextSelection::at_end("abc"), "", |_| ()).id("field"); + let mut interaction = Interaction { + focus: Some("field".into()), + ..Default::default() + }; + let prepared = layout.build(&field, 200., 48., &interaction, 0.); + assert!(interaction.set_preedit(&prepared, Some(("fixture".into(), 0, 7)))); + let active = layout.build(&field, 200., 48., &interaction, 0.); + assert!(decorations(&active).0 > 0); + interaction.set_keyboard_active(false); + let inactive = layout.build(&field, 200., 48., &interaction, 0.); + assert_eq!(decorations(&inactive), (0, 0)); + assert_eq!(interaction.focus.as_deref(), Some("field")); + assert!(!interaction.animating(0.)); + assert_eq!(interaction.next_wakeup(&inactive, 0.), None); + } + #[test] + fn offscreen_default_keeps_existing_active_focus_fixtures_explicit() { + let interaction = Interaction::<()>::default(); + assert!(interaction.keyboard_active()); + } +} diff --git a/lucent/crates/lucent-ui/src/lib.rs b/lucent/crates/lucent-ui/src/lib.rs index f482c034..ba31b002 100644 --- a/lucent/crates/lucent-ui/src/lib.rs +++ b/lucent/crates/lucent-ui/src/lib.rs @@ -1,6 +1,8 @@ //! Layout, hit testing and retained interaction state for declarative components. +mod focus_presentation; mod overlay; mod pointer; +mod press_observation; use lucent_api::*; pub use overlay::OverlayScene; mod scroll; @@ -72,6 +74,7 @@ pub struct Hit { pub secondary_click: Option, pub middle_click: Option, pub wheel: Option>, + pub pointer_press: Option>, pub submit: Option, pub hover: Option, pub input: Option>, @@ -370,6 +373,7 @@ impl Layout { None => clip, }; let paint_start = scene.paint.len(); + let hit_start = scene.hits.len(); let own_clip = if e.style.clip { clip.with_rounded(rect, e.style.radius) } else { @@ -550,6 +554,7 @@ impl Layout { secondary_click: e.secondary_click.clone(), middle_click: e.middle_click.clone(), wheel: e.wheel.clone(), + pointer_press: None, submit: e.submit.clone(), hover: e.hover.clone(), input: e.input.clone(), @@ -618,7 +623,7 @@ impl Layout { .inner, ), alpha, - interaction.focus.as_deref() == Some(&id), + interaction.keyboard_active && interaction.focus.as_deref() == Some(&id), self.fonts.get(e.style.font_face).unwrap_or(&self.fonts[0]), interaction, &id, @@ -671,7 +676,7 @@ impl Layout { color: fg, align: Align::Start, }); - if interaction.focus.as_deref() == Some(&id) { + if interaction.keyboard_active && interaction.focus.as_deref() == Some(&id) { let font = self.fonts.get(e.style.font_face).unwrap_or(&self.fonts[0]); let line = text::run_metrics(font, &value, e.style.font_size, None); let top = inner.y + (inner.h - line.height).max(0.) / 2.; @@ -844,7 +849,8 @@ impl Layout { .enumerate() .any(|(i, child)| contains_focus(child, focus, &format!("{path}/{i}"))) } - let focused = interaction.focus_visible + let focused = interaction.keyboard_active + && interaction.focus_visible && interaction.focus.as_deref().is_some_and(|focus| { focus == id || (e.style.focus_within && contains_focus(e, focus, path)) }); @@ -857,6 +863,13 @@ impl Layout { width: e.style.focus_width, }); } + // Descendants have already installed their closer observers. Attach + // this observer only to existing hits, without changing input coverage. + if let Some(observer) = &e.pointer_press { + for hit in &mut scene.hits[hit_start..] { + hit.pointer_press.get_or_insert_with(|| observer.clone()); + } + } if !e.style.paint { scene.paint.truncate(paint_start); } @@ -912,6 +925,7 @@ pub struct Interaction { pub focus: Option, pub hovered: Option, pub focus_visible: bool, + keyboard_active: bool, press: Option>, alternate_press: Option>, hover_transition: Transition, @@ -931,6 +945,9 @@ impl Default for Interaction { focus: None, hovered: None, focus_visible: false, + // Standalone/offscreen runners historically model an active input + // context. Native runners explicitly initialize this gate false. + keyboard_active: true, hover_transition: Transition::default(), press: None, alternate_press: None, @@ -1766,6 +1783,7 @@ mod tests { secondary_click: None, middle_click: None, wheel: None, + pointer_press: None, submit: None, input: None, edit: None, @@ -1855,6 +1873,7 @@ mod tests { secondary_click: None, middle_click: None, wheel: None, + pointer_press: None, submit: None, input: Some(Arc::new(|s: String| s)), edit: None, @@ -1914,6 +1933,7 @@ mod tests { secondary_click: None, middle_click: None, wheel: None, + pointer_press: None, submit: None, input: None, edit: None, diff --git a/lucent/crates/lucent-ui/src/overlay.rs b/lucent/crates/lucent-ui/src/overlay.rs index 0eb43533..83639ba9 100644 --- a/lucent/crates/lucent-ui/src/overlay.rs +++ b/lucent/crates/lucent-ui/src/overlay.rs @@ -470,7 +470,8 @@ impl Layout { } impl Interaction { fn tooltip_target<'a>(&self, scene: &'a Scene) -> Option<(&'a TooltipTarget, bool)> { - let keyboard = self.focus_visible + let keyboard = self.keyboard_active + && self.focus_visible && self .focus .as_ref() diff --git a/lucent/crates/lucent-ui/src/press_observation.rs b/lucent/crates/lucent-ui/src/press_observation.rs new file mode 100644 index 00000000..94a22f88 --- /dev/null +++ b/lucent/crates/lucent-ui/src/press_observation.rs @@ -0,0 +1,252 @@ +//! Physical intent follows the prepared hit, never a retained focus or re-hit. +use crate::{Interaction, Scene}; +use lucent_api::{KeyModifiers, MouseButton, PointerPress}; + +impl Interaction { + /// Inspect the actual captured primary target immediately after a physical + /// primary press. Runners pair this with their current native input origin; + /// this getter alone grants no user-gesture authority. + pub fn pressed_keyboard_focusable(&self) -> bool { + self.press.as_ref().is_some_and(|press| press.hit.tab_stop) + } + + /// Return the nearest subtree observer followed by the pressed control's + /// ordinary message. Runners dispatch in this order, retaining their native + /// lifetime guard between messages. Existing press APIs remain unchanged. + pub fn press_button_messages( + &mut self, + scene: &Scene, + x: f32, + y: f32, + button: MouseButton, + modifiers: KeyModifiers, + ) -> [Option; 2] { + // Dismissal consumes this press; an underlying subtree did not receive + // it and must not acquire an interaction merely because it has a hit. + if let Some(dismiss) = self.popover_outside_press(scene, x, y) { + return [None, Some(dismiss)]; + } + let observation = scene + .hits + .iter() + .rev() + .find(|hit| hit.contains(x, y)) + .and_then(|hit| { + hit.pointer_press.as_ref().map(|observe| { + observe(PointerPress { + button, + keyboard_focusable: hit.tab_stop, + }) + }) + }); + let action = self.press_button(scene, x, y, button, modifiers); + [observation, action] + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::Layout; + use lucent_api::{AnchoredSpec, Element, Key, OverlayAlign, OverlaySide, Popover}; + use std::sync::Arc; + + #[derive(Clone, Debug, PartialEq)] + enum Message { + Observed(&'static str, PointerPress), + Action, + Dismiss, + } + fn observer(owner: &'static str) -> impl Fn(PointerPress) -> Message { + move |press| Message::Observed(owner, press) + } + fn scene(tree: Element, input: &Interaction) -> Scene { + Layout::new(Arc::new(vec![])).build(&tree, 200., 100., input, 0.) + } + fn press( + input: &mut Interaction, + scene: &Scene, + x: f32, + y: f32, + ) -> Vec { + input + .press_button_messages(scene, x, y, MouseButton::Primary, KeyModifiers::default()) + .into_iter() + .flatten() + .collect() + } + #[test] + fn nearest_press_observer_uses_pressed_hit_instead_of_previous_keyboard_focus() { + let mut input = Interaction::default(); + let tree = Element::stack(vec![ + Element::empty() + .size(80., 80.) + .on_click(Message::Action) + .id("media-control") + .on_pointer_press(observer("media")), + Element::empty() + .size(80., 80.) + .at(100., 0.) + .on_drag(|_| Message::Action) + .id("clock-drag") + .on_pointer_press(observer("clock")), + ]); + let current = scene(tree, &input); + press(&mut input, ¤t, 30., 30.); + assert_eq!(input.focus.as_deref(), Some("media-control")); + assert!(input.pressed_keyboard_focusable()); + let messages = press(&mut input, ¤t, 130., 30.); + assert_eq!( + messages.first(), + Some(&Message::Observed( + "clock", + PointerPress { + button: MouseButton::Primary, + keyboard_focusable: false + } + )) + ); + assert!(!input.pressed_keyboard_focusable()); + // A passive press deliberately retains component focus, but that is + // not evidence that Media was pressed or requested keyboard ownership. + assert_eq!(input.focus.as_deref(), Some("media-control")); + } + #[test] + fn nested_press_observer_runs_once_and_never_expands_input_regions() { + let mut input = Interaction::default(); + let tree = Element::stack(vec![ + Element::empty() + .size(40., 40.) + .on_click(Message::Action) + .on_pointer_press(observer("inner")), + ]) + .on_pointer_press(observer("outer")); + let current = scene(tree, &input); + assert_eq!(current.hits.len(), 1); + assert_eq!(press(&mut input, ¤t, 90., 70.), vec![]); + assert_eq!(press(&mut input, ¤t, 20., 20.).len(), 1); + assert!(matches!( + press(&mut input, ¤t, 20., 20.).as_slice(), + [Message::Observed( + "inner", + PointerPress { + keyboard_focusable: true, + .. + } + )] + )); + } + #[test] + fn covered_target_and_rounded_clips_share_ordinary_press_selection() { + let mut input = Interaction::default(); + let tree = Element::stack(vec![ + Element::empty() + .size(80., 80.) + .on_click(Message::Action) + .on_pointer_press(observer("under")), + Element::empty() + .size(80., 80.) + .on_drag(|_| Message::Action) + .radius(30.) + .on_pointer_press(observer("top")), + ]) + .size(80., 80.) + .radius(30.) + .clip(); + let current = scene(Element::stack(vec![tree]), &input); + assert_eq!(press(&mut input, ¤t, 1., 1.), vec![]); + assert!(matches!( + press(&mut input, ¤t, 40., 40.).first(), + Some(Message::Observed("top", _)) + )); + } + #[test] + fn press_observer_precedes_text_selection_action() { + let font = crate::text::Font::from_bytes( + include_bytes!("../../../apps/lucent-desktop/assets/LucentSans.ttf") as &[u8], + fontdue::FontSettings::default(), + ) + .unwrap(); + let mut input = Interaction::default(); + let field = Element::text_input("", Default::default(), "", |_| Message::Action) + .on_pointer_press(observer("field")); + let current = Layout::new(Arc::new(vec![font])).build(&field, 200., 100., &input, 0.); + assert!(matches!( + press(&mut input, ¤t, 30., 30.).as_slice(), + [Message::Observed("field", _), Message::Action] + )); + } + #[test] + fn keyboard_activation_does_not_invent_a_physical_press() { + let mut input = Interaction::default(); + let current = scene( + Element::empty() + .on_click(Message::Action) + .id("button") + .on_pointer_press(observer("button")), + &input, + ); + input.focus = Some("button".into()); + assert_eq!(input.key(¤t, &Key::Enter), vec![Message::Action]); + } + #[test] + fn mapped_press_observer_preserves_typed_owner_and_button() { + let mut input = Interaction::default(); + let tree = Element::empty() + .on_click(Message::Action) + .on_pointer_press(observer("mapped")) + .map(|message| (7, message)); + let current = Layout::new(Arc::new(vec![])).build(&tree, 200., 100., &input, 0.); + assert_eq!( + input.press_button_messages( + ¤t, + 30., + 30., + MouseButton::Middle, + KeyModifiers::default(), + ), + [ + Some(( + 7, + Message::Observed( + "mapped", + PointerPress { + button: MouseButton::Middle, + keyboard_focusable: true, + } + ) + )), + None + ] + ); + } + #[test] + fn popover_outside_dismissal_does_not_arm_underlying_observer() { + let mut input = Interaction::default(); + let tree = Element::stack(vec![ + Element::empty().size(40., 30.).id("anchor"), + Element::empty() + .size(40., 40.) + .at(140., 50.) + .on_click(Message::Action) + .on_pointer_press(observer("under")), + ]) + .popover(Popover { + id: "test".into(), + anchor: "anchor".into(), + content: Box::new(Element::empty().size(40., 30.).on_click(Message::Action)), + placement: AnchoredSpec { + side: OverlaySide::Below, + align: OverlayAlign::Start, + gap: 4., + inset: 4., + }, + dismiss: Message::Dismiss, + }); + let current = scene(tree, &input); + assert_eq!( + press(&mut input, ¤t, 160., 70.), + vec![Message::Dismiss] + ); + } +} diff --git a/lucent/crates/lucent-ui/src/rich_text.rs b/lucent/crates/lucent-ui/src/rich_text.rs index 44d9902a..c28ab268 100644 --- a/lucent/crates/lucent-ui/src/rich_text.rs +++ b/lucent/crates/lucent-ui/src/rich_text.rs @@ -516,6 +516,7 @@ pub(super) fn paint( secondary_click: None, middle_click: None, wheel: None, + pointer_press: None, submit: None, hover: None, input: None, diff --git a/lucent/crates/lucent-wayland/Cargo.toml b/lucent/crates/lucent-wayland/Cargo.toml index a83f33f4..6370232e 100644 --- a/lucent/crates/lucent-wayland/Cargo.toml +++ b/lucent/crates/lucent-wayland/Cargo.toml @@ -15,4 +15,5 @@ smithay-client-toolkit = "0.21.1" wayland-client = "0.31.15" wayland-protocols = { version = "0.32.13", features = ["client", "staging", "unstable"] } wayland-backend = { version = "0.3.17", features = ["client_system", "rwh_06"] } +wayland-scanner = "0.31.11" rustix = { version = "1", features = ["fs"] } diff --git a/lucent/crates/lucent-wayland/protocols/README.md b/lucent/crates/lucent-wayland/protocols/README.md new file mode 100644 index 00000000..af1d5331 --- /dev/null +++ b/lucent/crates/lucent-wayland/protocols/README.md @@ -0,0 +1 @@ +The focus-grab XML is vendored unchanged from `hyprwm/hyprland-protocols` at commit `cd1aba6bd78775825eb230b3a4274c48b6705eb7`, path `protocols/hyprland-focus-grab-v1.xml`. Its BSD 3-clause license is retained inside the XML. The optional native adapter generates client bindings at compile time; public SDK concepts remain independent of this protocol. diff --git a/lucent/crates/lucent-wayland/protocols/hyprland-focus-grab-v1.xml b/lucent/crates/lucent-wayland/protocols/hyprland-focus-grab-v1.xml new file mode 100644 index 00000000..3b3cd344 --- /dev/null +++ b/lucent/crates/lucent-wayland/protocols/hyprland-focus-grab-v1.xml @@ -0,0 +1,128 @@ + + + + Copyright © 2024 outfoxxed + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + This protocol allows clients to limit input focus to a specific set + of surfaces and receive a notification when the limiter is removed as + detailed below. + + + + + This interface allows a client to create surface grab objects. + + + + + Create a surface grab object. + + + + + + + + Destroy the focus grab manager. + This doesn't destroy existing focus grab objects. + + + + + + + This interface restricts input focus to a specified whitelist of + surfaces as long as the focus grab object exists and has at least + one comitted surface. + + Mouse and touch events inside a whitelisted surface will be passed + to the surface normally, while events outside of a whitelisted surface + will clear the grab object. Keyboard events will be passed to the client + and a compositor-picked surface in the whitelist will receive a + wl_keyboard::enter event if a whitelisted surface is not already entered. + + Upon meeting implementation-defined criteria usually meaning a mouse or + touch input outside of any whitelisted surfaces, the compositor will + clear the whitelist, rendering the grab inert and sending the cleared + event. The same will happen if another focus grab or similar action + is started at the compositor's discretion. + + + + + Add a surface to the whitelist. Destroying the surface is treated the + same as an explicit call to remove_surface and duplicate additions are + ignored. + + Does not take effect until commit is called. + + + + + + + + Remove a surface from the whitelist. Destroying the surface is treated + the same as an explicit call to this function. + + If the grab was active and the removed surface was entered by the + keyboard, another surface will be entered on commit. + + Does not take effect until commit is called. + + + + + + + + Commit pending changes to the surface whitelist. + + If the list previously had no entries and now has at least one, the grab + will start. If it previously had entries and now has none, the grab will + become inert. + + + + + + Destroy the grab object and remove the grab if active. + + + + + + Sent when an active grab is cancelled by the compositor, + regardless of cause. + + + + diff --git a/lucent/crates/lucent-wayland/src/focus_request.rs b/lucent/crates/lucent-wayland/src/focus_request.rs new file mode 100644 index 00000000..9fa0bc60 --- /dev/null +++ b/lucent/crates/lucent-wayland/src/focus_request.rs @@ -0,0 +1,1206 @@ +//! Optional one-shot native keyboard acquisition. Client intent is generic; +//! the compositor-specific grab exists only until a real Enter or termination. +use super::*; +use smithay_client_toolkit::registry::RegistryHandler; +use wayland_client::{ + Dispatch, + globals::GlobalList, + protocol::wl_callback::{self, WlCallback}, +}; + +mod wire { + #![allow(dead_code, non_camel_case_types, unused_unsafe, unused_variables)] + #![allow(non_upper_case_globals, non_snake_case, unused_imports)] + #![allow(missing_docs, clippy::all)] + use wayland_client; + use wayland_client::protocol::*; + pub mod __interfaces { + use wayland_client::protocol::__interfaces::*; + wayland_scanner::generate_interfaces!("protocols/hyprland-focus-grab-v1.xml"); + } + use self::__interfaces::*; + wayland_scanner::generate_client_code!("protocols/hyprland-focus-grab-v1.xml"); +} +use wire::{ + hyprland_focus_grab_manager_v1::HyprlandFocusGrabManagerV1, + hyprland_focus_grab_v1::{self, HyprlandFocusGrabV1}, +}; + +const TIMEOUT: Duration = Duration::from_secs(2); +const INTERFACE: &str = "hyprland_focus_grab_manager_v1"; + +pub(super) struct Origin { + pub address: api::SurfaceAddress, + pub surface: wl_surface::WlSurface, + pub native: api::NativeSurfaceToken, + pub seat: wl_seat::WlSeat, +} + +struct Pending { + id: u64, + request: api::KeyboardFocusRequest, + surface: wl_surface::WlSurface, + native: api::NativeSurfaceToken, + phase: Phase, + timer: RegistrationToken, + deadline: Instant, +} +impl Pending { + fn matches_sync(&self, proxy: &WlCallback, data: &SyncData) -> bool { + self.id == data.id + && self.native == data.native + && matches!(&self.phase, Phase::Retaining(sync) if &sync.0 == proxy) + } + fn matches_grab(&self, proxy: &HyprlandFocusGrabV1, data: &GrabData) -> bool { + self.id == data.id + && self.native == data.native + && matches!(&self.phase, Phase::Acquiring(grab) if grab == proxy) + } +} + +enum Phase { + Acquiring(HyprlandFocusGrabV1), + Retaining(OwnedSync), +} + +/// wl_callback has no destructor request. Explicit local teardown prevents a +/// cancelled queued Done from owning another acquisition or leaking a proxy. +struct OwnedSync(WlCallback); +impl Drop for OwnedSync { + fn drop(&mut self) { + if let Some(backend) = self.0.backend().upgrade() { + let _ = backend.destroy_object(&self.0.id()); + } + } +} + +fn begin_retention + 'static>( + connection: &Connection, + qh: &QueueHandle, + grab: HyprlandFocusGrabV1, + data: SyncData, +) -> OwnedSync { + grab.destroy(); + OwnedSync(connection.display().sync(qh, data)) +} + +fn deliver_focused( + request: api::KeyboardFocusRequest, + native: api::NativeSurfaceToken, + mut deliver: impl FnMut(M), +) { + if let Some(message) = request.finish(api::KeyboardFocusOutcome::Focused(native)) { + deliver(message); + } +} + +#[derive(Clone)] +pub(super) struct SyncData { + id: u64, + native: api::NativeSurfaceToken, +} + +#[derive(Clone)] +pub(super) struct GrabData { + id: u64, + native: api::NativeSurfaceToken, +} + +pub(super) enum Notice { + Completion(api::KeyboardFocusRequest, api::KeyboardFocusOutcome), + Lifecycle( + api::SurfaceSpec, + api::NativeSurfaceToken, + api::KeyboardFocusChange, + ), +} + +pub(super) struct Requests { + manager: Option, + global: Option, + pending: Option>, + next: u64, + pub origin: Option, + pub notices: Vec>, +} + +impl Requests { + pub fn bind( + globals: &GlobalList, + qh: &QueueHandle>, + enabled: bool, + ) -> Self { + let manager: Option = + enabled.then(|| globals.bind(qh, 1..=1, ()).ok()).flatten(); + let global = manager.as_ref().and_then(|_| { + globals.contents().with_list(|list| { + list.iter() + .find(|entry| entry.interface == INTERFACE) + .map(|entry| entry.name) + }) + }); + Self { + manager, + global, + pending: None, + next: 0, + origin: None, + notices: vec![], + } + } + + fn id(&mut self) -> Option { + let next = self.next.checked_add(1)?; + self.next = next; + Some(next) + } + pub fn inspect(&self) -> serde_json::Value { + serde_json::json!({ + "supported": self.manager.is_some(), + "pending": self.pending.as_ref().map(|pending| serde_json::json!({ + "request": pending.id, + "surface": pending.request.surface.to_string(), + "phase": match &pending.phase { + Phase::Acquiring(_) => "awaiting-enter", + Phase::Retaining(_) => "verifying-retention", + }, + })), + "scope": "One-shot request; success requires exact native focus retained through post-grab teardown sync. Later native Leave remains authoritative.", + }) + } +} + +impl Drop for Requests { + fn drop(&mut self) { + // State first withdraws eligibility while its natives still exist. + if let Some(pending) = self.pending.take() + && let Phase::Acquiring(grab) = pending.phase + { + grab.destroy(); + } + if let Some(manager) = self.manager.take() { + manager.destroy(); + } + } +} + +/// Registry dispatch has no application policy and never automatically rearms. +pub(super) struct Registry; +impl RegistryHandler> for Registry { + fn remove_global( + state: &mut State, + _: &Connection, + qh: &QueueHandle>, + name: u32, + _: &str, + ) { + if state.focus_requests.global != Some(name) { + return; + } + state.focus_requests.global = None; + state.focus_request_end(api::KeyboardFocusOutcome::Unavailable, false); + if let Some(manager) = state.focus_requests.manager.take() { + manager.destroy(); + } + state.focus_request_flush(qh); + } +} + +#[derive(Clone, Copy)] +struct Admission { + secure: bool, + supported: bool, + keyboard: bool, + current_origin: bool, + same_seat: bool, + on_demand: bool, + presented: bool, +} +fn admission(value: Admission) -> Option { + use api::KeyboardFocusOutcome as Outcome; + if value.secure || !value.supported || !value.keyboard { + Some(Outcome::Unavailable) + } else if !value.current_origin || !value.same_seat || !value.on_demand { + Some(Outcome::Rejected) + } else if !value.presented { + Some(Outcome::Retired) + } else { + None + } +} +fn already_owned( + actual_enter: bool, + requested: api::Keyboard, + committed: api::Keyboard, + pending_none: bool, +) -> bool { + actual_enter + && requested == api::Keyboard::OnDemand + && committed == api::Keyboard::OnDemand + && !pending_none +} + +impl State { + pub(super) fn focus_requests_pending_for(&self, address: &api::SurfaceAddress) -> bool { + self.focus_requests + .pending + .as_ref() + .is_some_and(|pending| &pending.request.surface == address) + } + pub(super) fn focus_request_acquiring_for(&self, address: &api::SurfaceAddress) -> bool { + self.focus_requests.pending.as_ref().is_some_and(|pending| { + &pending.request.surface == address && matches!(&pending.phase, Phase::Acquiring(_)) + }) + } + /// No attach, damage, frame callback, presentation request or history advance + /// belongs in this commit. Restore all staged state against the old image. + fn keyboard_control_commit( + &mut self, + address: &api::SurfaceAddress, + original: &wl_surface::WlSurface, + keyboard: api::Keyboard, + ) -> Result { + let Some(native) = self + .surfaces + .get_mut(address) + .filter(|native| native.role.wl_surface() == original) + else { + return Ok(false); + }; + if native.committed_spec.keyboard == keyboard { + return Ok(true); + } + let SurfaceRole::Layer(layer) = &native.role else { + return Ok(false); + }; + let Some(plan) = + keyboard_control::plan(&native.committed_spec, native.presented.as_ref(), keyboard) + else { + return Ok(false); + }; + // Allocate before queueing any restoration, so allocation failure does + // not itself leave a partially staged control transaction. + let region = Region::new(&self.compositor)?; + for clip in &plan.presented.regions { + add_region(®ion, clip); + } + if let Some(fractional) = &mut native.fractional { + fractional.destination(plan.presented.extent.0, plan.presented.extent.1)?; + } + configure_layer(layer, &plan.spec); + layer + .wl_surface() + .set_buffer_scale(plan.presented.buffer_scale); + layer + .wl_surface() + .set_input_region(Some(region.wl_region())); + layer.commit(); + if keyboard == api::Keyboard::None { + native.pending_keyboard_none = true; + } + plan.record_commit(&mut native.committed_spec, &mut native.regions); + Ok(true) + } + + pub(super) fn focus_request( + &mut self, + request: api::KeyboardFocusRequest, + qh: &QueueHandle, + ) { + use api::KeyboardFocusOutcome as Outcome; + if request.cancellation.cancelled() { + return; + } + let origin = self.focus_requests.origin.take(); + let native = self.surfaces.get(&request.surface); + let current_origin = origin.as_ref().is_some_and(|origin| { + origin.address == request.surface + && native.is_some_and(|native| { + native.role.wl_surface() == &origin.surface && native.identity == origin.native + }) + }); + let check = Admission { + secure: self.authorize_unlock.is_some() || self.session_lock.is_some(), + supported: self.focus_requests.manager.is_some(), + keyboard: self.keyboard.is_some(), + current_origin, + same_seat: origin + .as_ref() + .is_some_and(|origin| self.keyboard_seat.as_ref() == Some(&origin.seat)), + on_demand: native.is_some_and(|native| { + native.spec.keyboard == api::Keyboard::OnDemand + && matches!(&native.role, SurfaceRole::Layer(_)) + }), + presented: native.is_some_and(|native| native.configured && native.presented.is_some()), + }; + if let Some(outcome) = admission(check) { + self.focus_requests + .notices + .push(Notice::Completion(request, outcome)); + return; + } + let origin = origin.expect("admitted exact prepared press"); + // A newer real press supersedes the old acquisition before its own + // eligibility is committed. Neither scope survives as a pointer grab. + self.focus_request_end(Outcome::Superseded, false); + let Some(id) = self.focus_requests.id() else { + self.focus_requests + .notices + .push(Notice::Completion(request, Outcome::Unavailable)); + return; + }; + if let Some(native) = self.surfaces.get_mut(&request.surface) { + native.keyboard_claimed = true; + } + let already_entered = self.surfaces.get(&request.surface).is_some_and(|native| { + already_owned( + self.keyboard_surface.as_ref() == Some(&request.surface), + native.spec.keyboard, + native.committed_spec.keyboard, + native.pending_keyboard_none, + ) + }); + match self.keyboard_control_commit( + &request.surface, + &origin.surface, + api::Keyboard::OnDemand, + ) { + Ok(true) => {} + Ok(false) => { + self.focus_requests + .notices + .push(Notice::Completion(request, Outcome::Retired)); + return; + } + Err(error) => { + self.error = Some(error.to_string()); + self.exit = true; + self.focus_requests + .notices + .push(Notice::Completion(request, Outcome::Unavailable)); + return; + } + } + if already_entered { + // A stable already-owned native needs no grab or new synthetic + // Enter. A None->OnDemand promotion cannot take this shortcut. + deliver_focused(request, origin.native, |message| self.message(message, qh)); + return; + } + let data = GrabData { + id, + native: origin.native.clone(), + }; + let grab = self + .focus_requests + .manager + .as_ref() + .expect("admitted global") + .create_grab(qh, data); + let timeout_qh = qh.clone(); + let timer = + match self + .handle + .insert_source(Timer::from_duration(TIMEOUT), move |_, _, state| { + if state + .focus_requests + .pending + .as_ref() + .is_some_and(|pending| pending.id == id) + { + state.focus_request_end(Outcome::Timeout, true); + state.focus_request_flush(&timeout_qh); + } + TimeoutAction::Drop + }) { + Ok(timer) => timer, + Err(_) => { + if let Err(error) = self.keyboard_control_commit( + &request.surface, + &origin.surface, + api::Keyboard::None, + ) { + self.error = Some(error.to_string()); + self.exit = true; + } + grab.destroy(); + self.focus_requests + .notices + .push(Notice::Completion(request, Outcome::Unavailable)); + return; + } + }; + grab.add_surface(&origin.surface); + self.focus_requests.pending = Some(Pending { + id, + request, + surface: origin.surface, + native: origin.native, + phase: Phase::Acquiring(grab.clone()), + timer, + deadline: Instant::now() + TIMEOUT, + }); + // The keyboard-only role commit above precedes this request on the same + // Wayland connection; acquiring never depends on an own frame callback. + grab.commit(); + } + + pub(super) fn focus_request_end( + &mut self, + outcome: api::KeyboardFocusOutcome, + timer_fired: bool, + ) { + let Some(pending) = self.focus_requests.pending.take() else { + return; + }; + if !timer_fired { + self.handle.remove(pending.timer); + } + // Failure/cancellation withdraws eligibility BEFORE destroying the + // grab, so ordinary compositor refocus cannot select this old demand. + if let Err(error) = self.keyboard_control_commit( + &pending.request.surface, + &pending.surface, + api::Keyboard::None, + ) { + self.error = Some(error.to_string()); + self.exit = true; + } + if let Phase::Acquiring(grab) = pending.phase { + grab.destroy(); + } + self.focus_requests + .notices + .push(Notice::Completion(pending.request, outcome)); + } + + pub(super) fn focus_request_revalidate(&mut self) { + use api::KeyboardFocusOutcome as Outcome; + // A completed one-shot has no retained protocol object. Its client can + // still withdraw the acknowledged ordinary OnDemand intent without + // waiting for another GPU frame or exposing staged image geometry. + let withdrawn: Vec<_> = self + .surfaces + .iter() + .filter(|(_, native)| { + native.keyboard_claimed && native.spec.keyboard == api::Keyboard::None + }) + .map(|(address, native)| (address.clone(), native.role.wl_surface().clone())) + .collect(); + for (address, surface) in withdrawn { + match self.keyboard_control_commit(&address, &surface, api::Keyboard::None) { + Ok(true) => { + if let Some(native) = self.surfaces.get_mut(&address) { + native.keyboard_claimed = false; + } + } + Ok(false) => {} + Err(error) => { + self.error = Some(error.to_string()); + self.exit = true; + } + } + } + let outcome = self.focus_requests.pending.as_ref().and_then(|pending| { + if pending.request.cancellation.cancelled() { + return Some(Outcome::Superseded); + } + if self.keyboard.is_none() { + return Some(Outcome::Unavailable); + } + if Instant::now() >= pending.deadline { + return Some(Outcome::Timeout); + } + let Some(native) = self + .surfaces + .get(&pending.request.surface) + .filter(|native| { + native.role.wl_surface() == &pending.surface + && native.identity == pending.native + }) + else { + return Some(Outcome::Retired); + }; + (native.spec.keyboard != api::Keyboard::OnDemand).then_some(Outcome::Superseded) + }); + if let Some(outcome) = outcome { + self.focus_request_end(outcome, false); + } + } + + pub(super) fn focus_request_enter( + &mut self, + surface: &wl_surface::WlSurface, + qh: &QueueHandle, + ) { + self.focus_request_revalidate(); + let valid = self.focus_requests.pending.as_ref().is_some_and(|pending| { + &pending.surface == surface + && self + .surfaces + .get(&pending.request.surface) + .is_some_and(|native| { + native.role.wl_surface() == surface + && native.identity == pending.native + && native.committed_spec.keyboard == api::Keyboard::OnDemand + }) + && self.keyboard_surface.as_ref() == Some(&pending.request.surface) + && matches!(&pending.phase, Phase::Acquiring(_)) + }); + if !valid { + return; + } + let pending = self.focus_requests.pending.take().expect("validated Enter"); + let Phase::Acquiring(grab) = pending.phase else { + unreachable!() + }; + // Successful acquisition is ONE SHOT. Keep ordinary OnDemand policy; + // remove the pointer grab immediately, without fabricating a Leave. + // A separate bounded sync verifies that this teardown did not itself + // refocus another native before reporting successful retention. + let callback = begin_retention( + &self.connection, + qh, + grab, + SyncData { + id: pending.id, + native: pending.native.clone(), + }, + ); + self.focus_requests.pending = Some(Pending { + phase: Phase::Retaining(callback), + ..pending + }); + } + + pub(super) fn focus_request_lifecycle( + &mut self, + spec: api::SurfaceSpec, + native: api::NativeSurfaceToken, + change: api::KeyboardFocusChange, + ) { + self.focus_requests + .notices + .push(Notice::Lifecycle(spec, native, change)); + } + + pub(super) fn focus_request_flush(&mut self, qh: &QueueHandle) { + for notice in std::mem::take(&mut self.focus_requests.notices) { + let message = match notice { + Notice::Completion(request, outcome) => request.finish(outcome), + Notice::Lifecycle(spec, native, change) => { + self.app.event(spec.scope_event(api::Event::KeyboardFocus { + surface: spec.id, + native, + change, + })) + } + }; + if let Some(message) = message { + self.message(message, qh); + } + } + } +} + +impl Dispatch for State { + fn event( + state: &mut Self, + proxy: &HyprlandFocusGrabV1, + event: hyprland_focus_grab_v1::Event, + data: &GrabData, + _: &Connection, + qh: &QueueHandle, + ) { + if matches!(event, hyprland_focus_grab_v1::Event::Cleared) + && state + .focus_requests + .pending + .as_ref() + .is_some_and(|pending| pending.matches_grab(proxy, data)) + { + state.focus_request_end(api::KeyboardFocusOutcome::Cleared, false); + state.focus_request_flush(qh); + } + } +} +wayland_client::delegate_noop!(@ State:HyprlandFocusGrabManagerV1); + +impl Dispatch for State { + fn event( + state: &mut Self, + proxy: &WlCallback, + event: wl_callback::Event, + data: &SyncData, + _: &Connection, + qh: &QueueHandle, + ) { + if !matches!(event, wl_callback::Event::Done { .. }) { + return; + } + // Done commonly makes the proxy dead before this dispatch. Exact owned + // identity, not is_alive(), decides whether queued valid Done belongs. + let valid = state + .focus_requests + .pending + .as_ref() + .is_some_and(|pending| pending.matches_sync(proxy, data)); + if !valid { + return; + } + state.focus_request_revalidate(); + let Some(pending) = state.focus_requests.pending.take() else { + state.focus_request_flush(qh); + return; + }; + state.handle.remove(pending.timer); + let retained = state.keyboard_surface.as_ref() == Some(&pending.request.surface) + && state + .surfaces + .get(&pending.request.surface) + .is_some_and(|native| { + native.role.wl_surface() == &pending.surface + && native.identity == pending.native + && native.spec.keyboard == api::Keyboard::OnDemand + && native.committed_spec.keyboard == api::Keyboard::OnDemand + }); + drop(pending.phase); + if retained { + if let Some(native) = state.surfaces.get_mut(&pending.request.surface) { + native.pending_keyboard_none = false; + } + // Complete synchronously before any later native loss delivery. + deliver_focused(pending.request, pending.native, |message| { + state.message(message, qh) + }); + } else { + if let Err(error) = state.keyboard_control_commit( + &pending.request.surface, + &pending.surface, + api::Keyboard::None, + ) { + state.error = Some(error.to_string()); + state.exit = true; + } + state.focus_requests.notices.push(Notice::Completion( + pending.request, + api::KeyboardFocusOutcome::NotRetained, + )); + } + state.focus_request_flush(qh); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::{ + io::{Read, Write}, + os::unix::net::UnixStream, + }; + use wayland_client::{ + EventQueue, + protocol::{wl_compositor::WlCompositor, wl_registry::WlRegistry}, + }; + fn valid() -> Admission { + Admission { + secure: false, + supported: true, + keyboard: true, + current_origin: true, + same_seat: true, + on_demand: true, + presented: true, + } + } + #[test] + fn only_current_prepared_press_with_keyboard_capability_can_admit() { + assert_eq!(admission(valid()), None); + assert_eq!( + admission(Admission { + current_origin: false, + ..valid() + }), + Some(api::KeyboardFocusOutcome::Rejected) + ); + assert_eq!( + admission(Admission { + same_seat: false, + ..valid() + }), + Some(api::KeyboardFocusOutcome::Rejected) + ); + assert_eq!( + admission(Admission { + on_demand: false, + ..valid() + }), + Some(api::KeyboardFocusOutcome::Rejected) + ); + } + #[test] + fn secure_unsupported_missing_keyboard_and_unpresented_targets_do_not_acquire() { + for check in [ + Admission { + secure: true, + ..valid() + }, + Admission { + supported: false, + ..valid() + }, + Admission { + keyboard: false, + ..valid() + }, + ] { + assert_eq!( + admission(check), + Some(api::KeyboardFocusOutcome::Unavailable) + ); + } + assert_eq!( + admission(Admission { + presented: false, + ..valid() + }), + Some(api::KeyboardFocusOutcome::Retired) + ); + } + #[test] + fn request_identifiers_never_wrap_or_reuse() { + let mut requests: Requests<()> = Requests { + manager: None, + global: None, + pending: None, + next: u64::MAX - 1, + origin: None, + notices: vec![], + }; + assert_eq!(requests.id(), Some(u64::MAX)); + assert_eq!(requests.id(), None); + assert_eq!(requests.id(), None); + } + #[test] + fn already_owned_noop_excludes_control_promotion_and_pending_none() { + use api::Keyboard::{None, OnDemand}; + assert!(already_owned(true, OnDemand, OnDemand, false)); + assert!(!already_owned(false, OnDemand, OnDemand, false)); + assert!(!already_owned(true, OnDemand, None, false)); + assert!(!already_owned(true, None, OnDemand, false)); + assert!(!already_owned(true, OnDemand, OnDemand, true)); + } + + // This wire peer exercises real queue ordering and the same receipt matcher + // and synchronous completion function as the native driver, without a GPU. + struct Peer { + pending: Option>, + current: Option, + native: api::NativeSurfaceToken, + client_pending: bool, + client_owner: Option, + trace: Vec<&'static str>, + } + impl Peer { + fn accept(&mut self, outcome: api::KeyboardFocusOutcome) { + self.client_pending = false; + match outcome { + api::KeyboardFocusOutcome::Focused(native) => { + self.client_owner = Some(native); + self.trace.push("focused"); + } + api::KeyboardFocusOutcome::NotRetained => { + self.client_owner = None; + self.trace.push("not-retained"); + } + _ => self.trace.push("other-outcome"), + } + } + } + wayland_client::delegate_noop!(Peer: ignore WlRegistry); + wayland_client::delegate_noop!(Peer: ignore WlCompositor); + wayland_client::delegate_noop!(Peer: ignore wl_surface::WlSurface); + wayland_client::delegate_noop!(Peer: ignore wl_seat::WlSeat); + wayland_client::delegate_noop!(Peer: ignore HyprlandFocusGrabManagerV1); + impl Dispatch for Peer { + fn event( + _: &mut Self, + _: &HyprlandFocusGrabV1, + _: hyprland_focus_grab_v1::Event, + _: &GrabData, + _: &Connection, + _: &QueueHandle, + ) { + } + } + impl Dispatch for Peer { + fn event( + state: &mut Self, + _: &wl_keyboard::WlKeyboard, + event: wl_keyboard::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + match event { + wl_keyboard::Event::Enter { surface, .. } => { + state.current = Some(surface); + state.trace.push("enter"); + } + wl_keyboard::Event::Leave { surface, .. } => { + if state.current.as_ref() == Some(&surface) { + state.current = None; + } + state.trace.push("leave"); + // Like the client, pending intent cannot infer ownership + // from a Leave that predates its acquisition receipt. + if !state.client_pending && state.client_owner.as_ref() == Some(&state.native) { + state.client_owner = None; + state.trace.push("loss"); + } + } + _ => {} + } + } + } + impl Dispatch for Peer { + fn event( + state: &mut Self, + proxy: &WlCallback, + event: wl_callback::Event, + data: &SyncData, + _: &Connection, + _: &QueueHandle, + ) { + if !matches!(event, wl_callback::Event::Done { .. }) + || !state + .pending + .as_ref() + .is_some_and(|pending| pending.matches_sync(proxy, data)) + { + return; + } + let pending = state.pending.take().unwrap(); + let retained = + state.current.as_ref() == Some(&pending.surface) && state.native == pending.native; + drop(pending.phase); + if retained { + deliver_focused(pending.request, pending.native, |message| { + state.accept(message) + }); + } else if let Some(message) = pending + .request + .finish(api::KeyboardFocusOutcome::NotRetained) + { + state.accept(message); + } + state.trace.push("sync"); + } + } + fn wire_socket() -> ( + Connection, + EventQueue, + UnixStream, + WlCompositor, + wl_keyboard::WlKeyboard, + ) { + let (client, server) = UnixStream::pair().unwrap(); + server + .set_read_timeout(Some(Duration::from_secs(1))) + .unwrap(); + let connection = Connection::from_socket(client).unwrap(); + let queue = connection.new_event_queue::(); + let qh = queue.handle(); + let registry = connection.display().get_registry(&qh, ()); + let compositor = registry.bind::(1, 1, &qh, ()); + let seat = registry.bind::(2, 5, &qh, ()); + let keyboard = seat.get_keyboard(&qh, ()); + (connection, queue, server, compositor, keyboard) + } + fn event(bytes: &mut Vec, object: u32, opcode: u16, payload: &[u32]) { + bytes.extend_from_slice(&object.to_ne_bytes()); + bytes.extend_from_slice( + &((((payload.len() * 4 + 8) as u32) << 16) | u32::from(opcode)).to_ne_bytes(), + ); + for word in payload { + bytes.extend_from_slice(&word.to_ne_bytes()); + } + } + struct Fixture { + connection: Connection, + queue: EventQueue, + server: UnixStream, + compositor: WlCompositor, + keyboard: wl_keyboard::WlKeyboard, + surface: wl_surface::WlSurface, + callback: WlCallback, + data: SyncData, + peer: Peer, + _event_loop: EventLoop<'static, Peer>, + } + fn fixture(cancel: api::Cancellation) -> Fixture { + let (connection, queue, server, compositor, keyboard) = wire_socket(); + let surface = compositor.create_surface(&queue.handle(), ()); + let native = api::NativeSurfaceToken::new(); + let data = SyncData { + id: 1, + native: native.clone(), + }; + let callback = connection.display().sync(&queue.handle(), data.clone()); + let event_loop = EventLoop::::try_new().unwrap(); + let timer = event_loop + .handle() + .insert_source(Timer::from_duration(TIMEOUT), |_, _, _| TimeoutAction::Drop) + .unwrap(); + let peer = Peer { + pending: Some(Pending { + id: 1, + request: api::KeyboardFocusRequest::new( + api::SurfaceAddress::new("notes"), + cancel, + std::convert::identity, + ), + surface: surface.clone(), + native: native.clone(), + phase: Phase::Retaining(OwnedSync(callback.clone())), + timer, + deadline: Instant::now() + TIMEOUT, + }), + current: None, + native, + client_pending: true, + client_owner: None, + trace: vec![], + }; + Fixture { + connection, + queue, + server, + compositor, + keyboard, + surface, + callback, + data, + peer, + _event_loop: event_loop, + } + } + fn dispatch(fixture: &mut Fixture, bytes: &[u8]) { + fixture.connection.flush().unwrap(); + fixture.server.write_all(bytes).unwrap(); + fixture.connection.prepare_read().unwrap().read().unwrap(); + fixture.queue.dispatch_pending(&mut fixture.peer).unwrap(); + } + #[test] + fn queued_sync_done_completes_before_a_following_real_leave_in_one_dispatch_batch() { + let mut f = fixture(api::Cancellation::default()); + let mut bytes = vec![]; + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 2, + &[1, f.surface.id().protocol_id()], + ); + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 1, + &[2, f.surface.id().protocol_id(), 0], + ); + event(&mut bytes, f.callback.id().protocol_id(), 0, &[3]); + event(&mut bytes, 1, 1, &[f.callback.id().protocol_id()]); + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 2, + &[4, f.surface.id().protocol_id()], + ); + dispatch(&mut f, &bytes); + assert_eq!( + f.peer.trace, + ["leave", "enter", "focused", "sync", "leave", "loss"] + ); + assert!(!f.peer.client_pending); + assert!(f.peer.client_owner.is_none()); + assert!(f.peer.pending.is_none()); + } + #[test] + fn a_leave_before_sync_is_not_retained_and_cannot_arm_late() { + let mut f = fixture(api::Cancellation::default()); + let mut bytes = vec![]; + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 1, + &[1, f.surface.id().protocol_id(), 0], + ); + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 2, + &[2, f.surface.id().protocol_id()], + ); + event(&mut bytes, f.callback.id().protocol_id(), 0, &[3]); + event(&mut bytes, 1, 1, &[f.callback.id().protocol_id()]); + dispatch(&mut f, &bytes); + assert_eq!(f.peer.trace, ["enter", "leave", "not-retained", "sync"]); + assert!(f.peer.client_owner.is_none()); + } + #[test] + fn another_native_enter_before_sync_cannot_retain_the_previous_routing_address() { + let mut f = fixture(api::Cancellation::default()); + let retired_or_other = f.compositor.create_surface(&f.queue.handle(), ()); + let mut bytes = vec![]; + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 1, + &[1, f.surface.id().protocol_id(), 0], + ); + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 1, + &[2, retired_or_other.id().protocol_id(), 0], + ); + event(&mut bytes, f.callback.id().protocol_id(), 0, &[3]); + event(&mut bytes, 1, 1, &[f.callback.id().protocol_id()]); + dispatch(&mut f, &bytes); + assert_eq!(f.peer.trace, ["enter", "enter", "not-retained", "sync"]); + assert!(f.peer.client_owner.is_none()); + } + #[test] + fn queued_valid_done_survives_proxy_death_but_reused_ids_and_native_replacements_do_not_match() + { + let mut f = fixture(api::Cancellation::default()); + f.connection.flush().unwrap(); + let mut bytes = vec![]; + event(&mut bytes, f.callback.id().protocol_id(), 0, &[1]); + event(&mut bytes, 1, 1, &[f.callback.id().protocol_id()]); + f.server.write_all(&bytes).unwrap(); + f.connection.prepare_read().unwrap().read().unwrap(); + assert!(!f.callback.is_alive()); + assert!( + f.peer + .pending + .as_ref() + .unwrap() + .matches_sync(&f.callback, &f.data) + ); + let replacement = f + .connection + .display() + .sync(&f.queue.handle(), f.data.clone()); + assert_eq!( + replacement.id().protocol_id(), + f.callback.id().protocol_id() + ); + assert_ne!(replacement, f.callback); + let pending = f.peer.pending.as_ref().unwrap(); + assert!(!pending.matches_sync(&replacement, &f.data)); + assert!(!pending.matches_sync( + &f.callback, + &SyncData { + native: api::NativeSurfaceToken::new(), + ..f.data.clone() + } + )); + assert!(!pending.matches_sync( + &f.callback, + &SyncData { + id: 2, + ..f.data.clone() + } + )); + // Retiring the old owner cannot destroy an object which reused its + // protocol number, and its already-queued Done cannot finish another + // request after that owner was removed. + drop(f.peer.pending.take()); + assert!(replacement.is_alive()); + f.queue.dispatch_pending(&mut f.peer).unwrap(); + assert!(f.peer.trace.is_empty()); + assert!(replacement.is_alive()); + // Explicit local teardown retires only the replacement callback. + drop(OwnedSync(replacement)); + } + #[test] + fn cancellation_before_sync_dispatch_suppresses_completion() { + let cancellation = api::Cancellation::default(); + let mut f = fixture(cancellation.clone()); + let mut bytes = vec![]; + event( + &mut bytes, + f.keyboard.id().protocol_id(), + 1, + &[1, f.surface.id().protocol_id(), 0], + ); + event(&mut bytes, f.callback.id().protocol_id(), 0, &[2]); + event(&mut bytes, 1, 1, &[f.callback.id().protocol_id()]); + cancellation.cancel(); + dispatch(&mut f, &bytes); + assert_eq!(f.peer.trace, ["enter", "sync"]); + assert!(f.peer.client_owner.is_none()); + } + #[test] + fn internal_grab_destroy_precedes_sync_and_adds_no_surface_or_frame_request() { + let (connection, queue, mut server, compositor, _) = wire_socket(); + let qh = queue.handle(); + let registry = connection.display().get_registry(&qh, ()); + let manager = registry.bind::(3, 1, &qh, ()); + let native = api::NativeSurfaceToken::new(); + let surface = compositor.create_surface(&qh, ()); + let grab = manager.create_grab( + &qh, + GrabData { + id: 1, + native: native.clone(), + }, + ); + grab.add_surface(&surface); + grab.commit(); + let grab_id = grab.id().protocol_id(); + let _sync = begin_retention(&connection, &qh, grab, SyncData { id: 1, native }); + connection.flush().unwrap(); + let mut observed = vec![]; + loop { + let mut header = [0u8; 8]; + server.read_exact(&mut header).unwrap(); + let object = u32::from_ne_bytes(header[..4].try_into().unwrap()); + let word = u32::from_ne_bytes(header[4..].try_into().unwrap()); + let opcode = word as u16; + let mut payload = vec![0; (word >> 16) as usize - 8]; + server.read_exact(&mut payload).unwrap(); + assert_ne!( + object, + surface.id().protocol_id(), + "No surface attach/damage/frame/commit belongs to grab teardown" + ); + if object == grab_id { + observed.push(("grab", opcode)); + } + if object == 1 && opcode == 0 { + observed.push(("display", opcode)); + break; + } + } + assert_eq!( + observed, + [("grab", 0), ("grab", 2), ("grab", 3), ("display", 0)] + ); + } + #[test] + fn owned_sync_teardown_retires_proxy_and_accepts_later_delete_id() { + let mut f = fixture(api::Cancellation::default()); + let callback_id = f.callback.id().protocol_id(); + drop(f.peer.pending.take()); + assert!(!f.callback.is_alive()); + let mut bytes = vec![]; + event(&mut bytes, callback_id, 0, &[1]); + event(&mut bytes, 1, 1, &[callback_id]); + dispatch(&mut f, &bytes); + assert!(f.connection.backend().last_error().is_none()); + assert!(f.peer.trace.is_empty()); + let replacement = f.compositor.create_surface(&f.queue.handle(), ()); + assert_eq!(replacement.id().protocol_id(), callback_id); + } +} diff --git a/lucent/crates/lucent-wayland/src/keyboard_control.rs b/lucent/crates/lucent-wayland/src/keyboard_control.rs new file mode 100644 index 00000000..01044778 --- /dev/null +++ b/lucent/crates/lucent-wayland/src/keyboard_control.rs @@ -0,0 +1,144 @@ +//! Keyboard-only commits preserve the last successfully presented image. +//! +//! A retry may already have staged another viewport, role or input region. +//! Neither that pending cache nor the latest input scene is a presentation. +use lucent_api::{Clip, Keyboard, SurfaceSpec}; + +#[derive(Clone)] +pub(super) struct Presented { + pub extent: (u32, u32), + pub buffer_scale: i32, + pub regions: Vec, +} + +pub(super) struct Plan { + pub spec: SurfaceSpec, + pub presented: Presented, +} +impl Plan { + /// Reset the staging cache so the next image must resend its different + /// input region. This records no new buffer or presentation history. + pub fn record_commit(self, committed: &mut SurfaceSpec, regions: &mut Vec) { + *committed = self.spec; + *regions = self.presented.regions; + } +} + +/// The requested next image deliberately does not participate in this plan. +pub(super) fn plan( + committed: &SurfaceSpec, + presented: Option<&Presented>, + keyboard: Keyboard, +) -> Option { + let mut spec = committed.clone(); + spec.keyboard = keyboard; + Some(Plan { + spec, + presented: presented?.clone(), + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use lucent_api::{Anchor, Layer, PointerInput, Rect}; + + fn spec() -> SurfaceSpec { + SurfaceSpec { + id: "editor", + instance: None, + output: None, + layer: Layer::Bottom, + anchor: Anchor::TopLeft, + margins: Default::default(), + redraw_group: None, + width: 304, + height: 240, + exclusive_zone: -1, + keyboard: Keyboard::None, + visible: true, + pointer_input: PointerInput::Content, + } + } + + #[test] + fn control_plan_keeps_presented_geometry_and_regions_after_another_image_retry() { + let mut committed = spec(); + let shown = Presented { + extent: (304, 240), + buffer_scale: 1, + regions: vec![Rect::new(8., 16., 200., 120.).into()], + }; + let mut requested = committed.clone(); + requested.width = 520; + requested.height = 480; + requested.margins.top = 92; + requested.keyboard = Keyboard::OnDemand; + let pending_regions = vec![Clip::from(Rect::new(0., 0., 520., 480.))]; + let plan = plan(&committed, Some(&shown), Keyboard::OnDemand).unwrap(); + let mut expected = committed.clone(); + expected.keyboard = Keyboard::OnDemand; + assert_eq!(plan.spec, expected); + assert_eq!(plan.presented.extent, (304, 240)); + assert_eq!(plan.presented.buffer_scale, 1); + assert_eq!(plan.presented.regions, shown.regions); + assert_ne!(plan.presented.regions, pending_regions); + let mut staged_cache = pending_regions.clone(); + plan.record_commit(&mut committed, &mut staged_cache); + assert_eq!(committed, expected); + assert_eq!(staged_cache, shown.regions); + // The next draw must resend B after restoring A's cache. + assert_ne!(staged_cache, pending_regions); + assert_eq!(requested.width, 520); + assert_eq!(requested.margins.top, 92); + } + + #[test] + fn automatic_role_axes_and_fractional_viewport_are_preserved_independently() { + let mut committed = spec(); + committed.width = 0; + committed.height = 0; + let shown = Presented { + extent: (1536, 864), + buffer_scale: 1, + regions: vec![], + }; + let plan = plan(&committed, Some(&shown), Keyboard::OnDemand).unwrap(); + assert_eq!((plan.spec.width, plan.spec.height), (0, 0)); + assert_eq!(plan.presented.extent, (1536, 864)); + assert!(plan.presented.regions.is_empty()); + } + + #[test] + fn no_successful_image_cannot_authorize_a_control_commit() { + assert!(plan(&spec(), None, Keyboard::OnDemand).is_none()); + } + + #[test] + fn withdrawing_keyboard_retains_integer_scale_and_full_input_region() { + let mut committed = spec(); + committed.keyboard = Keyboard::OnDemand; + let shown = Presented { + extent: (304, 240), + buffer_scale: 2, + regions: vec![Rect::new(0., 0., 304., 240.).into()], + }; + let plan = plan(&committed, Some(&shown), Keyboard::None).unwrap(); + assert_eq!(plan.spec.keyboard, Keyboard::None); + assert_eq!(plan.spec.pointer_input, PointerInput::Content); + assert_eq!(plan.presented.buffer_scale, 2); + assert_eq!(plan.presented.regions, shown.regions); + } + #[test] + fn native_interaction_starts_inactive_without_discarding_component_focus() { + let mut input = super::super::native_interaction::<()>(); + input.focus = Some("notes-input".into()); + input.focus_visible = true; + assert!(!input.keyboard_active()); + assert!(input.set_keyboard_active(true)); + assert!(input.keyboard_active()); + assert!(input.set_keyboard_active(false)); + assert_eq!(input.focus.as_deref(), Some("notes-input")); + assert!(input.focus_visible); + } +} diff --git a/lucent/crates/lucent-wayland/src/lib.rs b/lucent/crates/lucent-wayland/src/lib.rs index 5b09d4fe..b9082c06 100644 --- a/lucent/crates/lucent-wayland/src/lib.rs +++ b/lucent/crates/lucent-wayland/src/lib.rs @@ -51,12 +51,14 @@ mod batching; mod clipboard; mod delivery; mod effects; +mod focus_request; mod fractional; mod handoff; mod input_method; mod input_release; mod ipc; mod keyboard; +mod keyboard_control; mod keyboard_focus; mod layer_commit; mod outputs; @@ -74,11 +76,14 @@ enum RuntimeEvent { } struct Native { input_release_callbacks: Option, + identity: api::NativeSurfaceToken, renderer: Renderer, // Drop before layer. fractional: Option, // Destroy extensions before role/surface. role: SurfaceRole, spec: api::SurfaceSpec, committed_spec: api::SurfaceSpec, + pending_keyboard_none: bool, + keyboard_claimed: bool, bound_output: Option, width: u32, height: u32, @@ -100,10 +105,11 @@ impl Drop for Native { drop(self.input_release_callbacks.take()); } } -#[derive(Clone, Copy)] -struct PresentationState { - extent: (u32, u32), - buffer_scale: i32, +type PresentationState = keyboard_control::Presented; +fn native_interaction() -> Interaction { + let mut interaction = Interaction::default(); + interaction.set_keyboard_active(false); + interaction } impl Native { fn density(&self) -> api::Density { @@ -114,6 +120,14 @@ impl Native { api::Density::integer(self.scale).expect("positive native integer scale") }) } + fn set_keyboard_active(&mut self, active: bool) + where + M: Clone, + { + if self.interaction.set_keyboard_active(active) { + self.demand.invalidate(); + } + } } enum SurfaceRole { Layer(LayerSurface), @@ -155,6 +169,7 @@ struct State { input_method: input_method::InputMethod, activation: activation::Activation, input_release: input_release::Releases, + focus_requests: focus_request::Requests, modifiers: Modifiers, epoch: Instant, profile_frames: bool, @@ -178,6 +193,7 @@ impl Drop for State { self.clipboard_drop(); self.input_method.shutdown(); self.presentation.clear_pending(); + self.focus_request_end(api::KeyboardFocusOutcome::Retired, false); // Drop GPU surfaces before their protocol roles, then send the queued // destroy requests while the connection is still alive. A caller such // as a permission agent can outlive this individual runtime invocation. @@ -276,6 +292,11 @@ fn run_inner( &qh, app.activation_enabled() && authorize_unlock.is_none(), ); + let focus_requests = focus_request::Requests::bind::( + &globals, + &qh, + ipc && authorize_unlock.is_none() && app.keyboard_focus_requests_enabled(), + ); let profile_frames = std::env::var_os("LUCENT_PROFILE_FRAMES").is_some_and(|value| value == "1"); let mut state = State { @@ -306,6 +327,7 @@ fn run_inner( input_method: input_method::InputMethod::bind(&globals, &qh, !input_method_allowed), activation, input_release: Default::default(), + focus_requests, modifiers: Modifiers::default(), epoch: Instant::now(), presentation: presentation::Capture::bind(&globals, &qh, ipc && authorize_unlock.is_none()), @@ -435,6 +457,7 @@ impl State { ))?), Native { input_release_callbacks: None, + identity: api::NativeSurfaceToken::new(), renderer, fractional: self .fractional @@ -442,6 +465,8 @@ impl State { .map(|globals| globals.surface(lock_surface.wl_surface(), qh)), role: SurfaceRole::Lock(lock_surface, output), committed_spec: spec.clone(), + pending_keyboard_none: false, + keyboard_claimed: false, spec, bound_output: None, width: 1, @@ -451,7 +476,7 @@ impl State { presented: None, demand: FrameDemand::default(), scene: Scene::default(), - interaction: Interaction::default(), + interaction: native_interaction(), regions: vec![], history: Default::default(), pacing: self.pacing.start_native(), @@ -516,6 +541,7 @@ impl State { let surfaces = self.surfaces.iter().map(|(id,s)|serde_json::json!({"id":id.to_string(),"role":s.spec.id,"instance":s.spec.instance.as_ref().map(api::SurfaceInstance::as_str),"redraw_group":s.spec.redraw_group,"output":s.spec.output.as_ref().map(api::OutputName::as_str),"keyboard":keyboard_focus::policy_name(s.spec.keyboard),"requested_keyboard":keyboard_focus::policy_name(s.spec.keyboard),"committed_keyboard":keyboard_focus::policy_name(s.committed_spec.keyboard),"actual_native_keyboard_focused":keyboard_focus.current_address==Some(id),"pointer_input":s.spec.pointer_input.name(),"width":s.width,"height":s.height,"scale":s.scale,"density":s.density().factor(),"buffer_scale":if s.fractional.is_some(){1}else{s.scale},"buffer_width":s.density().physical_size(s.width,s.height).ok().map(|size|size.0),"buffer_height":s.density().physical_size(s.width,s.height).ok().map(|size|size.1),"frames":s.history.frames,"native_frames":s.renderer.frames,"native_generation":s.native_generation,"paint_primitives":s.scene.paint.len(),"focus":s.interaction.focus,"focus_visible":s.interaction.focus_visible,"frame_times_ms":s.history.frame_times,"frame_profiles":s.history.profiles.json(),"frame_pacing":s.pacing.as_ref().map(pacing::Trace::json),"presentation":s.history.presentation.json(),"hits":s.scene.hits.iter().map(|h|serde_json::json!({"id":h.id,"x":h.rect.x,"y":h.rect.y,"width":h.rect.w,"height":h.rect.h,"clip":{"x":h.clip.bounds.x,"y":h.clip.bounds.y,"width":h.clip.bounds.w,"height":h.clip.bounds.h}})).collect::>() })).collect::>(); let mut result = serde_json::json!({"profile_memory":profile_memory,"presentation_feedback":self.presentation.json(),"frame_profiling":self.profile_frames,"profile_scope":"Successful submissions only; CPU-side wall time includes driver waits. prepare_breakdown_ms is nested within prepare. No GPU execution or scanout timestamps.","gpu_cache":{"entries":cache.entries,"payload_bytes":cache.bytes,"active_payload_bytes":cache.active_bytes,"reuse_budget_bytes":cache.budget_bytes,"hits":cache.hits,"misses":cache.misses,"evictions":cache.evictions},"uptime_ms":self.epoch.elapsed().as_secs_f64()*1000.,"adapter":self.gpu.adapter_description,"surfaces":surfaces,"client":serde_json::from_str::(&self.app.inspect()).unwrap_or(serde_json::Value::Null)}); result["native_keyboard_focus"] = keyboard_focus.json; + result["keyboard_focus_requests"] = self.focus_requests.inspect(); result["native_keyboard_focus"]["routing_address_matches_observed_native"] = serde_json::json!( keyboard_focus .current_address @@ -655,6 +681,10 @@ impl State { self.error = Some(e.to_string()); self.exit = true; } + self.focus_request_revalidate(); + for request in effects.keyboard_focus { + self.focus_request(request, qh); + } self.input_release_revalidate(qh); for request in effects.input_release { self.input_release_request(request, qh); @@ -738,6 +768,7 @@ impl State { for request in effects.clipboard { self.clipboard_request(request, qh); } + self.focus_request_flush(qh); } fn reconcile(&mut self, qh: &QueueHandle) -> Result<(), Error> { self.reconcile_with_recreation(qh, &Default::default()) @@ -853,6 +884,7 @@ impl State { address, Native { input_release_callbacks: None, + identity: api::NativeSurfaceToken::new(), renderer, fractional: self .fractional @@ -860,6 +892,8 @@ impl State { .map(|globals| globals.surface(layer.wl_surface(), qh)), role: SurfaceRole::Layer(layer), committed_spec: spec.clone(), + pending_keyboard_none: false, + keyboard_claimed: false, spec, bound_output: target, width: 1, @@ -869,7 +903,7 @@ impl State { presented: None, demand: FrameDemand::default(), scene: Scene::default(), - interaction: Interaction::default(), + interaction: native_interaction(), regions: vec![], history: history.unwrap_or_default(), pacing: self.pacing.start_native(), @@ -884,12 +918,20 @@ impl State { Ok(()) } fn retire_native(&mut self, id: &api::SurfaceAddress) -> Option> { + if self.focus_requests_pending_for(id) { + self.focus_request_end(api::KeyboardFocusOutcome::Retired, false); + } if self.keyboard_surface.as_ref() == Some(id) { self.keyboard_surface = None; self.input_serial = None; } self.retiring.retire(id); let mut native = self.surfaces.remove(id)?; + self.focus_request_lifecycle( + native.spec.clone(), + native.identity.clone(), + api::KeyboardFocusChange::Retired, + ); self.pacing.retire(native.pacing.take()); self.presentation.retire_native(native.native_generation); Some(native) @@ -898,6 +940,9 @@ impl State { &mut self, id: &api::SurfaceAddress, ) -> Result, Error> { + if self.focus_requests_pending_for(id) { + self.focus_request_end(api::KeyboardFocusOutcome::Retired, false); + } let Some(native) = self.surfaces.get_mut(id) else { return Ok(None); }; @@ -905,7 +950,7 @@ impl State { return Err("Cannot recreate a session-lock surface".into()); }; let region = Region::new(&self.compositor)?; - if let Some(presented) = native.presented { + if let Some(presented) = &native.presented { // A failed/retried render may have queued viewport/role state // without submitting its matching buffer. This input-disable commit // must retain the geometry and scale of the last successful image. @@ -928,6 +973,11 @@ impl State { // native replacement and logical-history transfer are incomplete. } let mut previous = self.surfaces.remove(id).expect("validated native surface"); + self.focus_request_lifecycle( + previous.spec.clone(), + previous.identity.clone(), + api::KeyboardFocusChange::Retired, + ); self.pacing.retire(previous.pacing.take()); self.presentation.retire_native(previous.native_generation); let history = previous.history.continuation(); @@ -1150,6 +1200,11 @@ impl State { continue; } } + if s.committed_spec.keyboard != api::Keyboard::None + && s.spec.keyboard == api::Keyboard::None + { + s.pending_keyboard_none = true; + } s.committed_spec = s.spec.clone(); s.width = width; s.height = height; @@ -1166,6 +1221,7 @@ impl State { } else { s.scale as i32 }, + regions: s.regions.clone(), }); s.scene = scene; submitted.push(( @@ -1278,6 +1334,8 @@ impl State { .map(|(id, _)| id.clone()) } fn key(&mut self, event: KeyEvent, qh: &QueueHandle) { + self.focus_request_revalidate(); + self.focus_request_flush(qh); let Some(id) = self.keyboard_surface.clone() else { return; }; @@ -1287,6 +1345,10 @@ impl State { let Some(origin) = self .surfaces .get(&id) + .filter(|native| { + native.spec.keyboard != api::Keyboard::None + && native.committed_spec.keyboard != api::Keyboard::None + }) .map(|native| native.role.wl_surface().clone()) else { return; @@ -1298,7 +1360,12 @@ impl State { self.message(message, qh); } self.clipboard_observe_focus(qh); - if self.id_for(&origin).as_ref() != Some(&id) { + if self.id_for(&origin).as_ref() != Some(&id) + || !self.surfaces.get(&id).is_some_and(|native| { + native.spec.keyboard != api::Keyboard::None + && native.committed_spec.keyboard != api::Keyboard::None + }) + { return; } if let Some(s) = self.surfaces.get_mut(&id) { @@ -1708,6 +1775,7 @@ impl LayerShellHandler for State { } else { self.exit = true; } + self.focus_request_flush(qh); } fn configure( &mut self, @@ -1778,6 +1846,7 @@ impl OutputHandler for State { self.retire_native(&id); } self.outputs_changed(qh); + self.focus_request_flush(qh); } } impl SeatHandler for State { @@ -1828,6 +1897,8 @@ impl SeatHandler for State { && self.pointer_seat.as_ref() == Some(&seat) && let Some(p) = self.pointer.take() { + self.focus_request_end(api::KeyboardFocusOutcome::Unavailable, false); + self.focus_requests.origin = None; p.release(); self.pointer_seat = None; } @@ -1835,8 +1906,28 @@ impl SeatHandler for State { && self.keyboard_seat.as_ref() == Some(&seat) && let Some(k) = self.keyboard.take() { + if let Some(native) = self + .keyboard_surface + .as_ref() + .and_then(|id| self.surfaces.get(id)) + { + self.focus_request_lifecycle( + native.spec.clone(), + native.identity.clone(), + api::KeyboardFocusChange::Unavailable, + ); + } + if let Some(native) = self + .keyboard_surface + .as_ref() + .and_then(|id| self.surfaces.get_mut(id)) + { + native.set_keyboard_active(false); + } + self.focus_request_end(api::KeyboardFocusOutcome::Unavailable, false); self.input_serial = None; self.activation.input = None; + self.focus_requests.origin = None; self.input_method_remove_seat(qh); k.release(); self.native_keyboard_focus.keyboard_removed(); @@ -1845,6 +1936,7 @@ impl SeatHandler for State { self.clipboard_cancel(qh, true); self.clipboard_drop(); } + self.focus_request_flush(qh); } fn remove_seat(&mut self, conn: &Connection, qh: &QueueHandle, seat: wl_seat::WlSeat) { self.remove_capability(conn, qh, seat.clone(), Capability::Keyboard); @@ -1856,15 +1948,19 @@ impl PointerHandler for State { &mut self, _: &Connection, qh: &QueueHandle, - _: &wl_pointer::WlPointer, + pointer: &wl_pointer::WlPointer, events: &[PointerEvent], ) { + if self.pointer.as_ref() != Some(pointer) { + return; + } for event in events { // A wl_pointer.frame may contain several distinct native events. // Reconciliation for the next event must not borrow a preceding // button's unused authority (including when it is Motion/Leave). self.input_serial = None; self.activation.input = None; + self.focus_requests.origin = None; let Some(id) = self.id_for(&event.surface) else { continue; }; @@ -1911,19 +2007,34 @@ impl PointerHandler for State { let button = pointer_input::button(button); outside = button == api::MouseButton::Primary && !s.scene.hits.iter().any(|h| h.contains(x, y)); - if let Some(message) = s.interaction.press_button( - &s.scene, - x, - y, - button, - api::KeyModifiers { - control: self.modifiers.ctrl, - shift: self.modifiers.shift, - alt: self.modifiers.alt, - logo: self.modifiers.logo, - }, - ) { - messages.push(message); + messages.extend( + s.interaction + .press_button_messages( + &s.scene, + x, + y, + button, + api::KeyModifiers { + control: self.modifiers.ctrl, + shift: self.modifiers.shift, + alt: self.modifiers.alt, + logo: self.modifiers.logo, + }, + ) + .into_iter() + .flatten(), + ); + if button == api::MouseButton::Primary + && s.interaction.pressed_keyboard_focusable() + && s.spec.pointer_input != api::PointerInput::None + && let Some(seat) = &self.pointer_seat + { + self.focus_requests.origin = Some(focus_request::Origin { + address: id.clone(), + surface: event.surface.clone(), + native: s.identity.clone(), + seat: seat.clone(), + }); } } PointerEventKind::Release { button, .. } => { @@ -2023,9 +2134,18 @@ impl PointerHandler for State { } self.message(m, qh); } + if matches!(event.kind, PointerEventKind::Leave { .. }) + && self.focus_request_acquiring_for(&id) + { + self.focus_request_end(api::KeyboardFocusOutcome::Superseded, false); + } + self.focus_requests.origin = None; + self.focus_request_revalidate(); + self.focus_request_flush(qh); } self.input_serial = None; self.activation.input = None; + self.focus_requests.origin = None; } } impl KeyboardHandler for State { @@ -2041,7 +2161,20 @@ impl KeyboardHandler for State { ) { self.native_keyboard_focus .enter(self.keyboard.as_ref() == Some(keyboard), surface); + if self.keyboard.as_ref() != Some(keyboard) { + return; + } + // Even an Enter for a retiring/unknown own surface revokes the old + // routing address. It cannot leave a newer same-role native looking + // focused merely because this proxy is absent from the current map. + if let Some(previous) = self.keyboard_surface.take() + && let Some(native) = self.surfaces.get_mut(&previous) + { + native.set_keyboard_active(false); + } let Some(id) = self.id_for(surface) else { + self.input_method_observe(); + self.clipboard_cancel(qh, false); return; }; self.clipboard_cancel(qh, false); @@ -2049,8 +2182,25 @@ impl KeyboardHandler for State { // may hide or renew this address; only this exact native object's Enter // can grant authority to the still-current lifetime. if self.id_for(surface).as_ref() == Some(&id) { - self.keyboard_surface = Some(id); + self.keyboard_surface = Some(id.clone()); + if let Some(native) = self.surfaces.get_mut(&id) { + native.set_keyboard_active(true); + } self.input_method_observe(); + if let Some(native) = self + .id_for(surface) + .as_ref() + .and_then(|id| self.surfaces.get(id)) + { + self.focus_request_lifecycle( + native.spec.clone(), + native.identity.clone(), + api::KeyboardFocusChange::Entered, + ); + } + self.focus_request_flush(qh); + self.focus_request_enter(surface, qh); + self.focus_request_flush(qh); } } fn leave( @@ -2063,6 +2213,9 @@ impl KeyboardHandler for State { ) { self.native_keyboard_focus .leave(self.keyboard.as_ref() == Some(keyboard), surface); + if self.keyboard.as_ref() != Some(keyboard) { + return; + } let Some(id) = self.id_for(surface) else { return; }; @@ -2070,18 +2223,37 @@ impl KeyboardHandler for State { return; } self.keyboard_surface = None; + if let Some(native) = self.surfaces.get_mut(&id) { + native.pending_keyboard_none = false; + native.set_keyboard_active(false); + } self.input_serial = None; self.input_method_observe(); self.clipboard_cancel(qh, false); + if let Some(native) = self + .surfaces + .get(&id) + .filter(|native| native.role.wl_surface() == surface) + { + self.focus_request_lifecycle( + native.spec.clone(), + native.identity.clone(), + api::KeyboardFocusChange::Left, + ); + } + self.focus_request_flush(qh); } fn press_key( &mut self, _: &Connection, qh: &QueueHandle, - _: &wl_keyboard::WlKeyboard, + keyboard: &wl_keyboard::WlKeyboard, serial: u32, event: KeyEvent, ) { + if self.keyboard.as_ref() != Some(keyboard) { + return; + } self.input_serial = Some(serial); self.activation.input = self .keyboard_surface @@ -2101,10 +2273,13 @@ impl KeyboardHandler for State { &mut self, _: &Connection, qh: &QueueHandle, - _: &wl_keyboard::WlKeyboard, + keyboard: &wl_keyboard::WlKeyboard, _: u32, event: KeyEvent, ) { + if self.keyboard.as_ref() != Some(keyboard) { + return; + } self.key(event, qh); } fn release_key( @@ -2120,12 +2295,15 @@ impl KeyboardHandler for State { &mut self, _: &Connection, _: &QueueHandle, - _: &wl_keyboard::WlKeyboard, + keyboard: &wl_keyboard::WlKeyboard, _: u32, modifiers: Modifiers, _: RawModifiers, _: u32, ) { + if self.keyboard.as_ref() != Some(keyboard) { + return; + } self.modifiers = modifiers; } } @@ -2134,7 +2312,7 @@ impl ProvidesRegistryState for State { fn registry(&mut self) -> &mut RegistryState { &mut self.registry } - registry_handlers![OutputState, SeatState]; + registry_handlers![OutputState, SeatState, focus_request::Registry]; } smithay_client_toolkit::delegate_dispatch2!(@ State); diff --git a/reports/measurements/lucent-cold-default-uri-b2.json b/reports/measurements/lucent-cold-default-uri-b2.json new file mode 100644 index 00000000..c7235b2f --- /dev/null +++ b/reports/measurements/lucent-cold-default-uri-b2.json @@ -0,0 +1,384 @@ +{ + "schema_version": 1, + "scope": "canonical native cold default-URI trial on source b2; sanitized read-only focus diagnostic checkpoints", + "source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "desktop_binary_sha256": "8a076c744be2016e23bb5d033656af1eb23e243f6abbeecc7616cd1336c50d41", + "release_manifest_sha256": "ba2a89b036ad00fde7fca82cce9a1647ab91247e2b59a90874bf87f587fb48b2", + "deployment_receipt_sha256": "442708667fbb701b86ad7303f8b34dee33417d3055b7bdbccd8d13c3a2fc41b8", + "build": { + "hosted_run": 40415443527, + "stages_passed": 17, + "targeted_tests_passed": 840, + "static_target_elf_compatibility_passed": 10, + "not_performance_acceptance": true + }, + "cases": [ + { + "case": "pointer", + "original_report_sha256": "947ad73f12106a970f5fe792403258045b793b1319cdda11480c34512af6f9c3", + "feature_accepted": true, + "success_including_cleanup": true, + "checks": { + "temporary_real_mime_default_selected": true, + "pointer_fresh_token_default_route_exact_document": true, + "pointer_notification_absent_after_expiry_window": true + }, + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "focus_checkpoints": [ + { + "checkpoint": "after_group_setup", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 3, + "native_leave_count": 2, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_uri_dispatch", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 3, + "native_leave_count": 2, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "browser_mapped", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 3, + "native_leave_count": 3, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 3, + "native_leave_count": 3, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "after_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 3, + "native_leave_count": 3, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + } + ], + "native_trusted_key_accepted": true + }, + { + "case": "keyboard", + "original_report_sha256": "bded3f3e821a5f97cf4f3d3023c9d18e8758650deea11907c0c80eef6cdc3b36", + "feature_accepted": false, + "success_including_cleanup": false, + "checks": { + "temporary_real_mime_default_selected": true + }, + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "focus_checkpoints": [ + { + "checkpoint": "after_group_setup", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 4, + "native_leave_count": 3, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_uri_dispatch", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 4, + "native_leave_count": 3, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "browser_mapped", + "notification_history_open": false, + "native_resolution": "current-native", + "current_lucent_role": "clock", + "native_enter_count": 5, + "native_leave_count": 4, + "document_available": true, + "document_has_focus": false, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": true + }, + { + "role": "notifications", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_key_a", + "notification_history_open": false, + "native_resolution": "current-native", + "current_lucent_role": "clock", + "native_enter_count": 5, + "native_leave_count": 4, + "document_available": true, + "document_has_focus": false, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "after_key_a", + "notification_history_open": false, + "native_resolution": "current-native", + "current_lucent_role": "clock", + "native_enter_count": 5, + "native_leave_count": 4, + "document_available": true, + "document_has_focus": false, + "observed_policies": [ + { + "role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_keyboard_focused": true + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + } + ], + "native_trusted_key_accepted": false, + "failure": { + "scope": "native_default_uri_acceptance", + "phase": "browser_key_delivery_wait", + "fixed_reason": "owned_browser_received_native_key_a" + } + } + ], + "interpretation": [ + "During history, Clock and Calendar requested and committed None. After history closed, their OnDemand eligibility returned.", + "The keyboard route observed current Clock native focus while the real browser document lacked focus; the pointer route observed no Lucent client focus and browser document focus.", + "This establishes the current client native owner, not the compositor global seat owner or atomic ordering across snapshots.", + "Source-only one-shot focus acquisition and demand changes require fresh compilation and native acceptance; no fix is accepted here." + ], + "privacy": "No credentials, URI, browser profile, output identifier, native object identity, input text, hostname or raw snapshots included.", + "performance_accepted": false +} diff --git a/reports/measurements/lucent-cold-default-uri-ba5.json b/reports/measurements/lucent-cold-default-uri-ba5.json new file mode 100644 index 00000000..ce475133 --- /dev/null +++ b/reports/measurements/lucent-cold-default-uri-ba5.json @@ -0,0 +1,711 @@ +{ + "schema_version": 1, + "recorded_on": "2026-10-27", + "scope": "Canonical cold default-handler notification pointer and Tab/Enter routes on source ba5, one 1920x1080 scale-1 virtual output. Both routes and each nine-check cleanup pass. This source was an unmerged candidate at capture; broader widget, secure-session, application, hardware and performance acceptance remain separate.", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "desktop_binary_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "release_manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "deployment_receipt_sha256": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "candidate_accepted_main_at_capture": false, + "host_controller_sha256": "dbad8457b42e0f1eb6d47b38b11beefca8d79e682bbb58bb9ee0f1763dd695ba", + "focus_probe_sha256": "d63f741d57d16a16fe0ec14871ce9b333c1c6a6de0d0be19ac1e01b8e10870a6", + "build": { + "hosted_run": 40433468095, + "stages_passed": 17, + "targeted_tests_passed": 880, + "static_target_ELF_imports_passed": 10 + }, + "cases": [ + { + "case": "pointer", + "original_private_report_sha256": "9a13ffb1aad9628bb29e81309e03e3f9c3ac84fd269d2e149b41b2e65b2cc5f3", + "canonical_native_accepted": true, + "success_including_cleanup": true, + "feature_checks": { + "temporary_real_mime_default_selected": true, + "pointer_fresh_token_default_route_exact_document": true, + "pointer_notification_absent_after_expiry_window": true + }, + "feature_checks_passed": 3, + "browser_focus_observed": true, + "trusted_key_dispatch_attempted": true, + "trusted_key_dispatch_returned": true, + "observer_armed_with_zero_events": true, + "trusted_unmodified_nonrepeat_KeyA_observed": true, + "trusted_KeyA_event_count": 1, + "last_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": true, + "surface_absent": false, + "notification_policy": "normal-toast" + }, + "before_key_dispatch_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "after_key_event_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "policy_timeline_event_count": 5, + "focus_checkpoints": [ + { + "checkpoint": "after_group_setup", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 1, + "native_leave_count": 0, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_uri_dispatch", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 1, + "native_leave_count": 0, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "browser_mapped", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 1, + "native_leave_count": 1, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 1, + "native_leave_count": 1, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "after_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 1, + "native_leave_count": 1, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + } + ], + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "cleanup_checks_passed": 9, + "cleanup_check_count": 9 + }, + { + "case": "keyboard", + "original_private_report_sha256": "dba0711517979d7a05cbaa6e551e7f565563b93013b33bcb9565526ef7e11a3b", + "canonical_native_accepted": true, + "success_including_cleanup": true, + "feature_checks": { + "temporary_real_mime_default_selected": true, + "keyboard_fresh_token_default_route_exact_document": true, + "keyboard_notification_absent_after_expiry_window": true + }, + "feature_checks_passed": 3, + "browser_focus_observed": true, + "trusted_key_dispatch_attempted": true, + "trusted_key_dispatch_returned": true, + "observer_armed_with_zero_events": true, + "trusted_unmodified_nonrepeat_KeyA_observed": true, + "trusted_KeyA_event_count": 1, + "last_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "before_key_dispatch_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "after_key_event_release_observation": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "policy_timeline_event_count": 5, + "focus_checkpoints": [ + { + "checkpoint": "after_group_setup", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 2, + "native_leave_count": 1, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_uri_dispatch", + "notification_history_open": true, + "native_resolution": "current-native", + "current_lucent_role": "notifications", + "native_enter_count": 2, + "native_leave_count": 1, + "document_available": false, + "document_has_focus": null, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "exclusive", + "committed_keyboard": "exclusive", + "actual_native_keyboard_focused": true + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "browser_mapped", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 2, + "native_leave_count": 2, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "notifications", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "before_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 2, + "native_leave_count": 2, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + }, + { + "checkpoint": "after_key_a", + "notification_history_open": false, + "native_resolution": "no-client-focus-observed", + "current_lucent_role": null, + "native_enter_count": 2, + "native_leave_count": 2, + "document_available": true, + "document_has_focus": true, + "observed_policies": [ + { + "role": "background", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "bar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "clock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "dock", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + }, + { + "role": "system", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_keyboard_focused": false + } + ], + "atomic_snapshot": false, + "actual_global_seat_owner_available": false, + "release_ack_directly_observable": false + } + ], + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "cleanup_checks_passed": 9, + "cleanup_check_count": 9, + "tab_events_sent": 2 + } + ], + "route_separation": { + "independent_cold_profiles": true, + "independent_original_browser_process_births": true, + "same_desktop_lifetime_during_two_URI_cases": true, + "second_case_after_first_successful_cleanup": true + }, + "acceptance": { + "pointer_route_passed": true, + "keyboard_route_passed": true, + "both_original_cold_routes_passed": true, + "original_pointer_and_Tab_Enter_steps_unchanged": true, + "forced_compositor_focus_used": false, + "diagnostic_cursor_reposition_workaround_used": false, + "browser_prewarmed": false, + "direct_protocol_token_consumption_established": false, + "global_seat_owner_observed": false, + "immediate_first_Notes_key_or_first_outside_click_accepted_by_this_report": false, + "secure_lock_or_login_accepted_by_this_report": false, + "broader_handler_or_application_acceptance": false, + "physical_hardware_accepted": false, + "performance_accepted": false + }, + "interpretation": [ + "Each canonical route opens its exact declared document in a fresh owned Chromium birth through the real temporary default handler and receives exactly one trusted, unmodified, nonrepeat KeyA. Each passes all three feature and all nine named cleanup checks.", + "The original pointer and Tab/Enter routes are retained. No browser prewarming, focus dispatch, extra browser click, hiding, or diagnostic cursor-to-link workaround is used to make destination input succeed.", + "At browser-map, before-key and after-key checkpoints, the sampled Lucent widget policies remain None and the owned document reports focus. The Lucent observer reports no current own-client Native. This is dispatched client observation, not an atomic global seat-owner query.", + "Unavailable document focus, direct release acknowledgement timing and native-frame advancement are preserved as null or unavailable according to the actual report; disappearance of the notification surface is not converted into a zero frame count.", + "Historical eb348/3640/b2 keyboard failures and the separate cursor-only diagnostic retain their original outcomes. The mixed f26 decoder/performance result is unchanged. The current source closes only this controlled cold default-handler keyboard case, not every requested application or performance gap." + ], + "privacy": { + "only_allowlisted_source_hashes_booleans_counts_and_component_roles": true, + "credentials_URI_profile_paths_process_or_native_object_IDs_Notes_and_raw_snapshots_included": false, + "private_raw_evidence_preserved": true + } +} diff --git a/reports/measurements/lucent-cold-default-uri-d77.json b/reports/measurements/lucent-cold-default-uri-d77.json new file mode 100644 index 00000000..16c9498c --- /dev/null +++ b/reports/measurements/lucent-cold-default-uri-d77.json @@ -0,0 +1,107 @@ +{ + "schema_version": 1, + "source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", + "manifest_sha256": "b25ac061d3fe334299f61d7d120d489d03975036ed477fc797caca4ba7ab0a06", + "desktop_sha256": "ed2166062a55676897bc745b3cea956e8276b4ae5f9a6019dce4aa1f4c5a70b5", + "host_controller_sha256": "e1212b5562b7652568605bef0caae05bbda631ef28a2284ec765dbe2fd57b15a", + "accepted_main_at_capture": false, + "status": "both_original_canonical_cold_routes_passed", + "scope": "One 1920x1080 scale-1 virtual output. Separate fresh owned browser births through the real temporary default handler; original pointer and Tab/Enter gestures, trusted keyboard input and full cleanup. This is a separately executed d77 result, not inherited from ba5.", + "cases": [ + { + "case": "pointer", + "original_private_report_sha256": "e732aaeae99cffec9cba30092b868bdd52dc16007f1a2c97240f0065cbebc729", + "canonical_native_accepted": true, + "feature_checks": { + "temporary_real_mime_default_selected": true, + "pointer_fresh_token_default_route_exact_document": true, + "pointer_notification_absent_after_expiry_window": true + }, + "feature_checks_passed": 3, + "trusted_unmodified_nonrepeat_KeyA_count": 1, + "observer_armed_with_zero_events": true, + "pre_dispatch_release": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "post_event_release": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "cleanup_checks_passed": 9 + }, + { + "case": "keyboard", + "original_private_report_sha256": "a06d5157da88305dfddbf77895c0cfd3310804eadf47e779ae9d5ee9165703d8", + "canonical_native_accepted": true, + "feature_checks": { + "temporary_real_mime_default_selected": true, + "keyboard_fresh_token_default_route_exact_document": true, + "keyboard_notification_absent_after_expiry_window": true + }, + "feature_checks_passed": 3, + "trusted_unmodified_nonrepeat_KeyA_count": 1, + "observer_armed_with_zero_events": true, + "pre_dispatch_release": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "post_event_release": { + "history_closed": true, + "inspected_modal_input_released": true, + "native_frames_advanced": null, + "surface_absent": true, + "notification_policy": "absent" + }, + "cleanup": { + "browser_and_original_entry_retired": true, + "notifications_absent_after_expiry_window": true, + "default_mime_restored": true, + "default_entry_restored": true, + "notification_history_closed": true, + "configuration_guardian_retired": true, + "canonical_browser_and_entry_retired": true, + "original_http_watchdog_retired": true, + "caller_state_and_cursor_preserved": true + }, + "cleanup_checks_passed": 9 + } + ], + "acceptance": { + "pointer": true, + "Tab_Enter": true, + "original_steps_unchanged": true, + "forced_focus": false, + "browser_prewarmed": false, + "diagnostic_cursor_workaround": false, + "same_normal_desktop_lifetime_preserved": true, + "widget_first_key_outside_or_reacquisition": false, + "direct_protocol_token_consumption": false, + "secure_lock_or_login": false, + "physical_hardware": false, + "eligible_memory_or_source_rate_pacing": false + }, + "privacy": { + "raw_Notes_text_images_credentials_URI_profile_paths_process_ids_native_ids_argv_environment_and_exact_epochs_published": false + } +} diff --git a/reports/measurements/lucent-decoder-retarget-f26.json b/reports/measurements/lucent-decoder-retarget-f26.json new file mode 100644 index 00000000..c407d274 --- /dev/null +++ b/reports/measurements/lucent-decoder-retarget-f26.json @@ -0,0 +1,482 @@ +{ + "schema_version": 1, + "scope": "Isolated CPU decoder mechanism comparison on a GitHub-hosted Arch container; finite 12-second phases, no renderer/compositor/VM or full-desktop acceptance", + "backend_commit": "1aebe2e3ffa88416791f122d9fbf01bb0f66f91f", + "tools_commit": "f26f8a26b880eeb8ac01da9e57cb8a7cc4d76322", + "run_id": 40429866532, + "original_zip_sha256": "de1b83dc59ea4d7519d3d14e033973112a11877eabfdff9ea0c5d3c64a6fbabd", + "qualified_receipt_sha256": "48b7ff83f39f79357785ec9a255db445f7d6bf786d31c71863025f932979706e", + "actual_test_counts": { + "domain": 37, + "video": 67, + "observer": 21, + "consumer": 15 + }, + "canonical_cases_qualified": 4, + "same_binary_input_and_genuine_prepared_asset_verified": true, + "genuine_import_in_separate_process": true, + "case_processes_fresh_and_nonoverlapping": true, + "phases_seconds": 12, + "allocator_observation_scope": "Only before playback, after worker cancellation/join with latest held, and after latest dropped. Never queried during playback.", + "cases": [ + { + "sequence": "known_targets", + "mode": "reopen", + "play_calls": 3, + "joins": 3, + "phases": [ + { + "phase": "first_fhd", + "revision": 1, + "size": [ + 1920, + 1080 + ], + "ready_ms": 60, + "observed_ms": 12008, + "publications": 722, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 179656, + "rss_min_kib": 177412, + "rss_max_kib": 179656, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 3, + "stale_total": 0 + }, + { + "phase": "four_k", + "revision": 2, + "size": [ + 3840, + 2160 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 722, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 280704, + "rss_min_kib": 280320, + "rss_max_kib": 280704, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 6, + "stale_total": 0 + }, + { + "phase": "restored_fhd", + "revision": 3, + "size": [ + 1920, + 1080 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 723, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 202112, + "rss_min_kib": 201724, + "rss_max_kib": 202112, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 9, + "stale_total": 0 + } + ], + "stopped": [ + { + "moment": "before_play", + "rss_kib": 25756, + "arena_free_bytes": 124640, + "accounted_in_use_bytes": 276768, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_join_latest_held", + "rss_kib": 195216, + "arena_free_bytes": 154442448, + "accounted_in_use_bytes": 8840496, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_latest_dropped", + "rss_kib": 195216, + "arena_free_bytes": 162736272, + "accounted_in_use_bytes": 546672, + "direct_mmap_bytes": 0 + } + ] + }, + { + "sequence": "known_targets", + "mode": "retarget", + "play_calls": 1, + "joins": 1, + "phases": [ + { + "phase": "first_fhd", + "revision": 1, + "size": [ + 1920, + 1080 + ], + "ready_ms": 70, + "observed_ms": 12007, + "publications": 721, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 179928, + "rss_min_kib": 177776, + "rss_max_kib": 179928, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 3, + "stale_total": 0 + }, + { + "phase": "four_k", + "revision": 2, + "size": [ + 3840, + 2160 + ], + "ready_ms": 20, + "observed_ms": 12008, + "publications": 721, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 254852, + "rss_min_kib": 254848, + "rss_max_kib": 277556, + "first_pts_ns": 66666667, + "last_pts_ns": 66666667, + "loop_wraps_total": 6, + "stale_total": 1 + }, + { + "phase": "restored_fhd", + "revision": 3, + "size": [ + 1920, + 1080 + ], + "ready_ms": 20, + "observed_ms": 12008, + "publications": 720, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 180360, + "rss_min_kib": 180184, + "rss_max_kib": 180360, + "first_pts_ns": 100000000, + "last_pts_ns": 100000000, + "loop_wraps_total": 9, + "stale_total": 2 + } + ], + "stopped": [ + { + "moment": "before_play", + "rss_kib": 25928, + "arena_free_bytes": 124640, + "accounted_in_use_bytes": 276768, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_join_latest_held", + "rss_kib": 173592, + "arena_free_bytes": 132469152, + "accounted_in_use_bytes": 8838752, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_latest_dropped", + "rss_kib": 173592, + "arena_free_bytes": 140762928, + "accounted_in_use_bytes": 544976, + "direct_mmap_bytes": 0 + } + ] + }, + { + "sequence": "source_and_targets", + "mode": "reopen", + "play_calls": 5, + "joins": 5, + "phases": [ + { + "phase": "initial_source", + "revision": 1, + "size": [ + 3840, + 2160 + ], + "ready_ms": 60, + "observed_ms": 12009, + "publications": 722, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 252312, + "rss_min_kib": 250120, + "rss_max_kib": 252312, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 3, + "stale_total": 0 + }, + { + "phase": "first_fhd", + "revision": 2, + "size": [ + 1920, + 1080 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 719, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 202100, + "rss_min_kib": 201172, + "rss_max_kib": 202100, + "first_pts_ns": 0, + "last_pts_ns": 0, + "loop_wraps_total": 6, + "stale_total": 0 + }, + { + "phase": "four_k", + "revision": 3, + "size": [ + 3840, + 2160 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 723, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 299436, + "rss_min_kib": 299048, + "rss_max_kib": 299436, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 9, + "stale_total": 0 + }, + { + "phase": "restored_fhd", + "revision": 4, + "size": [ + 1920, + 1080 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 722, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 234708, + "rss_min_kib": 234328, + "rss_max_kib": 234708, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 12, + "stale_total": 0 + }, + { + "phase": "restored_source", + "revision": 5, + "size": [ + 3840, + 2160 + ], + "ready_ms": 50, + "observed_ms": 12008, + "publications": 723, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 299608, + "rss_min_kib": 299224, + "rss_max_kib": 299608, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 15, + "stale_total": 0 + } + ], + "stopped": [ + { + "moment": "before_play", + "rss_kib": 26024, + "arena_free_bytes": 124640, + "accounted_in_use_bytes": 276768, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_join_latest_held", + "rss_kib": 292712, + "arena_free_bytes": 229368176, + "accounted_in_use_bytes": 33889936, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_latest_dropped", + "rss_kib": 227908, + "arena_free_bytes": 196185984, + "accounted_in_use_bytes": 712832, + "direct_mmap_bytes": 0 + } + ] + }, + { + "sequence": "source_and_targets", + "mode": "retarget", + "play_calls": 1, + "joins": 1, + "phases": [ + { + "phase": "initial_source", + "revision": 1, + "size": [ + 3840, + 2160 + ], + "ready_ms": 60, + "observed_ms": 12008, + "publications": 721, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 250392, + "rss_min_kib": 248200, + "rss_max_kib": 250392, + "first_pts_ns": 0, + "last_pts_ns": 33333333, + "loop_wraps_total": 3, + "stale_total": 0 + }, + { + "phase": "first_fhd", + "revision": 2, + "size": [ + 1920, + 1080 + ], + "ready_ms": 10, + "observed_ms": 12008, + "publications": 721, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 178312, + "rss_min_kib": 177948, + "rss_max_kib": 178312, + "first_pts_ns": 50000000, + "last_pts_ns": 50000000, + "loop_wraps_total": 6, + "stale_total": 0 + }, + { + "phase": "four_k", + "revision": 3, + "size": [ + 3840, + 2160 + ], + "ready_ms": 30, + "observed_ms": 12009, + "publications": 722, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 275600, + "rss_min_kib": 275596, + "rss_max_kib": 275600, + "first_pts_ns": 83333333, + "last_pts_ns": 100000000, + "loop_wraps_total": 9, + "stale_total": 1 + }, + { + "phase": "restored_fhd", + "revision": 4, + "size": [ + 1920, + 1080 + ], + "ready_ms": 20, + "observed_ms": 12008, + "publications": 721, + "rgba_bytes": 8294400, + "latest_capacity_bytes": 8294400, + "rss_last_kib": 275804, + "rss_min_kib": 275676, + "rss_max_kib": 275804, + "first_pts_ns": 116666667, + "last_pts_ns": 116666667, + "loop_wraps_total": 12, + "stale_total": 1 + }, + { + "phase": "restored_source", + "revision": 5, + "size": [ + 3840, + 2160 + ], + "ready_ms": 20, + "observed_ms": 12008, + "publications": 721, + "rgba_bytes": 33177600, + "latest_capacity_bytes": 33177600, + "rss_last_kib": 308616, + "rss_min_kib": 308612, + "rss_max_kib": 308616, + "first_pts_ns": 150000000, + "last_pts_ns": 150000000, + "loop_wraps_total": 15, + "stale_total": 2 + } + ], + "stopped": [ + { + "moment": "before_play", + "rss_kib": 26012, + "arena_free_bytes": 124640, + "accounted_in_use_bytes": 276768, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_join_latest_held", + "rss_kib": 301912, + "arena_free_bytes": 240512848, + "accounted_in_use_bytes": 33886384, + "direct_mmap_bytes": 0 + }, + { + "moment": "after_latest_dropped", + "rss_kib": 237108, + "arena_free_bytes": 207330608, + "accounted_in_use_bytes": 709328, + "direct_mmap_bytes": 0 + } + ] + } + ], + "interpretation": [ + "The known-target FHD/4K/FHD endpoint uses 21.24 MiB less RSS with one retargeted worker than with reopening.", + "The Source/FHD/4K/FHD endpoint uses 40.13 MiB more RSS with one retargeted worker; the final source-size endpoint is also worse.", + "After dropping the final Source frame, retarget RSS remains 8.98 MiB higher, while accounted in-use bytes are nearly equal and free arena bytes are 10.63 MiB higher. This is consistent with extra arena retention, not proof of leaked live pixel owners.", + "No general memory improvement is established; production client target wiring is not enabled by these observations." + ], + "limitations": [ + "These are last/min/max RSS samples for finite isolated phases, not 120-second whole-shell measurements.", + "Only latest-frame capacity is instrumented; old-last-good and in-flight frame ownership are not separately measured.", + "Publications/PTS/loop validation do not establish display FPS or physical presentation.", + "Allocator counters overlap other memory scopes and do not form an additive RSS ledger." + ], + "whole_shell_memory_target_accepted": false, + "native_presentation_accepted": false, + "general_memory_improvement_established": false +} diff --git a/reports/measurements/lucent-keyboard-control-flush-d77.json b/reports/measurements/lucent-keyboard-control-flush-d77.json new file mode 100644 index 00000000..2d9be36a --- /dev/null +++ b/reports/measurements/lucent-keyboard-control-flush-d77.json @@ -0,0 +1,104 @@ +{ + "schema_version": 1, + "status": "coherent_candidate_deployed_native_input_handoff_unresolved", + "source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", + "manifest_sha256": "b25ac061d3fe334299f61d7d120d489d03975036ed477fc797caca4ba7ab0a06", + "desktop_sha256": "ed2166062a55676897bc745b3cea956e8276b4ae5f9a6019dce4aa1f4c5a70b5", + "accepted_main": false, + "source_change": { + "scope": "Two nonblocking complete keyboard-control transaction flushes; no timer, focus assertion or input replay. WouldBlock remains deferred to the existing event loop.", + "new_regression_tests_passed": 5, + "native_fix_accepted": false + }, + "actual_hosted_release": { + "run": 40448216820, + "job": 122004465545, + "conclusion": "SUCCESS", + "qualification_stages": 17, + "targeted_tests_passed": 885, + "required_named_tests_passed": 99, + "fresh_producer_inputs": 121, + "actual_PNGs": 480, + "static_ELF_consumers_passed": 10, + "independent_FFmpeg_header_ABI_review_passed_for_this_trial": true, + "target_provider_and_header_closure_revalidated": true, + "public_component_catalogue_promoted": false, + "catalogue_scope": "All 480 PNG bytes and 121 producer fingerprints match the ba5 catalogue; the actual fresh manifest records d77. No native or performance acceptance follows from headless rendering." + }, + "actual_coherent_deployment": { + "passed": true, + "private_receipt_sha256": "bc518320b94891739f3abc9e21961d2754030f8c83e88d7c6399e3efe964b8b8", + "managed_user_clients_verified": 6, + "root_greeter_verified": true, + "state_security_and_startup_stability_passed": true, + "greetd_restarted": false, + "settings_or_theme_written": false, + "scope": "Recorded installation and normal-state checkpoint; not ongoing process-liveness or lock/login interaction proof." + }, + "held_button_trial": { + "private_report_sha256": "ba52c2dab32472ac004ee9a5a4fb3ad741853b5d1eeb36620e802de64950bc37", + "whole_trial_passed": false, + "failed_check": "first_physical_notes_key_arrived", + "restoration_checks_passed": 9, + "all_recorded_restoration_passed": true, + "runtime_retired_by_expected_cleanup": true, + "host_DOWN_to_key_transport_ms": 42.85748297115788, + "first_key_reached_Notes": false, + "first_key_reached_owned_browser": true, + "Notes_native_focus_observed_later": true, + "outside_or_reacquisition_attempted": false + }, + "completed_click_V8": { + "private_report_sha256": "b671fefb8820e7a518043a9449860ae1cc3b1066a5c8d413f5fd4f8794741cf4", + "whole_trial_passed": false, + "failed_check": "no_managed_window_has_notes_keyboard_focus", + "restoration_checks_passed": 9, + "all_recorded_restoration_passed": true, + "runtime_retired_by_expected_cleanup": true, + "host_DOWN_to_key_transport_ms": 72.52693903865293, + "first_key_reached_Notes": true, + "first_key_reached_owned_browser": false, + "Notes_native_focus_and_visible_caret_observed": true, + "guard_failure_scope": "Inherited empty active-window assertion was invalid for a focused layer surface; the preserved trial still fails and stops before outside input.", + "outside_or_reacquisition_attempted": false + }, + "completed_click_V9": { + "private_report_sha256": "d3b0c2484847b5948171c4e93c1e93a444d10a39d2308f588fd010fcff6efd5e", + "whole_trial_passed": false, + "failed_check": "first_genuine_outside_click_and_key_delivered", + "restoration_checks_passed": 9, + "all_recorded_restoration_passed": true, + "runtime_retired_by_expected_cleanup": true, + "host_first_DOWN_to_key_transport_ms": 72.12372601497918, + "first_Notes_key_and_ordinary_undo_passed": true, + "guard_correction_scope": "Uses the actual current native layer object, seat keyboard availability, routing, native Enter and OnDemand policy together with browser DOM focus=false; managed active-window labels are not keyboard ownership.", + "outside_host_DOWN_to_key_transport_ms": 61.36029399931431, + "outside_browser_trusted_pointerdown_up_and_click_each": 1, + "outside_browser_plain_trusted_KeyA_count": 0, + "outside_browser_document_focus_observed_later": true, + "outside_key_reached_Notes": true, + "reacquisition_attempted": false + }, + "input_order_scope": { + "button_edges_have_separate_QMP_synchronizations": true, + "completed_click_sends_UP_before_key_on_host": true, + "QMP_return_is_guest_delivery_acknowledgement": false, + "host_transport_order_is_guest_input_dispatch_order": false, + "guest_kernel_input_order_measured": false, + "compositor_or_client_dispatch_order_measured": false, + "failure_cause_established": false, + "next_diagnostic": "A finite read-only observer of the exact VM USB tablet and PS/2 keyboard is being prepared. No delay, focus wait, repeated input or compositor-policy workaround is accepted as a fix." + }, + "remaining_acceptance": { + "canonical_cold_URI_on_d77": "not_executed; ba5 results are not inherited", + "first_same_workspace_outside_click_and_key": "failed_in_V9", + "Notes_reacquisition": "unattempted", + "secure_lock_on_d77": "not_executed; ba5 V3 pass retains its source", + "eligible_RSS_and_source_rate_pacing": "pending" + }, + "privacy": { + "raw_Notes_content_lengths_or_images_published": false, + "raw_paths_credentials_argv_environment_or_exact_epochs_published": false + }, + "historical_ba5_reports_unchanged": true +} diff --git a/reports/measurements/lucent-keyboard-intent-ba5-release.json b/reports/measurements/lucent-keyboard-intent-ba5-release.json new file mode 100644 index 00000000..85f32723 --- /dev/null +++ b/reports/measurements/lucent-keyboard-intent-ba5-release.json @@ -0,0 +1,267 @@ +{ + "schema_version": 1, + "recorded_date": "2026-10-27", + "scope": "Source-specific hosted Arch qualification, CPU software-Vulkan component export, concrete target compatibility review and coherent candidate VM deployment; native focus/security/performance acceptance remains separate.", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "source_tree": "7a0a016ae3b19462a14a564816251c22c531dbd7", + "accepted_main_checkpoint": "c3007cc5cefc5faab36f751a28542898ecefac0d", + "candidate_pull_request": 117, + "candidate_accepted_main": false, + "build": { + "workflow_run": 40433468095, + "workflow_head": "949cc8c954f3de70e91b59c5926b992dad545838", + "workflow_conclusion": "success", + "location": "github-hosted-Arch-container", + "qualification_stages_passed": 17, + "targeted_tests_passed": 880, + "required_named_regressions_passed": 94, + "test_counts": { + "lucent-domain-tests": 34, + "lucent-api-tests": 84, + "lucent-ui-tests": 121, + "lucent-wayland-tests": 115, + "desktop-tests": 404, + "video-tests": 49, + "application-adapter-tests": 46, + "upload-pure-tests": 2, + "upload-vulkan-tests": 7, + "desktop-bar-pixels-tests": 1, + "allocation-tests": 3, + "video-allocation-example-tests": 14 + }, + "coherent_runtime_executables": 9, + "standalone_component_lab_same_source": true, + "managed_support_files": 29, + "example_sources": 5, + "vendored_protocol_license_preserved": true, + "raw_archive_manifest_sha256": "c3417f557490b0d348dcc7446f881095c13f7e03d9fe0dcbcfa35f2c812e4788", + "localized_release_manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "artifact_zip_sha256": "e90681b1b8146c9af102c5881cf157b476aa5a9c0c6d755384884baa7ae3a9e5", + "original_archive_flags": { + "accepted_main": false, + "vm_deployed": false, + "native_activated": false, + "runtime_ABI_accepted": false + }, + "archive_flags_not_rewritten_after_deployment": true + }, + "hosted_memory_admission": { + "CPU_limit": 3, + "memory_limit_GiB": 10, + "swap_limit_bytes": 0, + "effective_available_floor_MiB": 4500, + "initial_samples_MiB": [ + 7324, + 7324, + 7324 + ], + "capture_samples_MiB": [ + 6402, + 6402, + 6402 + ], + "private_target_removed_after_hash_copy": true, + "copied_payload_hashes_verified_before_and_after": 45, + "effective_available_before_cleanup_MiB": 3795, + "effective_available_after_cleanup_MiB": 6402, + "cgroup_current_before_bytes": 6757535744, + "cgroup_current_after_bytes": 4023529472, + "cgroup_file_before_bytes": 6412808192, + "cgroup_file_after_bytes": 3770560512, + "global_caches_or_swap_policy_changed": false, + "scope": "Observed hosted build admission and owned target deletion. This is not normal desktop RSS/CPU acceptance or proof of the unrecorded earlier failure cause." + }, + "component_catalog": { + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "stories": 9, + "palettes": 5, + "captures": 480, + "rendering_inputs": 121, + "backend": "Vulkan", + "adapter": "llvmpipe", + "device_type": "Cpu", + "LLVM_version": "23.1.3", + "Mesa_version": "26.2.5-arch1.1", + "export_seconds": 5.195773642999939, + "strict_checker_passed": true, + "manifest_sha256": "8b168eb75057e90b19362d7c7170fb6abf8cea384e4d74196903425ea364c2ad", + "standalone_lab_sha256": "e3ba40f645c03fe0ccb7c873fda8e30e9db39ab82793929a05534df5a0530835", + "promotion_commit": "d0e863f37fc053edf9c1c6788264cc557052880f", + "catalogue_git_tree": "88b05f01146530ae4394c0353fdbbae7fffde6f8", + "PNG_hashes_changed": 480, + "PNG_hashes_identical": 0, + "sampled_pixel_comparison": { + "paired_examples": 18, + "stories": 9, + "densities": [ + 1, + 2 + ], + "palette": "dark", + "viewport": "regular", + "maximum_normalized_peak_error": 0.00784314, + "approximately_8bit_channel_steps": 2, + "manual_visual_pairs_reviewed": 4, + "visible_layout_caret_or_clipping_regression_observed": false, + "all480_decoded_pixel_parity_established": false + }, + "actual_CPU_software_export": true, + "RADV_capture_claimed": false, + "Wayland_compositor_tested_by_export": false, + "VM_native_or_physical_GPU_performance_accepted_by_export": false, + "publication_of_this_revision_verified": false, + "prior_RADV_source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9" + }, + "target_compatibility": { + "ELF_consumers_static_imports_resolve": 10, + "public_FFmpeg_headers_compared": 134, + "byte_identical_headers": 129, + "version_literal_only_differences": 5, + "all_headers_identical_after_exact_literal_normalization": true, + "header_review_status": "CONCRETE_HEADER_DIFFERENCES_COMPATIBLE_FOR_NATIVE_TRIAL", + "separate_review_status": "ELF_SYMBOL_AND_HEADER_INPUTS_REVIEWED_FOR_NATIVE_TRIAL", + "unresolved_header_or_struct_ABI": false, + "general_future_compatibility_or_native_feature_acceptance_claimed": false + }, + "deployment": { + "success": true, + "managed_user_clients_verified": 6, + "root_greeter_verified": true, + "supervised_beyond_initial_startup_deadline": true, + "user_state_preserved": true, + "secure_configuration_preserved": true, + "greetd_restarted": false, + "settings_or_theme_written": false, + "fresh_readonly_normal_proof_recorded": true, + "normal_profiling_flags_off_at_that_checkpoint": true, + "ongoing_live_session_state_guaranteed": false, + "fallback_source_commit": "b2f54551dfbe3744762e04b06cc9abcdfd167eaa", + "fallback_release_manifest_sha256": "ba2a89b036ad00fde7fca82cce9a1647ab91247e2b59a90874bf87f587fb48b2", + "scope": "Coherent candidate installation and a dated normal-state checkpoint; no new lock/login interaction, native focus fix or performance acceptance.", + "normal_checkpoint_later_retired_by_expected_Notes_cleanup": true + }, + "historical_failed_export": { + "workflow_run": 40430392734, + "workflow_head": "ac07aa5d7090c2869038f1d8001311a451c66940", + "qualification_stages_passed": 17, + "targeted_tests_passed": 880, + "required_named_regressions_passed": 94, + "workflow_conclusion": "failure", + "failure": "fresh_remote_4500MiB_admission_required_before_export", + "refused_memory_sample_recorded": false, + "export_started": false, + "release_archive_produced": false, + "cause_inferred_from_later_run": false + }, + "historical_native_b2": { + "report": "reports/measurements/lucent-cold-default-uri-b2.json", + "canonical_pointer_passed": true, + "canonical_Tab_Enter_passed": false, + "cleanup_checks_passed_each": 9, + "results_unchanged": true + }, + "pending_acceptance": { + "immediate_first_Notes_key": "failed_in_separate_V7_and_V8_native_trials", + "first_same_workspace_outside_click_and_key": "pending", + "Notes_reacquisition_and_caret_visuals": "pending", + "canonical_cold_URI_pointer_and_Tab_Enter_on_ba5": "passed_in_separate_original_canonical_native_trial", + "lock_and_login_security_regression": "ba5_native_lock_PAM_and_retained_exit_passed_login_pixels_and_other_secure_regressions_pending", + "eligible_normal_RSS_at_or_below300MiB": "pending", + "eligible_source_rate_or60FPS_and_launcher_animation": "pending", + "physical_devices_and_broader_applications": "pending" + }, + "isolated_decoder_retarget_f26_general_memory_gain_accepted": false, + "evidence_sha256": { + "hosted_import_receipt": "0607b889ccbc55d5a87c20fdc32f38eccbaddcef5cbe55ff7ba4d97ca0395044", + "coherent_deployment_receipt": "289ea9d6fe54adc8d792fd89676b0d2e4591e67a05c8f79a3afe43fb685cddbc", + "static_ELF_report": "dfb0d7e6769d9d5a0425acbd073f6c2b0015c30c3d2f219ed42ac5e3e7c8fea3", + "separate_ABI_review": "a5c28b8dd61a46cae38eabddb71d9019a5dcb7c999b8a9c9f25fe3b31ac1509a", + "concrete_header_review": "7b91d5f91ace05ab560a7f4e731c3668144224e8c1274ebd6a0ca475c2e4f5cf", + "actual_catalog_manifest": "8b168eb75057e90b19362d7c7170fb6abf8cea384e4d74196903425ea364c2ad", + "catalog_comparison": "8c2266e849e996caf3eeb37b86b58388ef1930f0bac190238b926de3371517bc", + "pre_Notes_readonly_normal_source_proof": "43fb45ff4f6172a8a923bea95ec5a37fd4d329eda4cdd9789d719a324245cafe" + }, + "privacy": { + "PIDs_boot_ids_process_births_or_addresses_published": false, + "private_paths_tokens_credentials_or_Notes_published": false + }, + "Notes_pre_input_trial": { + "status": "harness_failed_before_typing", + "failure_class": "bounded_command_failed", + "feature_checks_executed": 0, + "actual_key_attempt": false, + "restoration_checks_passed": 9, + "original_settings_source_exports_and_cursor_restored": true, + "guarded_normal_restart_and35second_supervision_verified": true, + "focus_feature_result": null, + "fresh_later_normal_proof_required_before_next_trial": true, + "scope": "A pre-input controller failure is not evidence that focus acquisition passed or failed." + }, + "later_canonical_cold_URI_trial": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "pointer_route_passed": true, + "keyboard_route_passed": true, + "trusted_nonrepeat_KeyA_events_per_case": 1, + "feature_checks_passed_per_case": 3, + "cleanup_checks_passed_per_case": 9, + "original_controller_steps_preserved": true, + "accepted_main_at_trial": false, + "scope": "One FHD virtual output and controlled real default Chromium handler. No direct token-consumption, inline-widget, secure-session, physical or performance acceptance." + }, + "later_first_Notes_key_trial": { + "report": "reports/measurements/lucent-widget-first-key-ba5.json", + "report_sha256": "a95916d4d1cb4082984475378ca27157bac68a021979b0ce4a60efc3f0582828", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "status": "corrected_native_first_key_delivery_failed", + "host_down_to_key_transport_ms": 31.62471897667274, + "Notes_logical_and_native_focus_observed_after_input": true, + "controlled_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "control_flush_candidate_native_verified": false + }, + "later_native_lock_trial": { + "report": "reports/measurements/lucent-native-lock-ba5.json", + "report_sha256": "af160b848c92e1d0a9453be672656f2b1e8f5c21e39df97db5fb078c103b9f61", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": false, + "native_lock_and_authenticated_unlock_observed": true, + "exit_status_assertion_failed": true, + "native_exit_status": null, + "later_same_runtime_files_security_and_playback_preserved": true + }, + "later_completed_click_Notes_trial": { + "report": "reports/measurements/lucent-widget-completed-click-ba5.json", + "report_sha256": "9cc6005267544dd4c8a8b33ef7741b148ef9ac949a521ea955a61d7062e34465", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "first_key_delivery_passed": false, + "gesture_contract": "completed-click-then-immediate-key", + "host_down_to_key_transport_ms": 66.63447699975222, + "Notes_logical_and_native_focus_observed_after_input": true, + "owned_browser_received_first_trusted_KeyA": true, + "Notes_insert_observed": false, + "restoration_checks_passed": 9, + "outside_click_and_reacquisition_attempted": false, + "actual_input_dispatch_timing_available": false, + "native_control_flush_fix_accepted": false, + "V7_held_button_result_unchanged": true + }, + "later_native_lock_V3_trial": { + "report": "reports/measurements/lucent-native-lock-ba5-v3.json", + "report_sha256": "c39c4a2d1b8d87935b809b95388858832b6f557132024c51806e2c18e50cd1b9", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "whole_trial_passed": true, + "checks_passed": 6, + "same_connection_new_locked_ACK_and_one_PAM_unlock": true, + "retained_same_invocation_exited_normally": true, + "exit_status": 0, + "reference_released": true, + "same_runtime_files_security_playback_idle_and_geometry_preserved": true, + "login_pixels_suspend_hardware_or_performance_accepted": false, + "V1_and_V2_failures_unchanged": true + } +} diff --git a/reports/measurements/lucent-native-lock-ba5-v3.json b/reports/measurements/lucent-native-lock-ba5-v3.json new file mode 100644 index 00000000..e2a5555f --- /dev/null +++ b/reports/measurements/lucent-native-lock-ba5-v3.json @@ -0,0 +1,91 @@ +{ + "schema_version": 1, + "status": "scoped_native_lock_PAM_and_retained_exit_regression_passed", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "native_locker_sha256": "4859c6c22ecbc62fb560e5a29ca3372b8223b2d52c14761c4b7c96b27ad8b423", + "controller_version": "V3", + "accepted_main_at_capture": false, + "whole_trial_passed": true, + "actual_private_report_sha256": "ab1f715db2ba4e2b30b0f2a93ff1f7ca717e771cf32f78547e09cbd03b5fd17b", + "controller_template_sha256": "108f8d6a15d5f187d5901494ea592331c36397e769d8ec6c97cf39258cacf991", + "actual_bound_controller_sha256": null, + "bound_controller_hash_exposed_by_trial_report": false, + "scope": "One FHD virtual output and one ordinary native lock/PAM unlock on ba5. The same notifier connection observes a new compositor Locked acknowledgement and subsequent Unlock. Six checks pass, including positive same-invocation native exit and exact normal-state preservation. Login, secure-client pixels, suspend, physical hardware and performance are not accepted.", + "checks_passed": 6, + "checks": { + "same_connection_new_locked_ack": true, + "exact_native_locker_without_fallback_or_restart": true, + "existing_live_wallpaper_pauses_without_preference_change": true, + "ordinary_PAM_unlock_and_native_exit_zero": true, + "existing_playback_policy_resumes_or_retains_manual_pause": true, + "normal_lifetime_settings_media_security_idle_and_geometry_preserved": true + }, + "ordinary_lock_requests": 1, + "private_password_helper_invocations": 1, + "notifier_events": [ + "ready_unlocked", + "locked_ack_transition", + "unlocked_transition", + "complete", + "connection_closed" + ], + "retained_native_exit": { + "one_owned_private_bus_reference_held_before_lock": true, + "same_manager_connection_and_live_invocation": true, + "same_live_and_exited_ExecMainPID": true, + "same_positive_start_timestamp": true, + "positive_exit_at_or_after_start": true, + "main_process_exited_normally": true, + "exit_status": 0, + "manager_result": "success", + "restart_count": 0, + "inactive_and_dead_after_exit": true, + "reference_released": true, + "reference_observation_count": 5, + "default_or_missing_Code0_accepted_as_exit_proof": false + }, + "preservation": { + "same_desktop_lifetime": true, + "normal_profiling_and_tracing_OFF": true, + "settings_media_exports_clipboard_and_supervision_unchanged": true, + "PAM_locker_login_security_unchanged": true, + "playback_policy_restored": true, + "idle_monitor_workspace_cursor_and_keyboard_map_unchanged": true, + "preservation_fingerprint_before_sha256": "2ce386b083cbefc51a91de5217a231c4c2ae748c73bf822b2b182f06749f510c", + "preservation_fingerprint_after_sha256": "2ce386b083cbefc51a91de5217a231c4c2ae748c73bf822b2b182f06749f510c", + "security_fingerprint_before_sha256": "68a7b7867d1af60ca515d0fec90043cff13f2d9ae77ed49be691877e1e9834e5", + "security_fingerprint_after_sha256": "68a7b7867d1af60ca515d0fec90043cff13f2d9ae77ed49be691877e1e9834e5" + }, + "intervention_scope": { + "preference_media_or_idle_writes": false, + "desktop_or_greetd_restarts": false, + "automatic_password_retry_or_forced_unlock": false, + "locker_kill_or_fallback_suppression": false, + "login_logout_or_power_request": false, + "password_output_or_images_captured": false + }, + "earlier_results_preserved": { + "V1_report": "reports/measurements/lucent-native-lock-ba5.json", + "V1_report_sha256": "af160b848c92e1d0a9453be672656f2b1e8f5c21e39df97db5fb078c103b9f61", + "V1_exit_assertion_failed_and_remains_failed": true, + "V2_private_prelock_refusal_sha256": "687ad020b97d71816e9a7e07b4d8c47fd899e20ba2b74b562c8f4833608325b6", + "V2_lock_requests": 0, + "V2_password_helper_invocations": 0, + "V2_initial_empty_ID_cause_confirmed_by_readonly_probe": true, + "V2_readonly_shape_receipt_sha256": "d76a06dacc24cb4bab7ae0c5bcc1c99992579f31700e8754c057545644150914", + "old_failures_retroactively_passed": false + }, + "not_accepted": { + "login_logout": true, + "caret_wallpaper_or_other_secure_pixels": true, + "suspend_resume": true, + "physical_device_or_driver_faults": true, + "FPS_CPU_or_memory_targets": true + }, + "privacy": { + "raw_PIDs_process_births_boot_ids_invocation_IDs_paths_or_exact_epochs_published": false, + "credentials_Notes_images_argv_or_environment_published": false + } +} diff --git a/reports/measurements/lucent-native-lock-ba5.json b/reports/measurements/lucent-native-lock-ba5.json new file mode 100644 index 00000000..d5a8bd17 --- /dev/null +++ b/reports/measurements/lucent-native-lock-ba5.json @@ -0,0 +1,49 @@ +{ + "schema_version": 1, + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "status": "native_cycle_observed_exit_status_assertion_failed", + "whole_trial_passed": false, + "failure": "native_locker_normal_exit_required", + "actual_private_trial_sha256": "2fd477bc1c101dd6fdde22307b1594000e4c8b9e0428d7dad85b8ec9449577e5", + "actual_later_readonly_receipt_sha256": "31670b13e70025babc14c13277530f8f3fa07eacdcc243d289b75fab2deb9ced", + "original_checks_passed": { + "same_connection_new_locked_ack": true, + "exact_native_locker_without_fallback_or_restart": true, + "existing_live_wallpaper_pauses_without_preference_change": true + }, + "same_connection_notifier_events": [ + "ready_unlocked", + "locked_ack_transition", + "unlocked_transition", + "complete", + "connection_closed" + ], + "ordinary_lock_requested": true, + "private_password_helper_invocations": 1, + "authenticated_unlock_observed": true, + "native_exit_status": null, + "later_systemd_properties": { + "ActiveState": "inactive", + "SubState": "dead", + "Result": "success", + "NRestarts": 0, + "ExecMainCode": "0", + "ExecMainStatus": "0" + }, + "later_readonly_preservation": { + "same_normal_runtime": true, + "unlocked_no_locker_or_fallback": true, + "fingerprint_matches_before": true, + "security_matches_before": true, + "playback_matches_before": true, + "all_tracing_OFF": true + }, + "earlier_failure_retroactively_changed": false, + "original_geometry_and_idle_baselines_saved": false, + "caret_wallpaper_pixels_login_suspend_hardware_or_performance_accepted": false, + "scope": "One FHD virtual output, ordinary lock, new compositor acknowledgement, exact native locker and one private PAM helper. Unlock and later same-runtime preservation are observed. The original exit-status assertion failed; later ExecMainCode=0 does not establish native exit status or its cause. No retry, forced unlock or locker kill.", + "privacy": { + "credentials_Notes_wallpaper_images_or_private_identifiers_published": false + } +} diff --git a/reports/measurements/lucent-widget-completed-click-ba5.json b/reports/measurements/lucent-widget-completed-click-ba5.json new file mode 100644 index 00000000..5d814d26 --- /dev/null +++ b/reports/measurements/lucent-widget-completed-click-ba5.json @@ -0,0 +1,165 @@ +{ + "schema_version": 1, + "status": "native_completed_click_first_key_delivery_failed", + "scope": "Source ba5 on one FHD virtual output. This additional case completes the physical click with separate DOWN and UP synchronizations before sending the first KeyA. Notes gains logical/native focus, but the first key reaches the owned browser; all nine restorations pass. V7 held-button failure remains unchanged. Outside-click and reacquisition are unattempted.", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "accepted_main_at_capture": false, + "actual_private_report_sha256": "f824c39bd944f9df01efa453f92a7d7f5007afb5b1d4cf9463a8009a3adb5d2e", + "actual_bound_controller_sha256": "55bc4daff1a193c236db8b163e4ee667e4dd16a23bcfe14cdfd4703affabc241", + "controller_version": "V8", + "input": { + "button_edges_have_separate_QMP_synchronizations": true, + "sequence": "Primary DOWN and separate completed UP synchronization, then immediate unmodified KeyA; no focus wait or retry.", + "host_down_transport_start_to_key_transport_start_ms": 66.63447699975222, + "host_interval_is_guest_dispatch_latency": false, + "focus_wait_sleep_retry_or_forced_focus": false, + "prepared_target_revalidated_by_final_guard": true, + "QMP_return_is_guest_delivery_acknowledgement": false, + "gesture_contract": "completed-click-then-immediate-key", + "key_sent_after_completed_click": true + }, + "native_result": { + "first_key_delivery_passed": false, + "failed_check": "first_physical_notes_key_arrived", + "Notes_insert_observed": false, + "first_key_destination": "controlled_owned_browser", + "controlled_browser_plain_trusted_nonrepeat_KeyA_count": 1, + "controlled_browser_untrusted_or_repeated_KeyA_count": 0, + "outside_click_attempted": false, + "reacquisition_attempted": false, + "caret_visuals_accepted": false, + "native_focus_fix_accepted": false + }, + "observations": [ + { + "checkpoint": "before_final_press_guard", + "Notes_logical_focus": false, + "Notes_native_group_role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_focus_is_Notes_group": false, + "observed_native_Enter_count": 0, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": true, + "browser_plain_trusted_nonrepeat_KeyA_count": 0, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + }, + { + "checkpoint": "after_key_transport", + "Notes_logical_focus": true, + "Notes_native_group_role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_focus_is_Notes_group": true, + "observed_native_Enter_count": 1, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": false, + "browser_plain_trusted_nonrepeat_KeyA_count": 1, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + }, + { + "checkpoint": "failure_before_restoration", + "Notes_logical_focus": true, + "Notes_native_group_role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_focus_is_Notes_group": true, + "observed_native_Enter_count": 1, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": false, + "browser_plain_trusted_nonrepeat_KeyA_count": 1, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + } + ], + "missing_timing_and_authority": { + "pointer_callback_timestamp": null, + "request_queue_timestamp": null, + "socket_flush_attempt_or_completion_timestamp": null, + "compositor_request_processing_timestamp": null, + "native_Enter_timestamp": null, + "native_KeyA_dispatch_timestamp": null, + "completed_typed_focus_request_outcome": null, + "exact_Enter_vs_KeyA_dispatch_order_measured": false, + "global_seat_owner_observed": false, + "scope": "Sequential SDK and owned-document checkpoints are not an atomic global input timeline. Source-specific keyboard-active and completed-outcome fields are unavailable." + }, + "restoration": { + "checks_passed": 9, + "all_passed": true, + "checks": { + "owned_browser_retired": true, + "exact_original_settings_stopped_service": true, + "normal_desktop_35s_stability": true, + "original_workspace": true, + "original_monitor": true, + "exact_wallpaper_source_exports_and_settings": true, + "original_idle_marker": true, + "owned_guest_checkpoint_removed": true, + "original_cursor": true + }, + "guarded_original_settings_wallpaper_source_exports_workspace_monitor_idle_and_cursor_restored": true, + "normal_desktop_restart_supervised_for35seconds": true, + "captured_runtime_identity_retired_by_expected_cleanup": true, + "fresh_normal_binding_required_before_later_native_trial": true + }, + "historical_transport_scope": { + "prior_V4_V5_V6_records_preserved": true, + "prior_combined_DOWN_UP_QMP_call_proves_a_pressed_USB_report": false, + "QEMU_version": "11.1.1", + "actual_USB_tablet_and_host_version_checked_by_controller_owner": true, + "source_review_sha256": "c91bfb8fd24a0875bbc809d6f3051dc52d3fd543f57b5db2a39ad6c832f0ee34", + "finding": "QMP sends the event list before one synchronization. USB HID updates one pending button bitfield, so DOWN then UP in that same call does not publish a pressed report. Earlier failed outcomes and cleanup evidence remain unchanged; actual Notes press delivery is not inferred for those cases.", + "primary_sources": [ + "https://gitlab.com/qemu-project/qemu/-/blob/v11.1.1/ui/input.c#L145-214", + "https://gitlab.com/qemu-project/qemu/-/blob/v11.1.1/hw/input/hid.c#L103-207" + ] + }, + "next_source_investigation": { + "adapter_control_flush_candidate_native_verified": false, + "transport_or_acquisition_failure_cause_established": false, + "scope": "The native control-flush candidate is not installed in this measured ba5 run and has no native first-key acceptance. Sequential checkpoints do not measure flush/server-processing timing or establish the cause. A separately built/deployed source and corrected native trial are required." + }, + "separate_accepted_workflow": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "original_canonical_pointer_and_Tab_Enter_passed": true, + "feature_checks_passed_per_case": 3, + "cleanup_checks_passed_per_case": 9, + "scope": "Controlled cold URI handoff remains accepted for its recorded source/workflow; it does not accept inline-widget first-key delivery." + }, + "privacy": { + "Notes_text_lengths_images_or_private_identifiers_published": false, + "raw_paths_profiles_credentials_argv_environment_or_exact_epochs_published": false + }, + "separate_preserved_held_button_trial": { + "report": "reports/measurements/lucent-widget-first-key-ba5.json", + "report_sha256": "a95916d4d1cb4082984475378ca27157bac68a021979b0ce4a60efc3f0582828", + "first_key_delivery_passed": false, + "host_down_to_key_transport_ms": 31.62471897667274, + "restoration_checks_passed": 9, + "result_unchanged": true + } +} diff --git a/reports/measurements/lucent-widget-first-key-ba5.json b/reports/measurements/lucent-widget-first-key-ba5.json new file mode 100644 index 00000000..e4bd849b --- /dev/null +++ b/reports/measurements/lucent-widget-first-key-ba5.json @@ -0,0 +1,156 @@ +{ + "schema_version": 1, + "status": "native_first_key_delivery_failed_after_corrected_pointer_transport", + "scope": "Source ba5 on one 1920x1080 scale-1 virtual output. Corrected V7 pointer transport reaches Notes logical/native focus, but the first KeyA reaches the owned browser and Notes remains unchanged. All nine restoration checks pass. Outside-click and reacquisition are not attempted.", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", + "manifest_sha256": "0e1291f46312057a6c9b349148868ad770b9b07c848fdd901ca4b01e32050b4d", + "desktop_sha256": "633960b90c1d08b84e4b53c85e3ccf9e63b1e091a8ab6f6b2a406296c4b916a5", + "accepted_main_at_capture": false, + "actual_private_report_sha256": "f3fd21137d271b93d48be941e6a5b366862e5fef56a4a5ce3c9b00db7d3b420d", + "actual_bound_controller_sha256": "8b9a0670f6400491d53af771e4f92f45f442bbd6fd3ab07f7eb10a745c6eb892", + "controller_version": "V7", + "input": { + "button_edges_have_separate_QMP_synchronizations": true, + "sequence": "Primary DOWN, immediate unmodified KeyA, balanced UP in finally before diagnostic reads.", + "host_down_transport_start_to_key_transport_start_ms": 31.62471897667274, + "host_interval_is_guest_dispatch_latency": false, + "focus_wait_sleep_retry_or_forced_focus": false, + "prepared_target_revalidated_by_final_guard": true, + "QMP_return_is_guest_delivery_acknowledgement": false + }, + "native_result": { + "first_key_delivery_passed": false, + "failed_check": "first_physical_notes_key_arrived", + "Notes_insert_observed": false, + "first_key_destination": "controlled_owned_browser", + "controlled_browser_plain_trusted_nonrepeat_KeyA_count": 1, + "controlled_browser_untrusted_or_repeated_KeyA_count": 0, + "outside_click_attempted": false, + "reacquisition_attempted": false, + "caret_visuals_accepted": false, + "native_focus_fix_accepted": false + }, + "observations": [ + { + "checkpoint": "before_final_press_guard", + "Notes_logical_focus": false, + "Notes_native_group_role": "calendar", + "requested_keyboard": "none", + "committed_keyboard": "none", + "actual_native_focus_is_Notes_group": false, + "observed_native_Enter_count": 0, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": true, + "browser_plain_trusted_nonrepeat_KeyA_count": 0, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + }, + { + "checkpoint": "after_key_transport", + "Notes_logical_focus": true, + "Notes_native_group_role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_focus_is_Notes_group": true, + "observed_native_Enter_count": 1, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": false, + "browser_plain_trusted_nonrepeat_KeyA_count": 1, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + }, + { + "checkpoint": "failure_before_restoration", + "Notes_logical_focus": true, + "Notes_native_group_role": "calendar", + "requested_keyboard": "on-demand", + "committed_keyboard": "on-demand", + "actual_native_focus_is_Notes_group": true, + "observed_native_Enter_count": 1, + "observed_native_Leave_count": 0, + "request_pending": false, + "completed_request_outcome": null, + "keyboard_active": null, + "browser_document_has_focus": false, + "browser_plain_trusted_nonrepeat_KeyA_count": 1, + "browser_trusted_pointerdown_count": 0, + "browser_trusted_pointerup_count": 0, + "browser_trusted_click_count": 0, + "Notes_insert_observed": false, + "classified_client_focus_error": null + } + ], + "missing_timing_and_authority": { + "pointer_callback_timestamp": null, + "request_queue_timestamp": null, + "socket_flush_attempt_or_completion_timestamp": null, + "compositor_request_processing_timestamp": null, + "native_Enter_timestamp": null, + "native_KeyA_dispatch_timestamp": null, + "completed_typed_focus_request_outcome": null, + "exact_Enter_vs_KeyA_dispatch_order_measured": false, + "global_seat_owner_observed": false, + "scope": "Sequential SDK and owned-document checkpoints are not an atomic global input timeline. Source-specific keyboard-active and completed-outcome fields are unavailable." + }, + "restoration": { + "checks_passed": 9, + "all_passed": true, + "checks": { + "owned_browser_retired": true, + "exact_original_settings_stopped_service": true, + "normal_desktop_35s_stability": true, + "original_workspace": true, + "original_monitor": true, + "exact_wallpaper_source_exports_and_settings": true, + "original_idle_marker": true, + "owned_guest_checkpoint_removed": true, + "original_cursor": true + }, + "guarded_original_settings_wallpaper_source_exports_workspace_monitor_idle_and_cursor_restored": true, + "normal_desktop_restart_supervised_for35seconds": true, + "captured_runtime_identity_retired_by_expected_cleanup": true, + "fresh_normal_binding_required_before_later_native_trial": true + }, + "historical_transport_scope": { + "prior_V4_V5_V6_records_preserved": true, + "prior_combined_DOWN_UP_QMP_call_proves_a_pressed_USB_report": false, + "QEMU_version": "11.1.1", + "actual_USB_tablet_and_host_version_checked_by_controller_owner": true, + "source_review_sha256": "c91bfb8fd24a0875bbc809d6f3051dc52d3fd543f57b5db2a39ad6c832f0ee34", + "finding": "QMP sends the event list before one synchronization. USB HID updates one pending button bitfield, so DOWN then UP in that same call does not publish a pressed report. Earlier failed outcomes and cleanup evidence remain unchanged; actual Notes press delivery is not inferred for those cases.", + "primary_sources": [ + "https://gitlab.com/qemu-project/qemu/-/blob/v11.1.1/ui/input.c#L145-214", + "https://gitlab.com/qemu-project/qemu/-/blob/v11.1.1/hw/input/hid.c#L103-207" + ] + }, + "next_source_investigation": { + "adapter_control_flush_candidate_native_verified": false, + "transport_or_acquisition_failure_cause_established": false, + "scope": "The generic native adapter queues an ordered role/grab transaction and normally flushes after pending callbacks. A proposed nonblocking flush is scheduling work, not evidence of a first-key fix or a focus grant. A new compiled runtime and corrected native trial are required." + }, + "separate_accepted_workflow": { + "report": "reports/measurements/lucent-cold-default-uri-ba5.json", + "report_sha256": "4b3fe0b80081ee8421f9a9f7aa248a161c4846c842cfa519375833bac0d76ad3", + "original_canonical_pointer_and_Tab_Enter_passed": true, + "feature_checks_passed_per_case": 3, + "cleanup_checks_passed_per_case": 9, + "scope": "Controlled cold URI handoff remains accepted for its recorded source/workflow; it does not accept inline-widget first-key delivery." + }, + "privacy": { + "Notes_text_lengths_or_images_published": false, + "PIDs_process_births_boot_ids_native_addresses_or_tokens_published": false, + "private_paths_profiles_credentials_argv_or_environment_published": false + } +} diff --git a/reports/measurements/lucent-widget-input-order-d77.json b/reports/measurements/lucent-widget-input-order-d77.json new file mode 100644 index 00000000..c0d5d90f --- /dev/null +++ b/reports/measurements/lucent-widget-input-order-d77.json @@ -0,0 +1,70 @@ +{ + "schema_version": 1, + "source_commit": "d77f3d0b2cafbd1fd4fcecc02e27844c5583b2cb", + "status": "diagnostic_guest_key_preceded_outside_mouse_and_pointer_transition_failed", + "scope": "Preserved V9 completed-click host gesture, now with the finite exact-VM event observer. First Notes input/undo passes. The outside step is not a valid click-before-key focus test: guest KeyA precedes the tablet press, and the cursor remains at the earlier Notes point instead of reaching the owned browser. No focus fix or causal result is accepted.", + "private_report_sha256": "bae16ae6864531ad5ec2bacee811a9c03c9f42e52dbc128c97e99288edca46ef", + "closed_private_trace_sha256": "f47736b47f3ca229670ce7dae733177313439266b9b262affbf54cdf7d2a0bf4", + "observer": { + "both_bound_VM_devices_only": true, + "clock": "per-client CLOCK_MONOTONIC; actual ioctls and timestamps checked", + "READY_then_finished": true, + "end_reason": "deadline", + "whitelisted_edges": 8, + "balanced_edges": true, + "incomplete_packet": false, + "kernel_drop_reported": false, + "all_owned_input_FDs_closed": true, + "native_focus_accepted": false, + "read_sequence_is_global_chronology": false, + "compositor_dispatch_order_observed": false + }, + "first_Notes_case": { + "left_DOWN_relative_ms": 0, + "left_UP_relative_ms": 0.977, + "KeyA_DOWN_relative_ms": 33.278, + "host_DOWN_to_key_transport_ms": 57.69790802150965, + "first_key_and_ordinary_undo_passed": true + }, + "outside_case": { + "guest_KeyA_MINUS_button_DOWN_ms": -4.332, + "guest_KeyA_preceded_button_DOWN": true, + "host_sent_completed_click_before_key": true, + "prepared_browser_target_reached": false, + "cursor_remained_at_prior_owned_Notes_point": true, + "browser_trusted_pointerdown_up_click_each": 0, + "first_key_reached_Notes": true, + "failed_check": "application_cursor_transition_not_confirmed", + "reacquisition_attempted": false + }, + "restoration": { + "checks": { + "owned_browser_retired": true, + "exact_original_settings_stopped_service": true, + "normal_desktop_35s_stability": true, + "original_workspace": true, + "original_monitor": true, + "exact_wallpaper_source_exports_and_settings": true, + "original_idle_marker": true, + "owned_guest_checkpoint_removed": true, + "original_cursor": false + }, + "passed": 8, + "total": 9, + "original_cursor_restored": false, + "all_other_recorded_restoration_passed": true, + "normal_restart_supervised35seconds": true, + "later_readonly_source_birth_check_passed": true, + "original_cursor_not_persisted_by_this_harness": true, + "later_recovery_claimed": false + }, + "interpretation": [ + "Host QMP completion is not guest delivery acknowledgement. For this outside step the guest keyboard packet precedes both tablet button packets; the key reaching Notes does not establish an incorrect Lucent focus handoff.", + "The pointer-target failure is separate. Mixing compositor cursor warps with absolute emulated tablet input is under source review; the A/button-only trace cannot prove the absolute-coordinate cause.", + "Earlier V7/V8/V9 failures retain their original observations and restoration flags. Their guest order was not measured and is not inferred from this later run.", + "A corrected transport must establish the actual intended pointer target and guest click/key ordering. A delivery acknowledgement is distinct from waiting for application focus; any new gesture and measured interval must be reported explicitly." + ], + "privacy": { + "exact_timestamps_device_paths_process_ids_credentials_argv_environment_Notes_and_images_published": false + } +} diff --git a/site/public/component-lab/images/buttons-dark-default-narrow-1x.png b/site/public/component-lab/images/buttons-dark-default-narrow-1x.png index d41add20..beb25132 100644 Binary files a/site/public/component-lab/images/buttons-dark-default-narrow-1x.png and b/site/public/component-lab/images/buttons-dark-default-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-default-narrow-2x.png b/site/public/component-lab/images/buttons-dark-default-narrow-2x.png index e76c210d..bc4fa6d2 100644 Binary files a/site/public/component-lab/images/buttons-dark-default-narrow-2x.png and b/site/public/component-lab/images/buttons-dark-default-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-default-regular-1x.png b/site/public/component-lab/images/buttons-dark-default-regular-1x.png index a99d33ab..4c6da104 100644 Binary files a/site/public/component-lab/images/buttons-dark-default-regular-1x.png and b/site/public/component-lab/images/buttons-dark-default-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-default-regular-2x.png b/site/public/component-lab/images/buttons-dark-default-regular-2x.png index 05913a76..a3aa139c 100644 Binary files a/site/public/component-lab/images/buttons-dark-default-regular-2x.png and b/site/public/component-lab/images/buttons-dark-default-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-disabled-narrow-1x.png b/site/public/component-lab/images/buttons-dark-disabled-narrow-1x.png index fc1e17f4..9c15e3e7 100644 Binary files a/site/public/component-lab/images/buttons-dark-disabled-narrow-1x.png and b/site/public/component-lab/images/buttons-dark-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-disabled-narrow-2x.png b/site/public/component-lab/images/buttons-dark-disabled-narrow-2x.png index 18950995..8b3c5eb4 100644 Binary files a/site/public/component-lab/images/buttons-dark-disabled-narrow-2x.png and b/site/public/component-lab/images/buttons-dark-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-disabled-regular-1x.png b/site/public/component-lab/images/buttons-dark-disabled-regular-1x.png index a66f14f9..bea63520 100644 Binary files a/site/public/component-lab/images/buttons-dark-disabled-regular-1x.png and b/site/public/component-lab/images/buttons-dark-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-disabled-regular-2x.png b/site/public/component-lab/images/buttons-dark-disabled-regular-2x.png index 8863c1e2..4ae01371 100644 Binary files a/site/public/component-lab/images/buttons-dark-disabled-regular-2x.png and b/site/public/component-lab/images/buttons-dark-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-focus-narrow-1x.png b/site/public/component-lab/images/buttons-dark-focus-narrow-1x.png index 6b4e607b..8468621b 100644 Binary files a/site/public/component-lab/images/buttons-dark-focus-narrow-1x.png and b/site/public/component-lab/images/buttons-dark-focus-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-focus-narrow-2x.png b/site/public/component-lab/images/buttons-dark-focus-narrow-2x.png index 8286e0ae..cfd357b2 100644 Binary files a/site/public/component-lab/images/buttons-dark-focus-narrow-2x.png and b/site/public/component-lab/images/buttons-dark-focus-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-focus-regular-1x.png b/site/public/component-lab/images/buttons-dark-focus-regular-1x.png index 7994cf02..fa12038e 100644 Binary files a/site/public/component-lab/images/buttons-dark-focus-regular-1x.png and b/site/public/component-lab/images/buttons-dark-focus-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-focus-regular-2x.png b/site/public/component-lab/images/buttons-dark-focus-regular-2x.png index ee58d354..1bdf62fa 100644 Binary files a/site/public/component-lab/images/buttons-dark-focus-regular-2x.png and b/site/public/component-lab/images/buttons-dark-focus-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-hover-narrow-1x.png b/site/public/component-lab/images/buttons-dark-hover-narrow-1x.png index 68a71773..c5ae6995 100644 Binary files a/site/public/component-lab/images/buttons-dark-hover-narrow-1x.png and b/site/public/component-lab/images/buttons-dark-hover-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-hover-narrow-2x.png b/site/public/component-lab/images/buttons-dark-hover-narrow-2x.png index c2181bd2..ec3ff928 100644 Binary files a/site/public/component-lab/images/buttons-dark-hover-narrow-2x.png and b/site/public/component-lab/images/buttons-dark-hover-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-dark-hover-regular-1x.png b/site/public/component-lab/images/buttons-dark-hover-regular-1x.png index 015a3fe5..2ae612a0 100644 Binary files a/site/public/component-lab/images/buttons-dark-hover-regular-1x.png and b/site/public/component-lab/images/buttons-dark-hover-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-dark-hover-regular-2x.png b/site/public/component-lab/images/buttons-dark-hover-regular-2x.png index 45095515..9472aa20 100644 Binary files a/site/public/component-lab/images/buttons-dark-hover-regular-2x.png and b/site/public/component-lab/images/buttons-dark-hover-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-default-narrow-1x.png b/site/public/component-lab/images/buttons-ember-default-narrow-1x.png index c6f2e11e..22c40551 100644 Binary files a/site/public/component-lab/images/buttons-ember-default-narrow-1x.png and b/site/public/component-lab/images/buttons-ember-default-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-default-narrow-2x.png b/site/public/component-lab/images/buttons-ember-default-narrow-2x.png index e8360a15..b03aca56 100644 Binary files a/site/public/component-lab/images/buttons-ember-default-narrow-2x.png and b/site/public/component-lab/images/buttons-ember-default-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-default-regular-1x.png b/site/public/component-lab/images/buttons-ember-default-regular-1x.png index 865d9e74..22f2d6ca 100644 Binary files a/site/public/component-lab/images/buttons-ember-default-regular-1x.png and b/site/public/component-lab/images/buttons-ember-default-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-default-regular-2x.png b/site/public/component-lab/images/buttons-ember-default-regular-2x.png index 2b953215..e15dfbce 100644 Binary files a/site/public/component-lab/images/buttons-ember-default-regular-2x.png and b/site/public/component-lab/images/buttons-ember-default-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-disabled-narrow-1x.png b/site/public/component-lab/images/buttons-ember-disabled-narrow-1x.png index 82695ca5..3c194958 100644 Binary files a/site/public/component-lab/images/buttons-ember-disabled-narrow-1x.png and b/site/public/component-lab/images/buttons-ember-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-disabled-narrow-2x.png b/site/public/component-lab/images/buttons-ember-disabled-narrow-2x.png index 24b13153..a9c9057c 100644 Binary files a/site/public/component-lab/images/buttons-ember-disabled-narrow-2x.png and b/site/public/component-lab/images/buttons-ember-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-disabled-regular-1x.png b/site/public/component-lab/images/buttons-ember-disabled-regular-1x.png index f8f67a8e..f3b9d555 100644 Binary files a/site/public/component-lab/images/buttons-ember-disabled-regular-1x.png and b/site/public/component-lab/images/buttons-ember-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-disabled-regular-2x.png b/site/public/component-lab/images/buttons-ember-disabled-regular-2x.png index 073955c8..b8b4419f 100644 Binary files a/site/public/component-lab/images/buttons-ember-disabled-regular-2x.png and b/site/public/component-lab/images/buttons-ember-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-focus-narrow-1x.png b/site/public/component-lab/images/buttons-ember-focus-narrow-1x.png index 3f21917b..2d681ae5 100644 Binary files a/site/public/component-lab/images/buttons-ember-focus-narrow-1x.png and b/site/public/component-lab/images/buttons-ember-focus-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-focus-narrow-2x.png b/site/public/component-lab/images/buttons-ember-focus-narrow-2x.png index ffb73b27..7c37e21d 100644 Binary files a/site/public/component-lab/images/buttons-ember-focus-narrow-2x.png and b/site/public/component-lab/images/buttons-ember-focus-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-focus-regular-1x.png b/site/public/component-lab/images/buttons-ember-focus-regular-1x.png index 9a833d5e..88e9ff0f 100644 Binary files a/site/public/component-lab/images/buttons-ember-focus-regular-1x.png and b/site/public/component-lab/images/buttons-ember-focus-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-focus-regular-2x.png b/site/public/component-lab/images/buttons-ember-focus-regular-2x.png index 8f4a14d5..8787105c 100644 Binary files a/site/public/component-lab/images/buttons-ember-focus-regular-2x.png and b/site/public/component-lab/images/buttons-ember-focus-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-hover-narrow-1x.png b/site/public/component-lab/images/buttons-ember-hover-narrow-1x.png index cf3539e0..b69ed60f 100644 Binary files a/site/public/component-lab/images/buttons-ember-hover-narrow-1x.png and b/site/public/component-lab/images/buttons-ember-hover-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-hover-narrow-2x.png b/site/public/component-lab/images/buttons-ember-hover-narrow-2x.png index 0f965cb9..79e4326f 100644 Binary files a/site/public/component-lab/images/buttons-ember-hover-narrow-2x.png and b/site/public/component-lab/images/buttons-ember-hover-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ember-hover-regular-1x.png b/site/public/component-lab/images/buttons-ember-hover-regular-1x.png index dfaa29fb..a39d115e 100644 Binary files a/site/public/component-lab/images/buttons-ember-hover-regular-1x.png and b/site/public/component-lab/images/buttons-ember-hover-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ember-hover-regular-2x.png b/site/public/component-lab/images/buttons-ember-hover-regular-2x.png index 8068bb61..ec599c0a 100644 Binary files a/site/public/component-lab/images/buttons-ember-hover-regular-2x.png and b/site/public/component-lab/images/buttons-ember-hover-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-default-narrow-1x.png b/site/public/component-lab/images/buttons-forest-default-narrow-1x.png index 38b5281d..4e7b8f8f 100644 Binary files a/site/public/component-lab/images/buttons-forest-default-narrow-1x.png and b/site/public/component-lab/images/buttons-forest-default-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-default-narrow-2x.png b/site/public/component-lab/images/buttons-forest-default-narrow-2x.png index 5ad684a1..1d808858 100644 Binary files a/site/public/component-lab/images/buttons-forest-default-narrow-2x.png and b/site/public/component-lab/images/buttons-forest-default-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-default-regular-1x.png b/site/public/component-lab/images/buttons-forest-default-regular-1x.png index b74d8bbf..d63e8790 100644 Binary files a/site/public/component-lab/images/buttons-forest-default-regular-1x.png and b/site/public/component-lab/images/buttons-forest-default-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-default-regular-2x.png b/site/public/component-lab/images/buttons-forest-default-regular-2x.png index 1857ed76..88c8a350 100644 Binary files a/site/public/component-lab/images/buttons-forest-default-regular-2x.png and b/site/public/component-lab/images/buttons-forest-default-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-disabled-narrow-1x.png b/site/public/component-lab/images/buttons-forest-disabled-narrow-1x.png index 8bfd0fd8..80ee0d78 100644 Binary files a/site/public/component-lab/images/buttons-forest-disabled-narrow-1x.png and b/site/public/component-lab/images/buttons-forest-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-disabled-narrow-2x.png b/site/public/component-lab/images/buttons-forest-disabled-narrow-2x.png index a639c34a..fbfcf8d3 100644 Binary files a/site/public/component-lab/images/buttons-forest-disabled-narrow-2x.png and b/site/public/component-lab/images/buttons-forest-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-disabled-regular-1x.png b/site/public/component-lab/images/buttons-forest-disabled-regular-1x.png index 37391dab..e07846a5 100644 Binary files a/site/public/component-lab/images/buttons-forest-disabled-regular-1x.png and b/site/public/component-lab/images/buttons-forest-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-disabled-regular-2x.png b/site/public/component-lab/images/buttons-forest-disabled-regular-2x.png index ed4f8404..28b1d10e 100644 Binary files a/site/public/component-lab/images/buttons-forest-disabled-regular-2x.png and b/site/public/component-lab/images/buttons-forest-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-focus-narrow-1x.png b/site/public/component-lab/images/buttons-forest-focus-narrow-1x.png index b9083f0c..f9e5d1ee 100644 Binary files a/site/public/component-lab/images/buttons-forest-focus-narrow-1x.png and b/site/public/component-lab/images/buttons-forest-focus-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-focus-narrow-2x.png b/site/public/component-lab/images/buttons-forest-focus-narrow-2x.png index 28b75441..63d2bf98 100644 Binary files a/site/public/component-lab/images/buttons-forest-focus-narrow-2x.png and b/site/public/component-lab/images/buttons-forest-focus-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-focus-regular-1x.png b/site/public/component-lab/images/buttons-forest-focus-regular-1x.png index edbfa5ef..276ef5ed 100644 Binary files a/site/public/component-lab/images/buttons-forest-focus-regular-1x.png and b/site/public/component-lab/images/buttons-forest-focus-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-focus-regular-2x.png b/site/public/component-lab/images/buttons-forest-focus-regular-2x.png index 6668731e..5d13474c 100644 Binary files a/site/public/component-lab/images/buttons-forest-focus-regular-2x.png and b/site/public/component-lab/images/buttons-forest-focus-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-hover-narrow-1x.png b/site/public/component-lab/images/buttons-forest-hover-narrow-1x.png index 29bce832..8f0c6106 100644 Binary files a/site/public/component-lab/images/buttons-forest-hover-narrow-1x.png and b/site/public/component-lab/images/buttons-forest-hover-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-hover-narrow-2x.png b/site/public/component-lab/images/buttons-forest-hover-narrow-2x.png index a57d79d7..cb57b078 100644 Binary files a/site/public/component-lab/images/buttons-forest-hover-narrow-2x.png and b/site/public/component-lab/images/buttons-forest-hover-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-forest-hover-regular-1x.png b/site/public/component-lab/images/buttons-forest-hover-regular-1x.png index f6c88271..0b51a915 100644 Binary files a/site/public/component-lab/images/buttons-forest-hover-regular-1x.png and b/site/public/component-lab/images/buttons-forest-hover-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-forest-hover-regular-2x.png b/site/public/component-lab/images/buttons-forest-hover-regular-2x.png index fe7aa3f2..a84bf7a0 100644 Binary files a/site/public/component-lab/images/buttons-forest-hover-regular-2x.png and b/site/public/component-lab/images/buttons-forest-hover-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-default-narrow-1x.png b/site/public/component-lab/images/buttons-light-default-narrow-1x.png index dc532ecf..da9b9ce6 100644 Binary files a/site/public/component-lab/images/buttons-light-default-narrow-1x.png and b/site/public/component-lab/images/buttons-light-default-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-default-narrow-2x.png b/site/public/component-lab/images/buttons-light-default-narrow-2x.png index fb45a64a..6d772d40 100644 Binary files a/site/public/component-lab/images/buttons-light-default-narrow-2x.png and b/site/public/component-lab/images/buttons-light-default-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-default-regular-1x.png b/site/public/component-lab/images/buttons-light-default-regular-1x.png index 8ed306f7..3b2d642a 100644 Binary files a/site/public/component-lab/images/buttons-light-default-regular-1x.png and b/site/public/component-lab/images/buttons-light-default-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-default-regular-2x.png b/site/public/component-lab/images/buttons-light-default-regular-2x.png index 2c45533d..49463b86 100644 Binary files a/site/public/component-lab/images/buttons-light-default-regular-2x.png and b/site/public/component-lab/images/buttons-light-default-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-disabled-narrow-1x.png b/site/public/component-lab/images/buttons-light-disabled-narrow-1x.png index 912391e2..dc0329b4 100644 Binary files a/site/public/component-lab/images/buttons-light-disabled-narrow-1x.png and b/site/public/component-lab/images/buttons-light-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-disabled-narrow-2x.png b/site/public/component-lab/images/buttons-light-disabled-narrow-2x.png index 3e17e9bd..7a1394de 100644 Binary files a/site/public/component-lab/images/buttons-light-disabled-narrow-2x.png and b/site/public/component-lab/images/buttons-light-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-disabled-regular-1x.png b/site/public/component-lab/images/buttons-light-disabled-regular-1x.png index fd2af047..2a2e5ac2 100644 Binary files a/site/public/component-lab/images/buttons-light-disabled-regular-1x.png and b/site/public/component-lab/images/buttons-light-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-disabled-regular-2x.png b/site/public/component-lab/images/buttons-light-disabled-regular-2x.png index bd332818..66967428 100644 Binary files a/site/public/component-lab/images/buttons-light-disabled-regular-2x.png and b/site/public/component-lab/images/buttons-light-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-focus-narrow-1x.png b/site/public/component-lab/images/buttons-light-focus-narrow-1x.png index a6b23671..2e6ed168 100644 Binary files a/site/public/component-lab/images/buttons-light-focus-narrow-1x.png and b/site/public/component-lab/images/buttons-light-focus-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-focus-narrow-2x.png b/site/public/component-lab/images/buttons-light-focus-narrow-2x.png index ad65d084..542c5d92 100644 Binary files a/site/public/component-lab/images/buttons-light-focus-narrow-2x.png and b/site/public/component-lab/images/buttons-light-focus-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-focus-regular-1x.png b/site/public/component-lab/images/buttons-light-focus-regular-1x.png index 83059e08..5654c4ba 100644 Binary files a/site/public/component-lab/images/buttons-light-focus-regular-1x.png and b/site/public/component-lab/images/buttons-light-focus-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-focus-regular-2x.png b/site/public/component-lab/images/buttons-light-focus-regular-2x.png index 68985a86..a56ddfb5 100644 Binary files a/site/public/component-lab/images/buttons-light-focus-regular-2x.png and b/site/public/component-lab/images/buttons-light-focus-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-hover-narrow-1x.png b/site/public/component-lab/images/buttons-light-hover-narrow-1x.png index b10e7db8..c72673bb 100644 Binary files a/site/public/component-lab/images/buttons-light-hover-narrow-1x.png and b/site/public/component-lab/images/buttons-light-hover-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-hover-narrow-2x.png b/site/public/component-lab/images/buttons-light-hover-narrow-2x.png index 38dbd438..92292799 100644 Binary files a/site/public/component-lab/images/buttons-light-hover-narrow-2x.png and b/site/public/component-lab/images/buttons-light-hover-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-light-hover-regular-1x.png b/site/public/component-lab/images/buttons-light-hover-regular-1x.png index 830a9b58..117e0d23 100644 Binary files a/site/public/component-lab/images/buttons-light-hover-regular-1x.png and b/site/public/component-lab/images/buttons-light-hover-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-light-hover-regular-2x.png b/site/public/component-lab/images/buttons-light-hover-regular-2x.png index 2cc6da50..c7810264 100644 Binary files a/site/public/component-lab/images/buttons-light-hover-regular-2x.png and b/site/public/component-lab/images/buttons-light-hover-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-default-narrow-1x.png b/site/public/component-lab/images/buttons-ocean-default-narrow-1x.png index a4387450..e690aa7a 100644 Binary files a/site/public/component-lab/images/buttons-ocean-default-narrow-1x.png and b/site/public/component-lab/images/buttons-ocean-default-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-default-narrow-2x.png b/site/public/component-lab/images/buttons-ocean-default-narrow-2x.png index 0a711bd3..02a37207 100644 Binary files a/site/public/component-lab/images/buttons-ocean-default-narrow-2x.png and b/site/public/component-lab/images/buttons-ocean-default-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-default-regular-1x.png b/site/public/component-lab/images/buttons-ocean-default-regular-1x.png index bad20609..c7885448 100644 Binary files a/site/public/component-lab/images/buttons-ocean-default-regular-1x.png and b/site/public/component-lab/images/buttons-ocean-default-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-default-regular-2x.png b/site/public/component-lab/images/buttons-ocean-default-regular-2x.png index 2c64fbc5..a815658b 100644 Binary files a/site/public/component-lab/images/buttons-ocean-default-regular-2x.png and b/site/public/component-lab/images/buttons-ocean-default-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-disabled-narrow-1x.png b/site/public/component-lab/images/buttons-ocean-disabled-narrow-1x.png index 0d7be1c9..b00d121b 100644 Binary files a/site/public/component-lab/images/buttons-ocean-disabled-narrow-1x.png and b/site/public/component-lab/images/buttons-ocean-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-disabled-narrow-2x.png b/site/public/component-lab/images/buttons-ocean-disabled-narrow-2x.png index 10861f14..f53d4600 100644 Binary files a/site/public/component-lab/images/buttons-ocean-disabled-narrow-2x.png and b/site/public/component-lab/images/buttons-ocean-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-disabled-regular-1x.png b/site/public/component-lab/images/buttons-ocean-disabled-regular-1x.png index 05f95108..4a2b5f28 100644 Binary files a/site/public/component-lab/images/buttons-ocean-disabled-regular-1x.png and b/site/public/component-lab/images/buttons-ocean-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-disabled-regular-2x.png b/site/public/component-lab/images/buttons-ocean-disabled-regular-2x.png index b6afa265..ec9e2dda 100644 Binary files a/site/public/component-lab/images/buttons-ocean-disabled-regular-2x.png and b/site/public/component-lab/images/buttons-ocean-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-focus-narrow-1x.png b/site/public/component-lab/images/buttons-ocean-focus-narrow-1x.png index 8c5c2488..65be6919 100644 Binary files a/site/public/component-lab/images/buttons-ocean-focus-narrow-1x.png and b/site/public/component-lab/images/buttons-ocean-focus-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-focus-narrow-2x.png b/site/public/component-lab/images/buttons-ocean-focus-narrow-2x.png index e6f54ca8..d39c0ff3 100644 Binary files a/site/public/component-lab/images/buttons-ocean-focus-narrow-2x.png and b/site/public/component-lab/images/buttons-ocean-focus-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-focus-regular-1x.png b/site/public/component-lab/images/buttons-ocean-focus-regular-1x.png index d6112f63..f6edacae 100644 Binary files a/site/public/component-lab/images/buttons-ocean-focus-regular-1x.png and b/site/public/component-lab/images/buttons-ocean-focus-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-focus-regular-2x.png b/site/public/component-lab/images/buttons-ocean-focus-regular-2x.png index 437d3fdb..a034349d 100644 Binary files a/site/public/component-lab/images/buttons-ocean-focus-regular-2x.png and b/site/public/component-lab/images/buttons-ocean-focus-regular-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-hover-narrow-1x.png b/site/public/component-lab/images/buttons-ocean-hover-narrow-1x.png index c90c7b21..ca2d880c 100644 Binary files a/site/public/component-lab/images/buttons-ocean-hover-narrow-1x.png and b/site/public/component-lab/images/buttons-ocean-hover-narrow-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-hover-narrow-2x.png b/site/public/component-lab/images/buttons-ocean-hover-narrow-2x.png index 9992cff9..2f06cb89 100644 Binary files a/site/public/component-lab/images/buttons-ocean-hover-narrow-2x.png and b/site/public/component-lab/images/buttons-ocean-hover-narrow-2x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-hover-regular-1x.png b/site/public/component-lab/images/buttons-ocean-hover-regular-1x.png index 8f6684d4..89f67a30 100644 Binary files a/site/public/component-lab/images/buttons-ocean-hover-regular-1x.png and b/site/public/component-lab/images/buttons-ocean-hover-regular-1x.png differ diff --git a/site/public/component-lab/images/buttons-ocean-hover-regular-2x.png b/site/public/component-lab/images/buttons-ocean-hover-regular-2x.png index 59ff9e41..c0db4a7b 100644 Binary files a/site/public/component-lab/images/buttons-ocean-hover-regular-2x.png and b/site/public/component-lab/images/buttons-ocean-hover-regular-2x.png differ diff --git a/site/public/component-lab/images/input-dark-empty-narrow-1x.png b/site/public/component-lab/images/input-dark-empty-narrow-1x.png index 1336baa9..bb53a9fc 100644 Binary files a/site/public/component-lab/images/input-dark-empty-narrow-1x.png and b/site/public/component-lab/images/input-dark-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-dark-empty-narrow-2x.png b/site/public/component-lab/images/input-dark-empty-narrow-2x.png index 65509c77..436f8049 100644 Binary files a/site/public/component-lab/images/input-dark-empty-narrow-2x.png and b/site/public/component-lab/images/input-dark-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-dark-empty-regular-1x.png b/site/public/component-lab/images/input-dark-empty-regular-1x.png index 0069ed69..d5035490 100644 Binary files a/site/public/component-lab/images/input-dark-empty-regular-1x.png and b/site/public/component-lab/images/input-dark-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-dark-empty-regular-2x.png b/site/public/component-lab/images/input-dark-empty-regular-2x.png index 1fff52cb..ac8e8370 100644 Binary files a/site/public/component-lab/images/input-dark-empty-regular-2x.png and b/site/public/component-lab/images/input-dark-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-dark-error-narrow-1x.png b/site/public/component-lab/images/input-dark-error-narrow-1x.png index 91abf5d2..83548d5d 100644 Binary files a/site/public/component-lab/images/input-dark-error-narrow-1x.png and b/site/public/component-lab/images/input-dark-error-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-dark-error-narrow-2x.png b/site/public/component-lab/images/input-dark-error-narrow-2x.png index b13f28f7..697f5910 100644 Binary files a/site/public/component-lab/images/input-dark-error-narrow-2x.png and b/site/public/component-lab/images/input-dark-error-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-dark-error-regular-1x.png b/site/public/component-lab/images/input-dark-error-regular-1x.png index b52b0bca..e9ad0cc3 100644 Binary files a/site/public/component-lab/images/input-dark-error-regular-1x.png and b/site/public/component-lab/images/input-dark-error-regular-1x.png differ diff --git a/site/public/component-lab/images/input-dark-error-regular-2x.png b/site/public/component-lab/images/input-dark-error-regular-2x.png index 7d3ec946..5b4e502f 100644 Binary files a/site/public/component-lab/images/input-dark-error-regular-2x.png and b/site/public/component-lab/images/input-dark-error-regular-2x.png differ diff --git a/site/public/component-lab/images/input-dark-filled-narrow-1x.png b/site/public/component-lab/images/input-dark-filled-narrow-1x.png index a3e9a840..26f623f1 100644 Binary files a/site/public/component-lab/images/input-dark-filled-narrow-1x.png and b/site/public/component-lab/images/input-dark-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-dark-filled-narrow-2x.png b/site/public/component-lab/images/input-dark-filled-narrow-2x.png index 829ea354..1714a36a 100644 Binary files a/site/public/component-lab/images/input-dark-filled-narrow-2x.png and b/site/public/component-lab/images/input-dark-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-dark-filled-regular-1x.png b/site/public/component-lab/images/input-dark-filled-regular-1x.png index 73cd97fc..f36d384e 100644 Binary files a/site/public/component-lab/images/input-dark-filled-regular-1x.png and b/site/public/component-lab/images/input-dark-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-dark-filled-regular-2x.png b/site/public/component-lab/images/input-dark-filled-regular-2x.png index 754dea00..e0bd0b60 100644 Binary files a/site/public/component-lab/images/input-dark-filled-regular-2x.png and b/site/public/component-lab/images/input-dark-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ember-empty-narrow-1x.png b/site/public/component-lab/images/input-ember-empty-narrow-1x.png index c2c20812..f0c2ae14 100644 Binary files a/site/public/component-lab/images/input-ember-empty-narrow-1x.png and b/site/public/component-lab/images/input-ember-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ember-empty-narrow-2x.png b/site/public/component-lab/images/input-ember-empty-narrow-2x.png index b619ee81..5e2c9ef3 100644 Binary files a/site/public/component-lab/images/input-ember-empty-narrow-2x.png and b/site/public/component-lab/images/input-ember-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ember-empty-regular-1x.png b/site/public/component-lab/images/input-ember-empty-regular-1x.png index c3a1b3d0..93d5d70c 100644 Binary files a/site/public/component-lab/images/input-ember-empty-regular-1x.png and b/site/public/component-lab/images/input-ember-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ember-empty-regular-2x.png b/site/public/component-lab/images/input-ember-empty-regular-2x.png index 7e0e0e00..017bc344 100644 Binary files a/site/public/component-lab/images/input-ember-empty-regular-2x.png and b/site/public/component-lab/images/input-ember-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ember-error-narrow-1x.png b/site/public/component-lab/images/input-ember-error-narrow-1x.png index 4c345f81..e03c9a5c 100644 Binary files a/site/public/component-lab/images/input-ember-error-narrow-1x.png and b/site/public/component-lab/images/input-ember-error-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ember-error-narrow-2x.png b/site/public/component-lab/images/input-ember-error-narrow-2x.png index 0d6c710c..9b784d33 100644 Binary files a/site/public/component-lab/images/input-ember-error-narrow-2x.png and b/site/public/component-lab/images/input-ember-error-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ember-error-regular-1x.png b/site/public/component-lab/images/input-ember-error-regular-1x.png index 773f0cb6..a5a0fb3a 100644 Binary files a/site/public/component-lab/images/input-ember-error-regular-1x.png and b/site/public/component-lab/images/input-ember-error-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ember-error-regular-2x.png b/site/public/component-lab/images/input-ember-error-regular-2x.png index 0e2b7d10..66e745c8 100644 Binary files a/site/public/component-lab/images/input-ember-error-regular-2x.png and b/site/public/component-lab/images/input-ember-error-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ember-filled-narrow-1x.png b/site/public/component-lab/images/input-ember-filled-narrow-1x.png index 8748250c..3ec534b2 100644 Binary files a/site/public/component-lab/images/input-ember-filled-narrow-1x.png and b/site/public/component-lab/images/input-ember-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ember-filled-narrow-2x.png b/site/public/component-lab/images/input-ember-filled-narrow-2x.png index 5be35791..2c76cb8b 100644 Binary files a/site/public/component-lab/images/input-ember-filled-narrow-2x.png and b/site/public/component-lab/images/input-ember-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ember-filled-regular-1x.png b/site/public/component-lab/images/input-ember-filled-regular-1x.png index 72be9e24..57c1717a 100644 Binary files a/site/public/component-lab/images/input-ember-filled-regular-1x.png and b/site/public/component-lab/images/input-ember-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ember-filled-regular-2x.png b/site/public/component-lab/images/input-ember-filled-regular-2x.png index f9bcd873..f8329071 100644 Binary files a/site/public/component-lab/images/input-ember-filled-regular-2x.png and b/site/public/component-lab/images/input-ember-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-forest-empty-narrow-1x.png b/site/public/component-lab/images/input-forest-empty-narrow-1x.png index 39a76a01..6c17f4a0 100644 Binary files a/site/public/component-lab/images/input-forest-empty-narrow-1x.png and b/site/public/component-lab/images/input-forest-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-forest-empty-narrow-2x.png b/site/public/component-lab/images/input-forest-empty-narrow-2x.png index 7219c6fa..56132e34 100644 Binary files a/site/public/component-lab/images/input-forest-empty-narrow-2x.png and b/site/public/component-lab/images/input-forest-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-forest-empty-regular-1x.png b/site/public/component-lab/images/input-forest-empty-regular-1x.png index 4f53814b..44049cee 100644 Binary files a/site/public/component-lab/images/input-forest-empty-regular-1x.png and b/site/public/component-lab/images/input-forest-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-forest-empty-regular-2x.png b/site/public/component-lab/images/input-forest-empty-regular-2x.png index 054a10f2..42465557 100644 Binary files a/site/public/component-lab/images/input-forest-empty-regular-2x.png and b/site/public/component-lab/images/input-forest-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-forest-error-narrow-1x.png b/site/public/component-lab/images/input-forest-error-narrow-1x.png index 4bfd84d2..cf1c0424 100644 Binary files a/site/public/component-lab/images/input-forest-error-narrow-1x.png and b/site/public/component-lab/images/input-forest-error-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-forest-error-narrow-2x.png b/site/public/component-lab/images/input-forest-error-narrow-2x.png index 3e3f8df2..f6affe31 100644 Binary files a/site/public/component-lab/images/input-forest-error-narrow-2x.png and b/site/public/component-lab/images/input-forest-error-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-forest-error-regular-1x.png b/site/public/component-lab/images/input-forest-error-regular-1x.png index 94c60f6e..366c250e 100644 Binary files a/site/public/component-lab/images/input-forest-error-regular-1x.png and b/site/public/component-lab/images/input-forest-error-regular-1x.png differ diff --git a/site/public/component-lab/images/input-forest-error-regular-2x.png b/site/public/component-lab/images/input-forest-error-regular-2x.png index c79dc9af..3c98b40b 100644 Binary files a/site/public/component-lab/images/input-forest-error-regular-2x.png and b/site/public/component-lab/images/input-forest-error-regular-2x.png differ diff --git a/site/public/component-lab/images/input-forest-filled-narrow-1x.png b/site/public/component-lab/images/input-forest-filled-narrow-1x.png index da1145a4..265af534 100644 Binary files a/site/public/component-lab/images/input-forest-filled-narrow-1x.png and b/site/public/component-lab/images/input-forest-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-forest-filled-narrow-2x.png b/site/public/component-lab/images/input-forest-filled-narrow-2x.png index 3c2b5cdf..4ff6a337 100644 Binary files a/site/public/component-lab/images/input-forest-filled-narrow-2x.png and b/site/public/component-lab/images/input-forest-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-forest-filled-regular-1x.png b/site/public/component-lab/images/input-forest-filled-regular-1x.png index d43fa0af..60279d50 100644 Binary files a/site/public/component-lab/images/input-forest-filled-regular-1x.png and b/site/public/component-lab/images/input-forest-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-forest-filled-regular-2x.png b/site/public/component-lab/images/input-forest-filled-regular-2x.png index 42649e6e..458488c4 100644 Binary files a/site/public/component-lab/images/input-forest-filled-regular-2x.png and b/site/public/component-lab/images/input-forest-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-dark-empty-narrow-1x.png b/site/public/component-lab/images/input-group-dark-empty-narrow-1x.png index e962de6e..d3da5df8 100644 Binary files a/site/public/component-lab/images/input-group-dark-empty-narrow-1x.png and b/site/public/component-lab/images/input-group-dark-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-dark-empty-narrow-2x.png b/site/public/component-lab/images/input-group-dark-empty-narrow-2x.png index 2c8ebeb6..1d0d76bd 100644 Binary files a/site/public/component-lab/images/input-group-dark-empty-narrow-2x.png and b/site/public/component-lab/images/input-group-dark-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-dark-empty-regular-1x.png b/site/public/component-lab/images/input-group-dark-empty-regular-1x.png index aed7791b..a1bd4d22 100644 Binary files a/site/public/component-lab/images/input-group-dark-empty-regular-1x.png and b/site/public/component-lab/images/input-group-dark-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-dark-empty-regular-2x.png b/site/public/component-lab/images/input-group-dark-empty-regular-2x.png index f2709e62..b7ba31b4 100644 Binary files a/site/public/component-lab/images/input-group-dark-empty-regular-2x.png and b/site/public/component-lab/images/input-group-dark-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-dark-filled-narrow-1x.png b/site/public/component-lab/images/input-group-dark-filled-narrow-1x.png index 90622288..e0967edd 100644 Binary files a/site/public/component-lab/images/input-group-dark-filled-narrow-1x.png and b/site/public/component-lab/images/input-group-dark-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-dark-filled-narrow-2x.png b/site/public/component-lab/images/input-group-dark-filled-narrow-2x.png index 11296b7f..8557747c 100644 Binary files a/site/public/component-lab/images/input-group-dark-filled-narrow-2x.png and b/site/public/component-lab/images/input-group-dark-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-dark-filled-regular-1x.png b/site/public/component-lab/images/input-group-dark-filled-regular-1x.png index ff8375cc..7338e981 100644 Binary files a/site/public/component-lab/images/input-group-dark-filled-regular-1x.png and b/site/public/component-lab/images/input-group-dark-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-dark-filled-regular-2x.png b/site/public/component-lab/images/input-group-dark-filled-regular-2x.png index 815a77b8..dd2c9ad4 100644 Binary files a/site/public/component-lab/images/input-group-dark-filled-regular-2x.png and b/site/public/component-lab/images/input-group-dark-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-ember-empty-narrow-1x.png b/site/public/component-lab/images/input-group-ember-empty-narrow-1x.png index 37951a6f..67588c46 100644 Binary files a/site/public/component-lab/images/input-group-ember-empty-narrow-1x.png and b/site/public/component-lab/images/input-group-ember-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-ember-empty-narrow-2x.png b/site/public/component-lab/images/input-group-ember-empty-narrow-2x.png index 86c83c97..60b00949 100644 Binary files a/site/public/component-lab/images/input-group-ember-empty-narrow-2x.png and b/site/public/component-lab/images/input-group-ember-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-ember-empty-regular-1x.png b/site/public/component-lab/images/input-group-ember-empty-regular-1x.png index 1e6face7..6332fa02 100644 Binary files a/site/public/component-lab/images/input-group-ember-empty-regular-1x.png and b/site/public/component-lab/images/input-group-ember-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-ember-empty-regular-2x.png b/site/public/component-lab/images/input-group-ember-empty-regular-2x.png index 6952aa84..af770421 100644 Binary files a/site/public/component-lab/images/input-group-ember-empty-regular-2x.png and b/site/public/component-lab/images/input-group-ember-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-ember-filled-narrow-1x.png b/site/public/component-lab/images/input-group-ember-filled-narrow-1x.png index f991ce53..080f06db 100644 Binary files a/site/public/component-lab/images/input-group-ember-filled-narrow-1x.png and b/site/public/component-lab/images/input-group-ember-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-ember-filled-narrow-2x.png b/site/public/component-lab/images/input-group-ember-filled-narrow-2x.png index d3142311..a6c716bf 100644 Binary files a/site/public/component-lab/images/input-group-ember-filled-narrow-2x.png and b/site/public/component-lab/images/input-group-ember-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-ember-filled-regular-1x.png b/site/public/component-lab/images/input-group-ember-filled-regular-1x.png index 3f66816e..a3b17020 100644 Binary files a/site/public/component-lab/images/input-group-ember-filled-regular-1x.png and b/site/public/component-lab/images/input-group-ember-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-ember-filled-regular-2x.png b/site/public/component-lab/images/input-group-ember-filled-regular-2x.png index e3e0214e..d308edaf 100644 Binary files a/site/public/component-lab/images/input-group-ember-filled-regular-2x.png and b/site/public/component-lab/images/input-group-ember-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-forest-empty-narrow-1x.png b/site/public/component-lab/images/input-group-forest-empty-narrow-1x.png index dcaa01df..57c5a1e7 100644 Binary files a/site/public/component-lab/images/input-group-forest-empty-narrow-1x.png and b/site/public/component-lab/images/input-group-forest-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-forest-empty-narrow-2x.png b/site/public/component-lab/images/input-group-forest-empty-narrow-2x.png index acd22ec4..1c78bfc4 100644 Binary files a/site/public/component-lab/images/input-group-forest-empty-narrow-2x.png and b/site/public/component-lab/images/input-group-forest-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-forest-empty-regular-1x.png b/site/public/component-lab/images/input-group-forest-empty-regular-1x.png index 97f56266..0510baf0 100644 Binary files a/site/public/component-lab/images/input-group-forest-empty-regular-1x.png and b/site/public/component-lab/images/input-group-forest-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-forest-empty-regular-2x.png b/site/public/component-lab/images/input-group-forest-empty-regular-2x.png index eb9b3cf2..656779f8 100644 Binary files a/site/public/component-lab/images/input-group-forest-empty-regular-2x.png and b/site/public/component-lab/images/input-group-forest-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-forest-filled-narrow-1x.png b/site/public/component-lab/images/input-group-forest-filled-narrow-1x.png index a49e39ac..8e235a5e 100644 Binary files a/site/public/component-lab/images/input-group-forest-filled-narrow-1x.png and b/site/public/component-lab/images/input-group-forest-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-forest-filled-narrow-2x.png b/site/public/component-lab/images/input-group-forest-filled-narrow-2x.png index 9c340e50..5b6df6b6 100644 Binary files a/site/public/component-lab/images/input-group-forest-filled-narrow-2x.png and b/site/public/component-lab/images/input-group-forest-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-forest-filled-regular-1x.png b/site/public/component-lab/images/input-group-forest-filled-regular-1x.png index d9ad4f85..09045940 100644 Binary files a/site/public/component-lab/images/input-group-forest-filled-regular-1x.png and b/site/public/component-lab/images/input-group-forest-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-forest-filled-regular-2x.png b/site/public/component-lab/images/input-group-forest-filled-regular-2x.png index 67b6ab0f..74187830 100644 Binary files a/site/public/component-lab/images/input-group-forest-filled-regular-2x.png and b/site/public/component-lab/images/input-group-forest-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-light-empty-narrow-1x.png b/site/public/component-lab/images/input-group-light-empty-narrow-1x.png index 92453826..8ec6572f 100644 Binary files a/site/public/component-lab/images/input-group-light-empty-narrow-1x.png and b/site/public/component-lab/images/input-group-light-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-light-empty-narrow-2x.png b/site/public/component-lab/images/input-group-light-empty-narrow-2x.png index e83ffcfc..3c6b8432 100644 Binary files a/site/public/component-lab/images/input-group-light-empty-narrow-2x.png and b/site/public/component-lab/images/input-group-light-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-light-empty-regular-1x.png b/site/public/component-lab/images/input-group-light-empty-regular-1x.png index 500c05d4..4673c73a 100644 Binary files a/site/public/component-lab/images/input-group-light-empty-regular-1x.png and b/site/public/component-lab/images/input-group-light-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-light-empty-regular-2x.png b/site/public/component-lab/images/input-group-light-empty-regular-2x.png index 4ca08008..31965473 100644 Binary files a/site/public/component-lab/images/input-group-light-empty-regular-2x.png and b/site/public/component-lab/images/input-group-light-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-light-filled-narrow-1x.png b/site/public/component-lab/images/input-group-light-filled-narrow-1x.png index dbcb1787..2b47d1ee 100644 Binary files a/site/public/component-lab/images/input-group-light-filled-narrow-1x.png and b/site/public/component-lab/images/input-group-light-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-light-filled-narrow-2x.png b/site/public/component-lab/images/input-group-light-filled-narrow-2x.png index 91831479..b3178283 100644 Binary files a/site/public/component-lab/images/input-group-light-filled-narrow-2x.png and b/site/public/component-lab/images/input-group-light-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-light-filled-regular-1x.png b/site/public/component-lab/images/input-group-light-filled-regular-1x.png index 571e1c86..959f161a 100644 Binary files a/site/public/component-lab/images/input-group-light-filled-regular-1x.png and b/site/public/component-lab/images/input-group-light-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-light-filled-regular-2x.png b/site/public/component-lab/images/input-group-light-filled-regular-2x.png index c4554c8e..041a63ed 100644 Binary files a/site/public/component-lab/images/input-group-light-filled-regular-2x.png and b/site/public/component-lab/images/input-group-light-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-empty-narrow-1x.png b/site/public/component-lab/images/input-group-ocean-empty-narrow-1x.png index 58a87bdf..5117912e 100644 Binary files a/site/public/component-lab/images/input-group-ocean-empty-narrow-1x.png and b/site/public/component-lab/images/input-group-ocean-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-empty-narrow-2x.png b/site/public/component-lab/images/input-group-ocean-empty-narrow-2x.png index 5645c095..781466d1 100644 Binary files a/site/public/component-lab/images/input-group-ocean-empty-narrow-2x.png and b/site/public/component-lab/images/input-group-ocean-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-empty-regular-1x.png b/site/public/component-lab/images/input-group-ocean-empty-regular-1x.png index 4db6c10e..3c66adf6 100644 Binary files a/site/public/component-lab/images/input-group-ocean-empty-regular-1x.png and b/site/public/component-lab/images/input-group-ocean-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-empty-regular-2x.png b/site/public/component-lab/images/input-group-ocean-empty-regular-2x.png index 3cc42703..c4bab722 100644 Binary files a/site/public/component-lab/images/input-group-ocean-empty-regular-2x.png and b/site/public/component-lab/images/input-group-ocean-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-filled-narrow-1x.png b/site/public/component-lab/images/input-group-ocean-filled-narrow-1x.png index 972bf48f..ba629a90 100644 Binary files a/site/public/component-lab/images/input-group-ocean-filled-narrow-1x.png and b/site/public/component-lab/images/input-group-ocean-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-filled-narrow-2x.png b/site/public/component-lab/images/input-group-ocean-filled-narrow-2x.png index 41dc652c..0d54552d 100644 Binary files a/site/public/component-lab/images/input-group-ocean-filled-narrow-2x.png and b/site/public/component-lab/images/input-group-ocean-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-filled-regular-1x.png b/site/public/component-lab/images/input-group-ocean-filled-regular-1x.png index 293c6594..fe53c503 100644 Binary files a/site/public/component-lab/images/input-group-ocean-filled-regular-1x.png and b/site/public/component-lab/images/input-group-ocean-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-group-ocean-filled-regular-2x.png b/site/public/component-lab/images/input-group-ocean-filled-regular-2x.png index 60d6ad01..25eefa1e 100644 Binary files a/site/public/component-lab/images/input-group-ocean-filled-regular-2x.png and b/site/public/component-lab/images/input-group-ocean-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-light-empty-narrow-1x.png b/site/public/component-lab/images/input-light-empty-narrow-1x.png index 87e2ff15..c92bf1f1 100644 Binary files a/site/public/component-lab/images/input-light-empty-narrow-1x.png and b/site/public/component-lab/images/input-light-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-light-empty-narrow-2x.png b/site/public/component-lab/images/input-light-empty-narrow-2x.png index eb207d3a..5b87c569 100644 Binary files a/site/public/component-lab/images/input-light-empty-narrow-2x.png and b/site/public/component-lab/images/input-light-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-light-empty-regular-1x.png b/site/public/component-lab/images/input-light-empty-regular-1x.png index dbc42ce2..07539973 100644 Binary files a/site/public/component-lab/images/input-light-empty-regular-1x.png and b/site/public/component-lab/images/input-light-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-light-empty-regular-2x.png b/site/public/component-lab/images/input-light-empty-regular-2x.png index 392b8f34..9864d2a3 100644 Binary files a/site/public/component-lab/images/input-light-empty-regular-2x.png and b/site/public/component-lab/images/input-light-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-light-error-narrow-1x.png b/site/public/component-lab/images/input-light-error-narrow-1x.png index d0b5eaa3..c24bcfc4 100644 Binary files a/site/public/component-lab/images/input-light-error-narrow-1x.png and b/site/public/component-lab/images/input-light-error-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-light-error-narrow-2x.png b/site/public/component-lab/images/input-light-error-narrow-2x.png index 9626c121..e63af0a5 100644 Binary files a/site/public/component-lab/images/input-light-error-narrow-2x.png and b/site/public/component-lab/images/input-light-error-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-light-error-regular-1x.png b/site/public/component-lab/images/input-light-error-regular-1x.png index fc601e9e..c73cd857 100644 Binary files a/site/public/component-lab/images/input-light-error-regular-1x.png and b/site/public/component-lab/images/input-light-error-regular-1x.png differ diff --git a/site/public/component-lab/images/input-light-error-regular-2x.png b/site/public/component-lab/images/input-light-error-regular-2x.png index f69989c0..5a462fb5 100644 Binary files a/site/public/component-lab/images/input-light-error-regular-2x.png and b/site/public/component-lab/images/input-light-error-regular-2x.png differ diff --git a/site/public/component-lab/images/input-light-filled-narrow-1x.png b/site/public/component-lab/images/input-light-filled-narrow-1x.png index 8c3f2329..02c650b1 100644 Binary files a/site/public/component-lab/images/input-light-filled-narrow-1x.png and b/site/public/component-lab/images/input-light-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-light-filled-narrow-2x.png b/site/public/component-lab/images/input-light-filled-narrow-2x.png index a8389cae..6f399026 100644 Binary files a/site/public/component-lab/images/input-light-filled-narrow-2x.png and b/site/public/component-lab/images/input-light-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-light-filled-regular-1x.png b/site/public/component-lab/images/input-light-filled-regular-1x.png index 74a29200..df00433f 100644 Binary files a/site/public/component-lab/images/input-light-filled-regular-1x.png and b/site/public/component-lab/images/input-light-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-light-filled-regular-2x.png b/site/public/component-lab/images/input-light-filled-regular-2x.png index 4a8f5667..d78ee4a0 100644 Binary files a/site/public/component-lab/images/input-light-filled-regular-2x.png and b/site/public/component-lab/images/input-light-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-empty-narrow-1x.png b/site/public/component-lab/images/input-ocean-empty-narrow-1x.png index 241769d8..a667c971 100644 Binary files a/site/public/component-lab/images/input-ocean-empty-narrow-1x.png and b/site/public/component-lab/images/input-ocean-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-empty-narrow-2x.png b/site/public/component-lab/images/input-ocean-empty-narrow-2x.png index 0f84a5af..bcb284b1 100644 Binary files a/site/public/component-lab/images/input-ocean-empty-narrow-2x.png and b/site/public/component-lab/images/input-ocean-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-empty-regular-1x.png b/site/public/component-lab/images/input-ocean-empty-regular-1x.png index 96029bba..9543d72e 100644 Binary files a/site/public/component-lab/images/input-ocean-empty-regular-1x.png and b/site/public/component-lab/images/input-ocean-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-empty-regular-2x.png b/site/public/component-lab/images/input-ocean-empty-regular-2x.png index e06b0f1d..657488b9 100644 Binary files a/site/public/component-lab/images/input-ocean-empty-regular-2x.png and b/site/public/component-lab/images/input-ocean-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-error-narrow-1x.png b/site/public/component-lab/images/input-ocean-error-narrow-1x.png index b87051a5..2e23ac56 100644 Binary files a/site/public/component-lab/images/input-ocean-error-narrow-1x.png and b/site/public/component-lab/images/input-ocean-error-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-error-narrow-2x.png b/site/public/component-lab/images/input-ocean-error-narrow-2x.png index 823b1937..018aa56c 100644 Binary files a/site/public/component-lab/images/input-ocean-error-narrow-2x.png and b/site/public/component-lab/images/input-ocean-error-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-error-regular-1x.png b/site/public/component-lab/images/input-ocean-error-regular-1x.png index 28a62203..eec1ac60 100644 Binary files a/site/public/component-lab/images/input-ocean-error-regular-1x.png and b/site/public/component-lab/images/input-ocean-error-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-error-regular-2x.png b/site/public/component-lab/images/input-ocean-error-regular-2x.png index d34483d8..700acf61 100644 Binary files a/site/public/component-lab/images/input-ocean-error-regular-2x.png and b/site/public/component-lab/images/input-ocean-error-regular-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-filled-narrow-1x.png b/site/public/component-lab/images/input-ocean-filled-narrow-1x.png index f3918c0c..297d87cd 100644 Binary files a/site/public/component-lab/images/input-ocean-filled-narrow-1x.png and b/site/public/component-lab/images/input-ocean-filled-narrow-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-filled-narrow-2x.png b/site/public/component-lab/images/input-ocean-filled-narrow-2x.png index e1d7c1d9..a6708f85 100644 Binary files a/site/public/component-lab/images/input-ocean-filled-narrow-2x.png and b/site/public/component-lab/images/input-ocean-filled-narrow-2x.png differ diff --git a/site/public/component-lab/images/input-ocean-filled-regular-1x.png b/site/public/component-lab/images/input-ocean-filled-regular-1x.png index 660145d5..e29a1791 100644 Binary files a/site/public/component-lab/images/input-ocean-filled-regular-1x.png and b/site/public/component-lab/images/input-ocean-filled-regular-1x.png differ diff --git a/site/public/component-lab/images/input-ocean-filled-regular-2x.png b/site/public/component-lab/images/input-ocean-filled-regular-2x.png index 7085afe9..e0ea8515 100644 Binary files a/site/public/component-lab/images/input-ocean-filled-regular-2x.png and b/site/public/component-lab/images/input-ocean-filled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-disabled-narrow-1x.png b/site/public/component-lab/images/menu-dark-disabled-narrow-1x.png index e585d61a..e52890d6 100644 Binary files a/site/public/component-lab/images/menu-dark-disabled-narrow-1x.png and b/site/public/component-lab/images/menu-dark-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-disabled-narrow-2x.png b/site/public/component-lab/images/menu-dark-disabled-narrow-2x.png index 62f2f7a7..4e119596 100644 Binary files a/site/public/component-lab/images/menu-dark-disabled-narrow-2x.png and b/site/public/component-lab/images/menu-dark-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-disabled-regular-1x.png b/site/public/component-lab/images/menu-dark-disabled-regular-1x.png index ffacd673..24fd2dab 100644 Binary files a/site/public/component-lab/images/menu-dark-disabled-regular-1x.png and b/site/public/component-lab/images/menu-dark-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-disabled-regular-2x.png b/site/public/component-lab/images/menu-dark-disabled-regular-2x.png index 819f23a0..4b04d363 100644 Binary files a/site/public/component-lab/images/menu-dark-disabled-regular-2x.png and b/site/public/component-lab/images/menu-dark-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-empty-narrow-1x.png b/site/public/component-lab/images/menu-dark-empty-narrow-1x.png index 7a3d8186..c6531b91 100644 Binary files a/site/public/component-lab/images/menu-dark-empty-narrow-1x.png and b/site/public/component-lab/images/menu-dark-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-empty-narrow-2x.png b/site/public/component-lab/images/menu-dark-empty-narrow-2x.png index 258fe26a..952968c7 100644 Binary files a/site/public/component-lab/images/menu-dark-empty-narrow-2x.png and b/site/public/component-lab/images/menu-dark-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-empty-regular-1x.png b/site/public/component-lab/images/menu-dark-empty-regular-1x.png index ca76d1f1..cd6821e6 100644 Binary files a/site/public/component-lab/images/menu-dark-empty-regular-1x.png and b/site/public/component-lab/images/menu-dark-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-empty-regular-2x.png b/site/public/component-lab/images/menu-dark-empty-regular-2x.png index 170d69a3..15d032e4 100644 Binary files a/site/public/component-lab/images/menu-dark-empty-regular-2x.png and b/site/public/component-lab/images/menu-dark-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-populated-narrow-1x.png b/site/public/component-lab/images/menu-dark-populated-narrow-1x.png index c4e56696..6625bdf2 100644 Binary files a/site/public/component-lab/images/menu-dark-populated-narrow-1x.png and b/site/public/component-lab/images/menu-dark-populated-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-populated-narrow-2x.png b/site/public/component-lab/images/menu-dark-populated-narrow-2x.png index d0262031..c94302a9 100644 Binary files a/site/public/component-lab/images/menu-dark-populated-narrow-2x.png and b/site/public/component-lab/images/menu-dark-populated-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-dark-populated-regular-1x.png b/site/public/component-lab/images/menu-dark-populated-regular-1x.png index 2e15d102..a0ee751f 100644 Binary files a/site/public/component-lab/images/menu-dark-populated-regular-1x.png and b/site/public/component-lab/images/menu-dark-populated-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-dark-populated-regular-2x.png b/site/public/component-lab/images/menu-dark-populated-regular-2x.png index 997dc542..247de90d 100644 Binary files a/site/public/component-lab/images/menu-dark-populated-regular-2x.png and b/site/public/component-lab/images/menu-dark-populated-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-disabled-narrow-1x.png b/site/public/component-lab/images/menu-ember-disabled-narrow-1x.png index b752b9d3..0146eda7 100644 Binary files a/site/public/component-lab/images/menu-ember-disabled-narrow-1x.png and b/site/public/component-lab/images/menu-ember-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-disabled-narrow-2x.png b/site/public/component-lab/images/menu-ember-disabled-narrow-2x.png index ef964a06..d690478d 100644 Binary files a/site/public/component-lab/images/menu-ember-disabled-narrow-2x.png and b/site/public/component-lab/images/menu-ember-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-disabled-regular-1x.png b/site/public/component-lab/images/menu-ember-disabled-regular-1x.png index f47b4698..9580a619 100644 Binary files a/site/public/component-lab/images/menu-ember-disabled-regular-1x.png and b/site/public/component-lab/images/menu-ember-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-disabled-regular-2x.png b/site/public/component-lab/images/menu-ember-disabled-regular-2x.png index a98210e9..e474c5e5 100644 Binary files a/site/public/component-lab/images/menu-ember-disabled-regular-2x.png and b/site/public/component-lab/images/menu-ember-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-empty-narrow-1x.png b/site/public/component-lab/images/menu-ember-empty-narrow-1x.png index f791aa3f..a00229ce 100644 Binary files a/site/public/component-lab/images/menu-ember-empty-narrow-1x.png and b/site/public/component-lab/images/menu-ember-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-empty-narrow-2x.png b/site/public/component-lab/images/menu-ember-empty-narrow-2x.png index c689ff27..30ea9c9c 100644 Binary files a/site/public/component-lab/images/menu-ember-empty-narrow-2x.png and b/site/public/component-lab/images/menu-ember-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-empty-regular-1x.png b/site/public/component-lab/images/menu-ember-empty-regular-1x.png index d737d32f..1e6c93ec 100644 Binary files a/site/public/component-lab/images/menu-ember-empty-regular-1x.png and b/site/public/component-lab/images/menu-ember-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-empty-regular-2x.png b/site/public/component-lab/images/menu-ember-empty-regular-2x.png index cdde8450..7b127e1f 100644 Binary files a/site/public/component-lab/images/menu-ember-empty-regular-2x.png and b/site/public/component-lab/images/menu-ember-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-populated-narrow-1x.png b/site/public/component-lab/images/menu-ember-populated-narrow-1x.png index 715134d5..50d1d263 100644 Binary files a/site/public/component-lab/images/menu-ember-populated-narrow-1x.png and b/site/public/component-lab/images/menu-ember-populated-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-populated-narrow-2x.png b/site/public/component-lab/images/menu-ember-populated-narrow-2x.png index 4d0d88a0..c695236e 100644 Binary files a/site/public/component-lab/images/menu-ember-populated-narrow-2x.png and b/site/public/component-lab/images/menu-ember-populated-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ember-populated-regular-1x.png b/site/public/component-lab/images/menu-ember-populated-regular-1x.png index 3c187ac6..fef11f9f 100644 Binary files a/site/public/component-lab/images/menu-ember-populated-regular-1x.png and b/site/public/component-lab/images/menu-ember-populated-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ember-populated-regular-2x.png b/site/public/component-lab/images/menu-ember-populated-regular-2x.png index efb6515d..161cef48 100644 Binary files a/site/public/component-lab/images/menu-ember-populated-regular-2x.png and b/site/public/component-lab/images/menu-ember-populated-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-disabled-narrow-1x.png b/site/public/component-lab/images/menu-forest-disabled-narrow-1x.png index a712dfe2..6fd9f18c 100644 Binary files a/site/public/component-lab/images/menu-forest-disabled-narrow-1x.png and b/site/public/component-lab/images/menu-forest-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-disabled-narrow-2x.png b/site/public/component-lab/images/menu-forest-disabled-narrow-2x.png index aca50e5e..016cf498 100644 Binary files a/site/public/component-lab/images/menu-forest-disabled-narrow-2x.png and b/site/public/component-lab/images/menu-forest-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-disabled-regular-1x.png b/site/public/component-lab/images/menu-forest-disabled-regular-1x.png index e8778366..19aa1fe5 100644 Binary files a/site/public/component-lab/images/menu-forest-disabled-regular-1x.png and b/site/public/component-lab/images/menu-forest-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-disabled-regular-2x.png b/site/public/component-lab/images/menu-forest-disabled-regular-2x.png index 399270ad..cb70c21d 100644 Binary files a/site/public/component-lab/images/menu-forest-disabled-regular-2x.png and b/site/public/component-lab/images/menu-forest-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-empty-narrow-1x.png b/site/public/component-lab/images/menu-forest-empty-narrow-1x.png index 85aa62a1..2139f0e8 100644 Binary files a/site/public/component-lab/images/menu-forest-empty-narrow-1x.png and b/site/public/component-lab/images/menu-forest-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-empty-narrow-2x.png b/site/public/component-lab/images/menu-forest-empty-narrow-2x.png index fa50b9ac..20818bec 100644 Binary files a/site/public/component-lab/images/menu-forest-empty-narrow-2x.png and b/site/public/component-lab/images/menu-forest-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-empty-regular-1x.png b/site/public/component-lab/images/menu-forest-empty-regular-1x.png index 97c397a4..fff934f5 100644 Binary files a/site/public/component-lab/images/menu-forest-empty-regular-1x.png and b/site/public/component-lab/images/menu-forest-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-empty-regular-2x.png b/site/public/component-lab/images/menu-forest-empty-regular-2x.png index 7e45f16a..39174a76 100644 Binary files a/site/public/component-lab/images/menu-forest-empty-regular-2x.png and b/site/public/component-lab/images/menu-forest-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-populated-narrow-1x.png b/site/public/component-lab/images/menu-forest-populated-narrow-1x.png index 50e12bff..dad1cf35 100644 Binary files a/site/public/component-lab/images/menu-forest-populated-narrow-1x.png and b/site/public/component-lab/images/menu-forest-populated-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-populated-narrow-2x.png b/site/public/component-lab/images/menu-forest-populated-narrow-2x.png index 6f5f7730..e666f14d 100644 Binary files a/site/public/component-lab/images/menu-forest-populated-narrow-2x.png and b/site/public/component-lab/images/menu-forest-populated-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-forest-populated-regular-1x.png b/site/public/component-lab/images/menu-forest-populated-regular-1x.png index bed6f928..e9a79925 100644 Binary files a/site/public/component-lab/images/menu-forest-populated-regular-1x.png and b/site/public/component-lab/images/menu-forest-populated-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-forest-populated-regular-2x.png b/site/public/component-lab/images/menu-forest-populated-regular-2x.png index e53828f9..46367829 100644 Binary files a/site/public/component-lab/images/menu-forest-populated-regular-2x.png and b/site/public/component-lab/images/menu-forest-populated-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-light-disabled-narrow-1x.png b/site/public/component-lab/images/menu-light-disabled-narrow-1x.png index a34886dc..dfbb33dc 100644 Binary files a/site/public/component-lab/images/menu-light-disabled-narrow-1x.png and b/site/public/component-lab/images/menu-light-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-light-disabled-narrow-2x.png b/site/public/component-lab/images/menu-light-disabled-narrow-2x.png index 2937f4bb..d8cb8fa2 100644 Binary files a/site/public/component-lab/images/menu-light-disabled-narrow-2x.png and b/site/public/component-lab/images/menu-light-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-light-disabled-regular-1x.png b/site/public/component-lab/images/menu-light-disabled-regular-1x.png index 69bed34e..26acc261 100644 Binary files a/site/public/component-lab/images/menu-light-disabled-regular-1x.png and b/site/public/component-lab/images/menu-light-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-light-disabled-regular-2x.png b/site/public/component-lab/images/menu-light-disabled-regular-2x.png index 03f2521a..815e70ec 100644 Binary files a/site/public/component-lab/images/menu-light-disabled-regular-2x.png and b/site/public/component-lab/images/menu-light-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-light-empty-narrow-1x.png b/site/public/component-lab/images/menu-light-empty-narrow-1x.png index 8e71364f..58f2cd97 100644 Binary files a/site/public/component-lab/images/menu-light-empty-narrow-1x.png and b/site/public/component-lab/images/menu-light-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-light-empty-narrow-2x.png b/site/public/component-lab/images/menu-light-empty-narrow-2x.png index 6cf8991b..372e3750 100644 Binary files a/site/public/component-lab/images/menu-light-empty-narrow-2x.png and b/site/public/component-lab/images/menu-light-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-light-empty-regular-1x.png b/site/public/component-lab/images/menu-light-empty-regular-1x.png index 29f26204..73dcb556 100644 Binary files a/site/public/component-lab/images/menu-light-empty-regular-1x.png and b/site/public/component-lab/images/menu-light-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-light-empty-regular-2x.png b/site/public/component-lab/images/menu-light-empty-regular-2x.png index 6a44d04e..cd895ec7 100644 Binary files a/site/public/component-lab/images/menu-light-empty-regular-2x.png and b/site/public/component-lab/images/menu-light-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-light-populated-narrow-1x.png b/site/public/component-lab/images/menu-light-populated-narrow-1x.png index e42899e9..4db71b6f 100644 Binary files a/site/public/component-lab/images/menu-light-populated-narrow-1x.png and b/site/public/component-lab/images/menu-light-populated-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-light-populated-narrow-2x.png b/site/public/component-lab/images/menu-light-populated-narrow-2x.png index 48614d88..4dc8774e 100644 Binary files a/site/public/component-lab/images/menu-light-populated-narrow-2x.png and b/site/public/component-lab/images/menu-light-populated-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-light-populated-regular-1x.png b/site/public/component-lab/images/menu-light-populated-regular-1x.png index f951e6f3..cbdc8485 100644 Binary files a/site/public/component-lab/images/menu-light-populated-regular-1x.png and b/site/public/component-lab/images/menu-light-populated-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-light-populated-regular-2x.png b/site/public/component-lab/images/menu-light-populated-regular-2x.png index b944e677..af4dc50e 100644 Binary files a/site/public/component-lab/images/menu-light-populated-regular-2x.png and b/site/public/component-lab/images/menu-light-populated-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-disabled-narrow-1x.png b/site/public/component-lab/images/menu-ocean-disabled-narrow-1x.png index ba76c96e..93ba7338 100644 Binary files a/site/public/component-lab/images/menu-ocean-disabled-narrow-1x.png and b/site/public/component-lab/images/menu-ocean-disabled-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-disabled-narrow-2x.png b/site/public/component-lab/images/menu-ocean-disabled-narrow-2x.png index 5e5f750b..0731b438 100644 Binary files a/site/public/component-lab/images/menu-ocean-disabled-narrow-2x.png and b/site/public/component-lab/images/menu-ocean-disabled-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-disabled-regular-1x.png b/site/public/component-lab/images/menu-ocean-disabled-regular-1x.png index 34e7d171..5afca58b 100644 Binary files a/site/public/component-lab/images/menu-ocean-disabled-regular-1x.png and b/site/public/component-lab/images/menu-ocean-disabled-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-disabled-regular-2x.png b/site/public/component-lab/images/menu-ocean-disabled-regular-2x.png index 6919fb83..8fe68878 100644 Binary files a/site/public/component-lab/images/menu-ocean-disabled-regular-2x.png and b/site/public/component-lab/images/menu-ocean-disabled-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-empty-narrow-1x.png b/site/public/component-lab/images/menu-ocean-empty-narrow-1x.png index 7826ff1f..1e6d3a2b 100644 Binary files a/site/public/component-lab/images/menu-ocean-empty-narrow-1x.png and b/site/public/component-lab/images/menu-ocean-empty-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-empty-narrow-2x.png b/site/public/component-lab/images/menu-ocean-empty-narrow-2x.png index 13e83949..a6334a1d 100644 Binary files a/site/public/component-lab/images/menu-ocean-empty-narrow-2x.png and b/site/public/component-lab/images/menu-ocean-empty-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-empty-regular-1x.png b/site/public/component-lab/images/menu-ocean-empty-regular-1x.png index 4c3ff8b3..056d167a 100644 Binary files a/site/public/component-lab/images/menu-ocean-empty-regular-1x.png and b/site/public/component-lab/images/menu-ocean-empty-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-empty-regular-2x.png b/site/public/component-lab/images/menu-ocean-empty-regular-2x.png index da9be3c6..866ffab0 100644 Binary files a/site/public/component-lab/images/menu-ocean-empty-regular-2x.png and b/site/public/component-lab/images/menu-ocean-empty-regular-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-populated-narrow-1x.png b/site/public/component-lab/images/menu-ocean-populated-narrow-1x.png index 4053a118..a13f4069 100644 Binary files a/site/public/component-lab/images/menu-ocean-populated-narrow-1x.png and b/site/public/component-lab/images/menu-ocean-populated-narrow-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-populated-narrow-2x.png b/site/public/component-lab/images/menu-ocean-populated-narrow-2x.png index dfdd9f48..4062136d 100644 Binary files a/site/public/component-lab/images/menu-ocean-populated-narrow-2x.png and b/site/public/component-lab/images/menu-ocean-populated-narrow-2x.png differ diff --git a/site/public/component-lab/images/menu-ocean-populated-regular-1x.png b/site/public/component-lab/images/menu-ocean-populated-regular-1x.png index d5ebfde5..21f7b8bd 100644 Binary files a/site/public/component-lab/images/menu-ocean-populated-regular-1x.png and b/site/public/component-lab/images/menu-ocean-populated-regular-1x.png differ diff --git a/site/public/component-lab/images/menu-ocean-populated-regular-2x.png b/site/public/component-lab/images/menu-ocean-populated-regular-2x.png index 64b6cfc9..377939b8 100644 Binary files a/site/public/component-lab/images/menu-ocean-populated-regular-2x.png and b/site/public/component-lab/images/menu-ocean-populated-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-end-narrow-1x.png b/site/public/component-lab/images/motion-dark-end-narrow-1x.png index 0ba4688d..714f9fc0 100644 Binary files a/site/public/component-lab/images/motion-dark-end-narrow-1x.png and b/site/public/component-lab/images/motion-dark-end-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-end-narrow-2x.png b/site/public/component-lab/images/motion-dark-end-narrow-2x.png index f79f1886..ab0f22b8 100644 Binary files a/site/public/component-lab/images/motion-dark-end-narrow-2x.png and b/site/public/component-lab/images/motion-dark-end-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-end-regular-1x.png b/site/public/component-lab/images/motion-dark-end-regular-1x.png index 0fff9257..fca64320 100644 Binary files a/site/public/component-lab/images/motion-dark-end-regular-1x.png and b/site/public/component-lab/images/motion-dark-end-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-end-regular-2x.png b/site/public/component-lab/images/motion-dark-end-regular-2x.png index 7ce5bd81..5b1a0e51 100644 Binary files a/site/public/component-lab/images/motion-dark-end-regular-2x.png and b/site/public/component-lab/images/motion-dark-end-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-middle-narrow-1x.png b/site/public/component-lab/images/motion-dark-middle-narrow-1x.png index 6dc1ed12..ddb201f4 100644 Binary files a/site/public/component-lab/images/motion-dark-middle-narrow-1x.png and b/site/public/component-lab/images/motion-dark-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-middle-narrow-2x.png b/site/public/component-lab/images/motion-dark-middle-narrow-2x.png index b141aae5..298b13e1 100644 Binary files a/site/public/component-lab/images/motion-dark-middle-narrow-2x.png and b/site/public/component-lab/images/motion-dark-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-middle-regular-1x.png b/site/public/component-lab/images/motion-dark-middle-regular-1x.png index e7c248d9..76a7d3eb 100644 Binary files a/site/public/component-lab/images/motion-dark-middle-regular-1x.png and b/site/public/component-lab/images/motion-dark-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-middle-regular-2x.png b/site/public/component-lab/images/motion-dark-middle-regular-2x.png index d1648c6d..0e471b6a 100644 Binary files a/site/public/component-lab/images/motion-dark-middle-regular-2x.png and b/site/public/component-lab/images/motion-dark-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-start-narrow-1x.png b/site/public/component-lab/images/motion-dark-start-narrow-1x.png index 6b009a5f..81afb461 100644 Binary files a/site/public/component-lab/images/motion-dark-start-narrow-1x.png and b/site/public/component-lab/images/motion-dark-start-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-start-narrow-2x.png b/site/public/component-lab/images/motion-dark-start-narrow-2x.png index 3a5b209d..70ee5adb 100644 Binary files a/site/public/component-lab/images/motion-dark-start-narrow-2x.png and b/site/public/component-lab/images/motion-dark-start-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-dark-start-regular-1x.png b/site/public/component-lab/images/motion-dark-start-regular-1x.png index a110cd5c..2b3b3be5 100644 Binary files a/site/public/component-lab/images/motion-dark-start-regular-1x.png and b/site/public/component-lab/images/motion-dark-start-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-dark-start-regular-2x.png b/site/public/component-lab/images/motion-dark-start-regular-2x.png index b14fb7cd..6a68a4d7 100644 Binary files a/site/public/component-lab/images/motion-dark-start-regular-2x.png and b/site/public/component-lab/images/motion-dark-start-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-end-narrow-1x.png b/site/public/component-lab/images/motion-ember-end-narrow-1x.png index 81e597b9..42c19267 100644 Binary files a/site/public/component-lab/images/motion-ember-end-narrow-1x.png and b/site/public/component-lab/images/motion-ember-end-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-end-narrow-2x.png b/site/public/component-lab/images/motion-ember-end-narrow-2x.png index b0cd66f2..e0407efd 100644 Binary files a/site/public/component-lab/images/motion-ember-end-narrow-2x.png and b/site/public/component-lab/images/motion-ember-end-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-end-regular-1x.png b/site/public/component-lab/images/motion-ember-end-regular-1x.png index c28352e3..2e8359f2 100644 Binary files a/site/public/component-lab/images/motion-ember-end-regular-1x.png and b/site/public/component-lab/images/motion-ember-end-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-end-regular-2x.png b/site/public/component-lab/images/motion-ember-end-regular-2x.png index b01a82fb..5071ba1e 100644 Binary files a/site/public/component-lab/images/motion-ember-end-regular-2x.png and b/site/public/component-lab/images/motion-ember-end-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-middle-narrow-1x.png b/site/public/component-lab/images/motion-ember-middle-narrow-1x.png index 5bbdfb9a..6bb7d68a 100644 Binary files a/site/public/component-lab/images/motion-ember-middle-narrow-1x.png and b/site/public/component-lab/images/motion-ember-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-middle-narrow-2x.png b/site/public/component-lab/images/motion-ember-middle-narrow-2x.png index 411d3b5d..3bbc08c1 100644 Binary files a/site/public/component-lab/images/motion-ember-middle-narrow-2x.png and b/site/public/component-lab/images/motion-ember-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-middle-regular-1x.png b/site/public/component-lab/images/motion-ember-middle-regular-1x.png index 405d7f2b..3ed194b8 100644 Binary files a/site/public/component-lab/images/motion-ember-middle-regular-1x.png and b/site/public/component-lab/images/motion-ember-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-middle-regular-2x.png b/site/public/component-lab/images/motion-ember-middle-regular-2x.png index 793c1aaa..fc63078e 100644 Binary files a/site/public/component-lab/images/motion-ember-middle-regular-2x.png and b/site/public/component-lab/images/motion-ember-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-start-narrow-1x.png b/site/public/component-lab/images/motion-ember-start-narrow-1x.png index a11f0a34..5fae6503 100644 Binary files a/site/public/component-lab/images/motion-ember-start-narrow-1x.png and b/site/public/component-lab/images/motion-ember-start-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-start-narrow-2x.png b/site/public/component-lab/images/motion-ember-start-narrow-2x.png index e610a030..53d0a3ca 100644 Binary files a/site/public/component-lab/images/motion-ember-start-narrow-2x.png and b/site/public/component-lab/images/motion-ember-start-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ember-start-regular-1x.png b/site/public/component-lab/images/motion-ember-start-regular-1x.png index 738bdcd9..70941a42 100644 Binary files a/site/public/component-lab/images/motion-ember-start-regular-1x.png and b/site/public/component-lab/images/motion-ember-start-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ember-start-regular-2x.png b/site/public/component-lab/images/motion-ember-start-regular-2x.png index 4059f572..e600b8ae 100644 Binary files a/site/public/component-lab/images/motion-ember-start-regular-2x.png and b/site/public/component-lab/images/motion-ember-start-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-end-narrow-1x.png b/site/public/component-lab/images/motion-forest-end-narrow-1x.png index e564a6d3..5f7ee495 100644 Binary files a/site/public/component-lab/images/motion-forest-end-narrow-1x.png and b/site/public/component-lab/images/motion-forest-end-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-end-narrow-2x.png b/site/public/component-lab/images/motion-forest-end-narrow-2x.png index 6e3b41c3..28a1968b 100644 Binary files a/site/public/component-lab/images/motion-forest-end-narrow-2x.png and b/site/public/component-lab/images/motion-forest-end-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-end-regular-1x.png b/site/public/component-lab/images/motion-forest-end-regular-1x.png index 4a364fd3..98a62e04 100644 Binary files a/site/public/component-lab/images/motion-forest-end-regular-1x.png and b/site/public/component-lab/images/motion-forest-end-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-end-regular-2x.png b/site/public/component-lab/images/motion-forest-end-regular-2x.png index ceacdd4c..82085af6 100644 Binary files a/site/public/component-lab/images/motion-forest-end-regular-2x.png and b/site/public/component-lab/images/motion-forest-end-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-middle-narrow-1x.png b/site/public/component-lab/images/motion-forest-middle-narrow-1x.png index 184a7300..80fb413f 100644 Binary files a/site/public/component-lab/images/motion-forest-middle-narrow-1x.png and b/site/public/component-lab/images/motion-forest-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-middle-narrow-2x.png b/site/public/component-lab/images/motion-forest-middle-narrow-2x.png index 5f9d0b53..bb54e211 100644 Binary files a/site/public/component-lab/images/motion-forest-middle-narrow-2x.png and b/site/public/component-lab/images/motion-forest-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-middle-regular-1x.png b/site/public/component-lab/images/motion-forest-middle-regular-1x.png index fe9f51f9..32a9c162 100644 Binary files a/site/public/component-lab/images/motion-forest-middle-regular-1x.png and b/site/public/component-lab/images/motion-forest-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-middle-regular-2x.png b/site/public/component-lab/images/motion-forest-middle-regular-2x.png index 1a6492e6..d3617f05 100644 Binary files a/site/public/component-lab/images/motion-forest-middle-regular-2x.png and b/site/public/component-lab/images/motion-forest-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-start-narrow-1x.png b/site/public/component-lab/images/motion-forest-start-narrow-1x.png index 3a7f101b..1e5bfb58 100644 Binary files a/site/public/component-lab/images/motion-forest-start-narrow-1x.png and b/site/public/component-lab/images/motion-forest-start-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-start-narrow-2x.png b/site/public/component-lab/images/motion-forest-start-narrow-2x.png index 82d38518..a0246ce0 100644 Binary files a/site/public/component-lab/images/motion-forest-start-narrow-2x.png and b/site/public/component-lab/images/motion-forest-start-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-forest-start-regular-1x.png b/site/public/component-lab/images/motion-forest-start-regular-1x.png index 43126855..de84ec0c 100644 Binary files a/site/public/component-lab/images/motion-forest-start-regular-1x.png and b/site/public/component-lab/images/motion-forest-start-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-forest-start-regular-2x.png b/site/public/component-lab/images/motion-forest-start-regular-2x.png index f19fabd1..100083c6 100644 Binary files a/site/public/component-lab/images/motion-forest-start-regular-2x.png and b/site/public/component-lab/images/motion-forest-start-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-light-end-narrow-1x.png b/site/public/component-lab/images/motion-light-end-narrow-1x.png index f246261e..93fb3d90 100644 Binary files a/site/public/component-lab/images/motion-light-end-narrow-1x.png and b/site/public/component-lab/images/motion-light-end-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-light-end-narrow-2x.png b/site/public/component-lab/images/motion-light-end-narrow-2x.png index 6ccd51da..dc59ac4b 100644 Binary files a/site/public/component-lab/images/motion-light-end-narrow-2x.png and b/site/public/component-lab/images/motion-light-end-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-light-end-regular-1x.png b/site/public/component-lab/images/motion-light-end-regular-1x.png index d83923fa..3d5b12e1 100644 Binary files a/site/public/component-lab/images/motion-light-end-regular-1x.png and b/site/public/component-lab/images/motion-light-end-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-light-end-regular-2x.png b/site/public/component-lab/images/motion-light-end-regular-2x.png index 6028fc98..8debeab0 100644 Binary files a/site/public/component-lab/images/motion-light-end-regular-2x.png and b/site/public/component-lab/images/motion-light-end-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-light-middle-narrow-1x.png b/site/public/component-lab/images/motion-light-middle-narrow-1x.png index b5c65726..18c6aafd 100644 Binary files a/site/public/component-lab/images/motion-light-middle-narrow-1x.png and b/site/public/component-lab/images/motion-light-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-light-middle-narrow-2x.png b/site/public/component-lab/images/motion-light-middle-narrow-2x.png index b09945bc..f8062bab 100644 Binary files a/site/public/component-lab/images/motion-light-middle-narrow-2x.png and b/site/public/component-lab/images/motion-light-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-light-middle-regular-1x.png b/site/public/component-lab/images/motion-light-middle-regular-1x.png index b4e65658..812b7e4a 100644 Binary files a/site/public/component-lab/images/motion-light-middle-regular-1x.png and b/site/public/component-lab/images/motion-light-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-light-middle-regular-2x.png b/site/public/component-lab/images/motion-light-middle-regular-2x.png index 33699269..a0dc691b 100644 Binary files a/site/public/component-lab/images/motion-light-middle-regular-2x.png and b/site/public/component-lab/images/motion-light-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-light-start-narrow-1x.png b/site/public/component-lab/images/motion-light-start-narrow-1x.png index 9410fac2..4a411ffe 100644 Binary files a/site/public/component-lab/images/motion-light-start-narrow-1x.png and b/site/public/component-lab/images/motion-light-start-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-light-start-narrow-2x.png b/site/public/component-lab/images/motion-light-start-narrow-2x.png index 72f11efc..606940a3 100644 Binary files a/site/public/component-lab/images/motion-light-start-narrow-2x.png and b/site/public/component-lab/images/motion-light-start-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-light-start-regular-1x.png b/site/public/component-lab/images/motion-light-start-regular-1x.png index c78fe0c7..38751169 100644 Binary files a/site/public/component-lab/images/motion-light-start-regular-1x.png and b/site/public/component-lab/images/motion-light-start-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-light-start-regular-2x.png b/site/public/component-lab/images/motion-light-start-regular-2x.png index 67829590..62218fb5 100644 Binary files a/site/public/component-lab/images/motion-light-start-regular-2x.png and b/site/public/component-lab/images/motion-light-start-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-end-narrow-1x.png b/site/public/component-lab/images/motion-ocean-end-narrow-1x.png index dc71cfd7..cb72b560 100644 Binary files a/site/public/component-lab/images/motion-ocean-end-narrow-1x.png and b/site/public/component-lab/images/motion-ocean-end-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-end-narrow-2x.png b/site/public/component-lab/images/motion-ocean-end-narrow-2x.png index e3ecf9fb..527a134b 100644 Binary files a/site/public/component-lab/images/motion-ocean-end-narrow-2x.png and b/site/public/component-lab/images/motion-ocean-end-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-end-regular-1x.png b/site/public/component-lab/images/motion-ocean-end-regular-1x.png index 3bec3071..087c01ed 100644 Binary files a/site/public/component-lab/images/motion-ocean-end-regular-1x.png and b/site/public/component-lab/images/motion-ocean-end-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-end-regular-2x.png b/site/public/component-lab/images/motion-ocean-end-regular-2x.png index 506b247d..0318d917 100644 Binary files a/site/public/component-lab/images/motion-ocean-end-regular-2x.png and b/site/public/component-lab/images/motion-ocean-end-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-middle-narrow-1x.png b/site/public/component-lab/images/motion-ocean-middle-narrow-1x.png index c432c181..b3622585 100644 Binary files a/site/public/component-lab/images/motion-ocean-middle-narrow-1x.png and b/site/public/component-lab/images/motion-ocean-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-middle-narrow-2x.png b/site/public/component-lab/images/motion-ocean-middle-narrow-2x.png index 34540ad9..55f8e57f 100644 Binary files a/site/public/component-lab/images/motion-ocean-middle-narrow-2x.png and b/site/public/component-lab/images/motion-ocean-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-middle-regular-1x.png b/site/public/component-lab/images/motion-ocean-middle-regular-1x.png index 0b77b5f0..1961ba5d 100644 Binary files a/site/public/component-lab/images/motion-ocean-middle-regular-1x.png and b/site/public/component-lab/images/motion-ocean-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-middle-regular-2x.png b/site/public/component-lab/images/motion-ocean-middle-regular-2x.png index e0ea4346..c85b60dd 100644 Binary files a/site/public/component-lab/images/motion-ocean-middle-regular-2x.png and b/site/public/component-lab/images/motion-ocean-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-start-narrow-1x.png b/site/public/component-lab/images/motion-ocean-start-narrow-1x.png index 09a9fe9e..aa54de8f 100644 Binary files a/site/public/component-lab/images/motion-ocean-start-narrow-1x.png and b/site/public/component-lab/images/motion-ocean-start-narrow-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-start-narrow-2x.png b/site/public/component-lab/images/motion-ocean-start-narrow-2x.png index 618bff09..5fc2b670 100644 Binary files a/site/public/component-lab/images/motion-ocean-start-narrow-2x.png and b/site/public/component-lab/images/motion-ocean-start-narrow-2x.png differ diff --git a/site/public/component-lab/images/motion-ocean-start-regular-1x.png b/site/public/component-lab/images/motion-ocean-start-regular-1x.png index 729ee041..aae9bd96 100644 Binary files a/site/public/component-lab/images/motion-ocean-start-regular-1x.png and b/site/public/component-lab/images/motion-ocean-start-regular-1x.png differ diff --git a/site/public/component-lab/images/motion-ocean-start-regular-2x.png b/site/public/component-lab/images/motion-ocean-start-regular-2x.png index 28519e29..af518114 100644 Binary files a/site/public/component-lab/images/motion-ocean-start-regular-2x.png and b/site/public/component-lab/images/motion-ocean-start-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-dark-closed-narrow-1x.png b/site/public/component-lab/images/popover-dark-closed-narrow-1x.png index 290774a4..99bf5db4 100644 Binary files a/site/public/component-lab/images/popover-dark-closed-narrow-1x.png and b/site/public/component-lab/images/popover-dark-closed-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-dark-closed-narrow-2x.png b/site/public/component-lab/images/popover-dark-closed-narrow-2x.png index 2e3ce47f..45443b0d 100644 Binary files a/site/public/component-lab/images/popover-dark-closed-narrow-2x.png and b/site/public/component-lab/images/popover-dark-closed-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-dark-closed-regular-1x.png b/site/public/component-lab/images/popover-dark-closed-regular-1x.png index d85998a3..48f11a18 100644 Binary files a/site/public/component-lab/images/popover-dark-closed-regular-1x.png and b/site/public/component-lab/images/popover-dark-closed-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-dark-closed-regular-2x.png b/site/public/component-lab/images/popover-dark-closed-regular-2x.png index e84f913a..d928355f 100644 Binary files a/site/public/component-lab/images/popover-dark-closed-regular-2x.png and b/site/public/component-lab/images/popover-dark-closed-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-dark-open-narrow-1x.png b/site/public/component-lab/images/popover-dark-open-narrow-1x.png index 50fd1a5b..292a8dbd 100644 Binary files a/site/public/component-lab/images/popover-dark-open-narrow-1x.png and b/site/public/component-lab/images/popover-dark-open-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-dark-open-narrow-2x.png b/site/public/component-lab/images/popover-dark-open-narrow-2x.png index 92cab86d..33c96891 100644 Binary files a/site/public/component-lab/images/popover-dark-open-narrow-2x.png and b/site/public/component-lab/images/popover-dark-open-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-dark-open-regular-1x.png b/site/public/component-lab/images/popover-dark-open-regular-1x.png index a7b9dc84..8c79635b 100644 Binary files a/site/public/component-lab/images/popover-dark-open-regular-1x.png and b/site/public/component-lab/images/popover-dark-open-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-dark-open-regular-2x.png b/site/public/component-lab/images/popover-dark-open-regular-2x.png index aa5eb44c..a3b239ea 100644 Binary files a/site/public/component-lab/images/popover-dark-open-regular-2x.png and b/site/public/component-lab/images/popover-dark-open-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-ember-closed-narrow-1x.png b/site/public/component-lab/images/popover-ember-closed-narrow-1x.png index cb192392..00a03505 100644 Binary files a/site/public/component-lab/images/popover-ember-closed-narrow-1x.png and b/site/public/component-lab/images/popover-ember-closed-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-ember-closed-narrow-2x.png b/site/public/component-lab/images/popover-ember-closed-narrow-2x.png index beda76d8..27970756 100644 Binary files a/site/public/component-lab/images/popover-ember-closed-narrow-2x.png and b/site/public/component-lab/images/popover-ember-closed-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-ember-closed-regular-1x.png b/site/public/component-lab/images/popover-ember-closed-regular-1x.png index 9047114b..ddc6d15f 100644 Binary files a/site/public/component-lab/images/popover-ember-closed-regular-1x.png and b/site/public/component-lab/images/popover-ember-closed-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-ember-closed-regular-2x.png b/site/public/component-lab/images/popover-ember-closed-regular-2x.png index d61316a8..5b4ac718 100644 Binary files a/site/public/component-lab/images/popover-ember-closed-regular-2x.png and b/site/public/component-lab/images/popover-ember-closed-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-ember-open-narrow-1x.png b/site/public/component-lab/images/popover-ember-open-narrow-1x.png index 18e59829..c05d7010 100644 Binary files a/site/public/component-lab/images/popover-ember-open-narrow-1x.png and b/site/public/component-lab/images/popover-ember-open-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-ember-open-narrow-2x.png b/site/public/component-lab/images/popover-ember-open-narrow-2x.png index bd037197..f747db2e 100644 Binary files a/site/public/component-lab/images/popover-ember-open-narrow-2x.png and b/site/public/component-lab/images/popover-ember-open-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-ember-open-regular-1x.png b/site/public/component-lab/images/popover-ember-open-regular-1x.png index f17b4440..028e0f79 100644 Binary files a/site/public/component-lab/images/popover-ember-open-regular-1x.png and b/site/public/component-lab/images/popover-ember-open-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-ember-open-regular-2x.png b/site/public/component-lab/images/popover-ember-open-regular-2x.png index 7f33a649..640ee3b8 100644 Binary files a/site/public/component-lab/images/popover-ember-open-regular-2x.png and b/site/public/component-lab/images/popover-ember-open-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-forest-closed-narrow-1x.png b/site/public/component-lab/images/popover-forest-closed-narrow-1x.png index f4133c42..c6ac8d40 100644 Binary files a/site/public/component-lab/images/popover-forest-closed-narrow-1x.png and b/site/public/component-lab/images/popover-forest-closed-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-forest-closed-narrow-2x.png b/site/public/component-lab/images/popover-forest-closed-narrow-2x.png index 65de6dc1..38b9a53c 100644 Binary files a/site/public/component-lab/images/popover-forest-closed-narrow-2x.png and b/site/public/component-lab/images/popover-forest-closed-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-forest-closed-regular-1x.png b/site/public/component-lab/images/popover-forest-closed-regular-1x.png index e36b6ddd..2a75a55f 100644 Binary files a/site/public/component-lab/images/popover-forest-closed-regular-1x.png and b/site/public/component-lab/images/popover-forest-closed-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-forest-closed-regular-2x.png b/site/public/component-lab/images/popover-forest-closed-regular-2x.png index ef2f2438..a315f7db 100644 Binary files a/site/public/component-lab/images/popover-forest-closed-regular-2x.png and b/site/public/component-lab/images/popover-forest-closed-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-forest-open-narrow-1x.png b/site/public/component-lab/images/popover-forest-open-narrow-1x.png index 12d77b5f..239de823 100644 Binary files a/site/public/component-lab/images/popover-forest-open-narrow-1x.png and b/site/public/component-lab/images/popover-forest-open-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-forest-open-narrow-2x.png b/site/public/component-lab/images/popover-forest-open-narrow-2x.png index 2b32b352..a0374d3d 100644 Binary files a/site/public/component-lab/images/popover-forest-open-narrow-2x.png and b/site/public/component-lab/images/popover-forest-open-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-forest-open-regular-1x.png b/site/public/component-lab/images/popover-forest-open-regular-1x.png index 92b64609..5d68b213 100644 Binary files a/site/public/component-lab/images/popover-forest-open-regular-1x.png and b/site/public/component-lab/images/popover-forest-open-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-forest-open-regular-2x.png b/site/public/component-lab/images/popover-forest-open-regular-2x.png index 62b0fe75..d2ba1029 100644 Binary files a/site/public/component-lab/images/popover-forest-open-regular-2x.png and b/site/public/component-lab/images/popover-forest-open-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-light-closed-narrow-1x.png b/site/public/component-lab/images/popover-light-closed-narrow-1x.png index 8a5dcaaa..de590eb3 100644 Binary files a/site/public/component-lab/images/popover-light-closed-narrow-1x.png and b/site/public/component-lab/images/popover-light-closed-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-light-closed-narrow-2x.png b/site/public/component-lab/images/popover-light-closed-narrow-2x.png index f8b352cb..82555725 100644 Binary files a/site/public/component-lab/images/popover-light-closed-narrow-2x.png and b/site/public/component-lab/images/popover-light-closed-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-light-closed-regular-1x.png b/site/public/component-lab/images/popover-light-closed-regular-1x.png index dbd6ed88..c66fb252 100644 Binary files a/site/public/component-lab/images/popover-light-closed-regular-1x.png and b/site/public/component-lab/images/popover-light-closed-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-light-closed-regular-2x.png b/site/public/component-lab/images/popover-light-closed-regular-2x.png index ac92ac5e..ca2a38a3 100644 Binary files a/site/public/component-lab/images/popover-light-closed-regular-2x.png and b/site/public/component-lab/images/popover-light-closed-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-light-open-narrow-1x.png b/site/public/component-lab/images/popover-light-open-narrow-1x.png index 05e6a90b..082bb6d2 100644 Binary files a/site/public/component-lab/images/popover-light-open-narrow-1x.png and b/site/public/component-lab/images/popover-light-open-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-light-open-narrow-2x.png b/site/public/component-lab/images/popover-light-open-narrow-2x.png index 90803ed5..728d5fc7 100644 Binary files a/site/public/component-lab/images/popover-light-open-narrow-2x.png and b/site/public/component-lab/images/popover-light-open-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-light-open-regular-1x.png b/site/public/component-lab/images/popover-light-open-regular-1x.png index 03b39904..ee46d187 100644 Binary files a/site/public/component-lab/images/popover-light-open-regular-1x.png and b/site/public/component-lab/images/popover-light-open-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-light-open-regular-2x.png b/site/public/component-lab/images/popover-light-open-regular-2x.png index 8e1286ff..8e4c5d51 100644 Binary files a/site/public/component-lab/images/popover-light-open-regular-2x.png and b/site/public/component-lab/images/popover-light-open-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-ocean-closed-narrow-1x.png b/site/public/component-lab/images/popover-ocean-closed-narrow-1x.png index f64f484f..bc5b9ebb 100644 Binary files a/site/public/component-lab/images/popover-ocean-closed-narrow-1x.png and b/site/public/component-lab/images/popover-ocean-closed-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-ocean-closed-narrow-2x.png b/site/public/component-lab/images/popover-ocean-closed-narrow-2x.png index b4ef7534..1b3b8f6d 100644 Binary files a/site/public/component-lab/images/popover-ocean-closed-narrow-2x.png and b/site/public/component-lab/images/popover-ocean-closed-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-ocean-closed-regular-1x.png b/site/public/component-lab/images/popover-ocean-closed-regular-1x.png index 67ac18d8..762ae1d1 100644 Binary files a/site/public/component-lab/images/popover-ocean-closed-regular-1x.png and b/site/public/component-lab/images/popover-ocean-closed-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-ocean-closed-regular-2x.png b/site/public/component-lab/images/popover-ocean-closed-regular-2x.png index fed4c99f..4659fb8a 100644 Binary files a/site/public/component-lab/images/popover-ocean-closed-regular-2x.png and b/site/public/component-lab/images/popover-ocean-closed-regular-2x.png differ diff --git a/site/public/component-lab/images/popover-ocean-open-narrow-1x.png b/site/public/component-lab/images/popover-ocean-open-narrow-1x.png index 925eae86..9c9675ed 100644 Binary files a/site/public/component-lab/images/popover-ocean-open-narrow-1x.png and b/site/public/component-lab/images/popover-ocean-open-narrow-1x.png differ diff --git a/site/public/component-lab/images/popover-ocean-open-narrow-2x.png b/site/public/component-lab/images/popover-ocean-open-narrow-2x.png index bf2ec1fd..6ecc5c03 100644 Binary files a/site/public/component-lab/images/popover-ocean-open-narrow-2x.png and b/site/public/component-lab/images/popover-ocean-open-narrow-2x.png differ diff --git a/site/public/component-lab/images/popover-ocean-open-regular-1x.png b/site/public/component-lab/images/popover-ocean-open-regular-1x.png index fa4593e1..5c4d1541 100644 Binary files a/site/public/component-lab/images/popover-ocean-open-regular-1x.png and b/site/public/component-lab/images/popover-ocean-open-regular-1x.png differ diff --git a/site/public/component-lab/images/popover-ocean-open-regular-2x.png b/site/public/component-lab/images/popover-ocean-open-regular-2x.png index eb446281..015a6b69 100644 Binary files a/site/public/component-lab/images/popover-ocean-open-regular-2x.png and b/site/public/component-lab/images/popover-ocean-open-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-dark-bottom-narrow-1x.png b/site/public/component-lab/images/scroll-dark-bottom-narrow-1x.png index 75897a60..3379fdf6 100644 Binary files a/site/public/component-lab/images/scroll-dark-bottom-narrow-1x.png and b/site/public/component-lab/images/scroll-dark-bottom-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-dark-bottom-narrow-2x.png b/site/public/component-lab/images/scroll-dark-bottom-narrow-2x.png index 18ab28b0..112598bb 100644 Binary files a/site/public/component-lab/images/scroll-dark-bottom-narrow-2x.png and b/site/public/component-lab/images/scroll-dark-bottom-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-dark-bottom-regular-1x.png b/site/public/component-lab/images/scroll-dark-bottom-regular-1x.png index aca72375..9ec7df6e 100644 Binary files a/site/public/component-lab/images/scroll-dark-bottom-regular-1x.png and b/site/public/component-lab/images/scroll-dark-bottom-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-dark-bottom-regular-2x.png b/site/public/component-lab/images/scroll-dark-bottom-regular-2x.png index 86f145ad..ec8e3dad 100644 Binary files a/site/public/component-lab/images/scroll-dark-bottom-regular-2x.png and b/site/public/component-lab/images/scroll-dark-bottom-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-dark-top-narrow-1x.png b/site/public/component-lab/images/scroll-dark-top-narrow-1x.png index 408615d0..2b060b08 100644 Binary files a/site/public/component-lab/images/scroll-dark-top-narrow-1x.png and b/site/public/component-lab/images/scroll-dark-top-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-dark-top-narrow-2x.png b/site/public/component-lab/images/scroll-dark-top-narrow-2x.png index 817b7197..309c6af6 100644 Binary files a/site/public/component-lab/images/scroll-dark-top-narrow-2x.png and b/site/public/component-lab/images/scroll-dark-top-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-dark-top-regular-1x.png b/site/public/component-lab/images/scroll-dark-top-regular-1x.png index de2968ed..dfc551f7 100644 Binary files a/site/public/component-lab/images/scroll-dark-top-regular-1x.png and b/site/public/component-lab/images/scroll-dark-top-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-dark-top-regular-2x.png b/site/public/component-lab/images/scroll-dark-top-regular-2x.png index 3ee3f3ea..f305d251 100644 Binary files a/site/public/component-lab/images/scroll-dark-top-regular-2x.png and b/site/public/component-lab/images/scroll-dark-top-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-ember-bottom-narrow-1x.png b/site/public/component-lab/images/scroll-ember-bottom-narrow-1x.png index 13b9b47d..08872910 100644 Binary files a/site/public/component-lab/images/scroll-ember-bottom-narrow-1x.png and b/site/public/component-lab/images/scroll-ember-bottom-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-ember-bottom-narrow-2x.png b/site/public/component-lab/images/scroll-ember-bottom-narrow-2x.png index def27cd7..9b70485f 100644 Binary files a/site/public/component-lab/images/scroll-ember-bottom-narrow-2x.png and b/site/public/component-lab/images/scroll-ember-bottom-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-ember-bottom-regular-1x.png b/site/public/component-lab/images/scroll-ember-bottom-regular-1x.png index 4f143910..662b0789 100644 Binary files a/site/public/component-lab/images/scroll-ember-bottom-regular-1x.png and b/site/public/component-lab/images/scroll-ember-bottom-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-ember-bottom-regular-2x.png b/site/public/component-lab/images/scroll-ember-bottom-regular-2x.png index 1ead5f41..d4cadaea 100644 Binary files a/site/public/component-lab/images/scroll-ember-bottom-regular-2x.png and b/site/public/component-lab/images/scroll-ember-bottom-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-ember-top-narrow-1x.png b/site/public/component-lab/images/scroll-ember-top-narrow-1x.png index ec30af29..6caf2b2b 100644 Binary files a/site/public/component-lab/images/scroll-ember-top-narrow-1x.png and b/site/public/component-lab/images/scroll-ember-top-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-ember-top-narrow-2x.png b/site/public/component-lab/images/scroll-ember-top-narrow-2x.png index 79930f4e..13d91151 100644 Binary files a/site/public/component-lab/images/scroll-ember-top-narrow-2x.png and b/site/public/component-lab/images/scroll-ember-top-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-ember-top-regular-1x.png b/site/public/component-lab/images/scroll-ember-top-regular-1x.png index 81051d5c..fda5c564 100644 Binary files a/site/public/component-lab/images/scroll-ember-top-regular-1x.png and b/site/public/component-lab/images/scroll-ember-top-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-ember-top-regular-2x.png b/site/public/component-lab/images/scroll-ember-top-regular-2x.png index cfadd2a8..a895cb0d 100644 Binary files a/site/public/component-lab/images/scroll-ember-top-regular-2x.png and b/site/public/component-lab/images/scroll-ember-top-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-forest-bottom-narrow-1x.png b/site/public/component-lab/images/scroll-forest-bottom-narrow-1x.png index 44709624..119044d8 100644 Binary files a/site/public/component-lab/images/scroll-forest-bottom-narrow-1x.png and b/site/public/component-lab/images/scroll-forest-bottom-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-forest-bottom-narrow-2x.png b/site/public/component-lab/images/scroll-forest-bottom-narrow-2x.png index 268d22d1..62627312 100644 Binary files a/site/public/component-lab/images/scroll-forest-bottom-narrow-2x.png and b/site/public/component-lab/images/scroll-forest-bottom-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-forest-bottom-regular-1x.png b/site/public/component-lab/images/scroll-forest-bottom-regular-1x.png index 215337c5..015262b0 100644 Binary files a/site/public/component-lab/images/scroll-forest-bottom-regular-1x.png and b/site/public/component-lab/images/scroll-forest-bottom-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-forest-bottom-regular-2x.png b/site/public/component-lab/images/scroll-forest-bottom-regular-2x.png index c42bc0ba..5e16fc8c 100644 Binary files a/site/public/component-lab/images/scroll-forest-bottom-regular-2x.png and b/site/public/component-lab/images/scroll-forest-bottom-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-forest-top-narrow-1x.png b/site/public/component-lab/images/scroll-forest-top-narrow-1x.png index ebb6d60b..2db9d3d3 100644 Binary files a/site/public/component-lab/images/scroll-forest-top-narrow-1x.png and b/site/public/component-lab/images/scroll-forest-top-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-forest-top-narrow-2x.png b/site/public/component-lab/images/scroll-forest-top-narrow-2x.png index a2fb5556..2b8cabbd 100644 Binary files a/site/public/component-lab/images/scroll-forest-top-narrow-2x.png and b/site/public/component-lab/images/scroll-forest-top-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-forest-top-regular-1x.png b/site/public/component-lab/images/scroll-forest-top-regular-1x.png index 45b95672..e54fd449 100644 Binary files a/site/public/component-lab/images/scroll-forest-top-regular-1x.png and b/site/public/component-lab/images/scroll-forest-top-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-forest-top-regular-2x.png b/site/public/component-lab/images/scroll-forest-top-regular-2x.png index 8e810f35..b8a990ae 100644 Binary files a/site/public/component-lab/images/scroll-forest-top-regular-2x.png and b/site/public/component-lab/images/scroll-forest-top-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-light-bottom-narrow-1x.png b/site/public/component-lab/images/scroll-light-bottom-narrow-1x.png index 1bc8032b..81a38036 100644 Binary files a/site/public/component-lab/images/scroll-light-bottom-narrow-1x.png and b/site/public/component-lab/images/scroll-light-bottom-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-light-bottom-narrow-2x.png b/site/public/component-lab/images/scroll-light-bottom-narrow-2x.png index 0b0d2bbc..a44aa5cf 100644 Binary files a/site/public/component-lab/images/scroll-light-bottom-narrow-2x.png and b/site/public/component-lab/images/scroll-light-bottom-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-light-bottom-regular-1x.png b/site/public/component-lab/images/scroll-light-bottom-regular-1x.png index 3fb72a0f..02200dc3 100644 Binary files a/site/public/component-lab/images/scroll-light-bottom-regular-1x.png and b/site/public/component-lab/images/scroll-light-bottom-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-light-bottom-regular-2x.png b/site/public/component-lab/images/scroll-light-bottom-regular-2x.png index 0c592239..57143195 100644 Binary files a/site/public/component-lab/images/scroll-light-bottom-regular-2x.png and b/site/public/component-lab/images/scroll-light-bottom-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-light-top-narrow-1x.png b/site/public/component-lab/images/scroll-light-top-narrow-1x.png index e65c6ae0..13636389 100644 Binary files a/site/public/component-lab/images/scroll-light-top-narrow-1x.png and b/site/public/component-lab/images/scroll-light-top-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-light-top-narrow-2x.png b/site/public/component-lab/images/scroll-light-top-narrow-2x.png index 73178b6e..7d47b03a 100644 Binary files a/site/public/component-lab/images/scroll-light-top-narrow-2x.png and b/site/public/component-lab/images/scroll-light-top-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-light-top-regular-1x.png b/site/public/component-lab/images/scroll-light-top-regular-1x.png index e4bed12a..6610cc26 100644 Binary files a/site/public/component-lab/images/scroll-light-top-regular-1x.png and b/site/public/component-lab/images/scroll-light-top-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-light-top-regular-2x.png b/site/public/component-lab/images/scroll-light-top-regular-2x.png index fec5a6af..6a057fbd 100644 Binary files a/site/public/component-lab/images/scroll-light-top-regular-2x.png and b/site/public/component-lab/images/scroll-light-top-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-bottom-narrow-1x.png b/site/public/component-lab/images/scroll-ocean-bottom-narrow-1x.png index 9c493609..5c3fd12f 100644 Binary files a/site/public/component-lab/images/scroll-ocean-bottom-narrow-1x.png and b/site/public/component-lab/images/scroll-ocean-bottom-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-bottom-narrow-2x.png b/site/public/component-lab/images/scroll-ocean-bottom-narrow-2x.png index d341bef3..9fdf3b84 100644 Binary files a/site/public/component-lab/images/scroll-ocean-bottom-narrow-2x.png and b/site/public/component-lab/images/scroll-ocean-bottom-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-bottom-regular-1x.png b/site/public/component-lab/images/scroll-ocean-bottom-regular-1x.png index b201c860..d688114e 100644 Binary files a/site/public/component-lab/images/scroll-ocean-bottom-regular-1x.png and b/site/public/component-lab/images/scroll-ocean-bottom-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-bottom-regular-2x.png b/site/public/component-lab/images/scroll-ocean-bottom-regular-2x.png index 078b0f00..fb665d04 100644 Binary files a/site/public/component-lab/images/scroll-ocean-bottom-regular-2x.png and b/site/public/component-lab/images/scroll-ocean-bottom-regular-2x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-top-narrow-1x.png b/site/public/component-lab/images/scroll-ocean-top-narrow-1x.png index e68e2508..b92bdae4 100644 Binary files a/site/public/component-lab/images/scroll-ocean-top-narrow-1x.png and b/site/public/component-lab/images/scroll-ocean-top-narrow-1x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-top-narrow-2x.png b/site/public/component-lab/images/scroll-ocean-top-narrow-2x.png index 2687893f..179dc45b 100644 Binary files a/site/public/component-lab/images/scroll-ocean-top-narrow-2x.png and b/site/public/component-lab/images/scroll-ocean-top-narrow-2x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-top-regular-1x.png b/site/public/component-lab/images/scroll-ocean-top-regular-1x.png index 85b98184..c5db5c2e 100644 Binary files a/site/public/component-lab/images/scroll-ocean-top-regular-1x.png and b/site/public/component-lab/images/scroll-ocean-top-regular-1x.png differ diff --git a/site/public/component-lab/images/scroll-ocean-top-regular-2x.png b/site/public/component-lab/images/scroll-ocean-top-regular-2x.png index 28608d1d..d4835d0e 100644 Binary files a/site/public/component-lab/images/scroll-ocean-top-regular-2x.png and b/site/public/component-lab/images/scroll-ocean-top-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-maximum-narrow-1x.png b/site/public/component-lab/images/slider-dark-maximum-narrow-1x.png index 16891186..0a348977 100644 Binary files a/site/public/component-lab/images/slider-dark-maximum-narrow-1x.png and b/site/public/component-lab/images/slider-dark-maximum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-maximum-narrow-2x.png b/site/public/component-lab/images/slider-dark-maximum-narrow-2x.png index 85ca1039..6d9d6978 100644 Binary files a/site/public/component-lab/images/slider-dark-maximum-narrow-2x.png and b/site/public/component-lab/images/slider-dark-maximum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-maximum-regular-1x.png b/site/public/component-lab/images/slider-dark-maximum-regular-1x.png index d0dba84a..c9838090 100644 Binary files a/site/public/component-lab/images/slider-dark-maximum-regular-1x.png and b/site/public/component-lab/images/slider-dark-maximum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-maximum-regular-2x.png b/site/public/component-lab/images/slider-dark-maximum-regular-2x.png index 86a7f206..5fe30bc3 100644 Binary files a/site/public/component-lab/images/slider-dark-maximum-regular-2x.png and b/site/public/component-lab/images/slider-dark-maximum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-middle-narrow-1x.png b/site/public/component-lab/images/slider-dark-middle-narrow-1x.png index c43e62cb..eb78b7c7 100644 Binary files a/site/public/component-lab/images/slider-dark-middle-narrow-1x.png and b/site/public/component-lab/images/slider-dark-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-middle-narrow-2x.png b/site/public/component-lab/images/slider-dark-middle-narrow-2x.png index c681a451..15feb931 100644 Binary files a/site/public/component-lab/images/slider-dark-middle-narrow-2x.png and b/site/public/component-lab/images/slider-dark-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-middle-regular-1x.png b/site/public/component-lab/images/slider-dark-middle-regular-1x.png index 24f5ce2f..10a764aa 100644 Binary files a/site/public/component-lab/images/slider-dark-middle-regular-1x.png and b/site/public/component-lab/images/slider-dark-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-middle-regular-2x.png b/site/public/component-lab/images/slider-dark-middle-regular-2x.png index 7400ee75..66c8415a 100644 Binary files a/site/public/component-lab/images/slider-dark-middle-regular-2x.png and b/site/public/component-lab/images/slider-dark-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-minimum-narrow-1x.png b/site/public/component-lab/images/slider-dark-minimum-narrow-1x.png index 775dc07c..12258103 100644 Binary files a/site/public/component-lab/images/slider-dark-minimum-narrow-1x.png and b/site/public/component-lab/images/slider-dark-minimum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-minimum-narrow-2x.png b/site/public/component-lab/images/slider-dark-minimum-narrow-2x.png index b224f0ba..ad3550a7 100644 Binary files a/site/public/component-lab/images/slider-dark-minimum-narrow-2x.png and b/site/public/component-lab/images/slider-dark-minimum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-dark-minimum-regular-1x.png b/site/public/component-lab/images/slider-dark-minimum-regular-1x.png index a4867fc6..74a74f62 100644 Binary files a/site/public/component-lab/images/slider-dark-minimum-regular-1x.png and b/site/public/component-lab/images/slider-dark-minimum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-dark-minimum-regular-2x.png b/site/public/component-lab/images/slider-dark-minimum-regular-2x.png index b00b5671..893cc1a3 100644 Binary files a/site/public/component-lab/images/slider-dark-minimum-regular-2x.png and b/site/public/component-lab/images/slider-dark-minimum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-maximum-narrow-1x.png b/site/public/component-lab/images/slider-ember-maximum-narrow-1x.png index d5d192d7..86d186ab 100644 Binary files a/site/public/component-lab/images/slider-ember-maximum-narrow-1x.png and b/site/public/component-lab/images/slider-ember-maximum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-maximum-narrow-2x.png b/site/public/component-lab/images/slider-ember-maximum-narrow-2x.png index 026f8bc4..3b3fbf12 100644 Binary files a/site/public/component-lab/images/slider-ember-maximum-narrow-2x.png and b/site/public/component-lab/images/slider-ember-maximum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-maximum-regular-1x.png b/site/public/component-lab/images/slider-ember-maximum-regular-1x.png index 7712e4f2..2ecaf56f 100644 Binary files a/site/public/component-lab/images/slider-ember-maximum-regular-1x.png and b/site/public/component-lab/images/slider-ember-maximum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-maximum-regular-2x.png b/site/public/component-lab/images/slider-ember-maximum-regular-2x.png index 794c82dd..8cb753bb 100644 Binary files a/site/public/component-lab/images/slider-ember-maximum-regular-2x.png and b/site/public/component-lab/images/slider-ember-maximum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-middle-narrow-1x.png b/site/public/component-lab/images/slider-ember-middle-narrow-1x.png index d1e8a4ba..da6b757f 100644 Binary files a/site/public/component-lab/images/slider-ember-middle-narrow-1x.png and b/site/public/component-lab/images/slider-ember-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-middle-narrow-2x.png b/site/public/component-lab/images/slider-ember-middle-narrow-2x.png index e7602ad8..c9320a23 100644 Binary files a/site/public/component-lab/images/slider-ember-middle-narrow-2x.png and b/site/public/component-lab/images/slider-ember-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-middle-regular-1x.png b/site/public/component-lab/images/slider-ember-middle-regular-1x.png index 520509dd..707d82f3 100644 Binary files a/site/public/component-lab/images/slider-ember-middle-regular-1x.png and b/site/public/component-lab/images/slider-ember-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-middle-regular-2x.png b/site/public/component-lab/images/slider-ember-middle-regular-2x.png index ce9c8d16..374787d7 100644 Binary files a/site/public/component-lab/images/slider-ember-middle-regular-2x.png and b/site/public/component-lab/images/slider-ember-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-minimum-narrow-1x.png b/site/public/component-lab/images/slider-ember-minimum-narrow-1x.png index 5e081d0f..fc1dd6c6 100644 Binary files a/site/public/component-lab/images/slider-ember-minimum-narrow-1x.png and b/site/public/component-lab/images/slider-ember-minimum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-minimum-narrow-2x.png b/site/public/component-lab/images/slider-ember-minimum-narrow-2x.png index 578e9a0b..f2fdaf93 100644 Binary files a/site/public/component-lab/images/slider-ember-minimum-narrow-2x.png and b/site/public/component-lab/images/slider-ember-minimum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ember-minimum-regular-1x.png b/site/public/component-lab/images/slider-ember-minimum-regular-1x.png index a84195d4..b79d5b08 100644 Binary files a/site/public/component-lab/images/slider-ember-minimum-regular-1x.png and b/site/public/component-lab/images/slider-ember-minimum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ember-minimum-regular-2x.png b/site/public/component-lab/images/slider-ember-minimum-regular-2x.png index 54ae9e4d..90ee522d 100644 Binary files a/site/public/component-lab/images/slider-ember-minimum-regular-2x.png and b/site/public/component-lab/images/slider-ember-minimum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-maximum-narrow-1x.png b/site/public/component-lab/images/slider-forest-maximum-narrow-1x.png index 4429621b..aa7f65be 100644 Binary files a/site/public/component-lab/images/slider-forest-maximum-narrow-1x.png and b/site/public/component-lab/images/slider-forest-maximum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-maximum-narrow-2x.png b/site/public/component-lab/images/slider-forest-maximum-narrow-2x.png index 5f9eb7b1..55c450c2 100644 Binary files a/site/public/component-lab/images/slider-forest-maximum-narrow-2x.png and b/site/public/component-lab/images/slider-forest-maximum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-maximum-regular-1x.png b/site/public/component-lab/images/slider-forest-maximum-regular-1x.png index 328ed929..fab929f2 100644 Binary files a/site/public/component-lab/images/slider-forest-maximum-regular-1x.png and b/site/public/component-lab/images/slider-forest-maximum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-maximum-regular-2x.png b/site/public/component-lab/images/slider-forest-maximum-regular-2x.png index 9cb6b60f..34489029 100644 Binary files a/site/public/component-lab/images/slider-forest-maximum-regular-2x.png and b/site/public/component-lab/images/slider-forest-maximum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-middle-narrow-1x.png b/site/public/component-lab/images/slider-forest-middle-narrow-1x.png index 64f038c3..d7a30004 100644 Binary files a/site/public/component-lab/images/slider-forest-middle-narrow-1x.png and b/site/public/component-lab/images/slider-forest-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-middle-narrow-2x.png b/site/public/component-lab/images/slider-forest-middle-narrow-2x.png index 22cbcef9..3a84fba0 100644 Binary files a/site/public/component-lab/images/slider-forest-middle-narrow-2x.png and b/site/public/component-lab/images/slider-forest-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-middle-regular-1x.png b/site/public/component-lab/images/slider-forest-middle-regular-1x.png index 78f55b5e..336f2be2 100644 Binary files a/site/public/component-lab/images/slider-forest-middle-regular-1x.png and b/site/public/component-lab/images/slider-forest-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-middle-regular-2x.png b/site/public/component-lab/images/slider-forest-middle-regular-2x.png index 127fe6f9..663e57e1 100644 Binary files a/site/public/component-lab/images/slider-forest-middle-regular-2x.png and b/site/public/component-lab/images/slider-forest-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-minimum-narrow-1x.png b/site/public/component-lab/images/slider-forest-minimum-narrow-1x.png index b8935245..1aa1eb18 100644 Binary files a/site/public/component-lab/images/slider-forest-minimum-narrow-1x.png and b/site/public/component-lab/images/slider-forest-minimum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-minimum-narrow-2x.png b/site/public/component-lab/images/slider-forest-minimum-narrow-2x.png index 7e5fc2e1..4c9693e7 100644 Binary files a/site/public/component-lab/images/slider-forest-minimum-narrow-2x.png and b/site/public/component-lab/images/slider-forest-minimum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-forest-minimum-regular-1x.png b/site/public/component-lab/images/slider-forest-minimum-regular-1x.png index 88028b2c..e36f4a4b 100644 Binary files a/site/public/component-lab/images/slider-forest-minimum-regular-1x.png and b/site/public/component-lab/images/slider-forest-minimum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-forest-minimum-regular-2x.png b/site/public/component-lab/images/slider-forest-minimum-regular-2x.png index 3acb7508..bcb85007 100644 Binary files a/site/public/component-lab/images/slider-forest-minimum-regular-2x.png and b/site/public/component-lab/images/slider-forest-minimum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-light-maximum-narrow-1x.png b/site/public/component-lab/images/slider-light-maximum-narrow-1x.png index c0260a4a..a569a5c6 100644 Binary files a/site/public/component-lab/images/slider-light-maximum-narrow-1x.png and b/site/public/component-lab/images/slider-light-maximum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-light-maximum-narrow-2x.png b/site/public/component-lab/images/slider-light-maximum-narrow-2x.png index 30691f14..742ffe1c 100644 Binary files a/site/public/component-lab/images/slider-light-maximum-narrow-2x.png and b/site/public/component-lab/images/slider-light-maximum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-light-maximum-regular-1x.png b/site/public/component-lab/images/slider-light-maximum-regular-1x.png index 0ade2979..383440c9 100644 Binary files a/site/public/component-lab/images/slider-light-maximum-regular-1x.png and b/site/public/component-lab/images/slider-light-maximum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-light-maximum-regular-2x.png b/site/public/component-lab/images/slider-light-maximum-regular-2x.png index 0165e295..68f1da3f 100644 Binary files a/site/public/component-lab/images/slider-light-maximum-regular-2x.png and b/site/public/component-lab/images/slider-light-maximum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-light-middle-narrow-1x.png b/site/public/component-lab/images/slider-light-middle-narrow-1x.png index b2fb6db1..94b4f034 100644 Binary files a/site/public/component-lab/images/slider-light-middle-narrow-1x.png and b/site/public/component-lab/images/slider-light-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-light-middle-narrow-2x.png b/site/public/component-lab/images/slider-light-middle-narrow-2x.png index b3266c84..5681c1ba 100644 Binary files a/site/public/component-lab/images/slider-light-middle-narrow-2x.png and b/site/public/component-lab/images/slider-light-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-light-middle-regular-1x.png b/site/public/component-lab/images/slider-light-middle-regular-1x.png index 0fa3cd79..a97c7ab8 100644 Binary files a/site/public/component-lab/images/slider-light-middle-regular-1x.png and b/site/public/component-lab/images/slider-light-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-light-middle-regular-2x.png b/site/public/component-lab/images/slider-light-middle-regular-2x.png index 434eb79c..b2a46b4f 100644 Binary files a/site/public/component-lab/images/slider-light-middle-regular-2x.png and b/site/public/component-lab/images/slider-light-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-light-minimum-narrow-1x.png b/site/public/component-lab/images/slider-light-minimum-narrow-1x.png index 3946d486..4f901436 100644 Binary files a/site/public/component-lab/images/slider-light-minimum-narrow-1x.png and b/site/public/component-lab/images/slider-light-minimum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-light-minimum-narrow-2x.png b/site/public/component-lab/images/slider-light-minimum-narrow-2x.png index a2257c4e..7fa5f3c6 100644 Binary files a/site/public/component-lab/images/slider-light-minimum-narrow-2x.png and b/site/public/component-lab/images/slider-light-minimum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-light-minimum-regular-1x.png b/site/public/component-lab/images/slider-light-minimum-regular-1x.png index cd42bc11..d75be27c 100644 Binary files a/site/public/component-lab/images/slider-light-minimum-regular-1x.png and b/site/public/component-lab/images/slider-light-minimum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-light-minimum-regular-2x.png b/site/public/component-lab/images/slider-light-minimum-regular-2x.png index 11f1a6da..3d9ba0a9 100644 Binary files a/site/public/component-lab/images/slider-light-minimum-regular-2x.png and b/site/public/component-lab/images/slider-light-minimum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-maximum-narrow-1x.png b/site/public/component-lab/images/slider-ocean-maximum-narrow-1x.png index fd7c2dc8..913f9fc0 100644 Binary files a/site/public/component-lab/images/slider-ocean-maximum-narrow-1x.png and b/site/public/component-lab/images/slider-ocean-maximum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-maximum-narrow-2x.png b/site/public/component-lab/images/slider-ocean-maximum-narrow-2x.png index 06d171aa..fe97471f 100644 Binary files a/site/public/component-lab/images/slider-ocean-maximum-narrow-2x.png and b/site/public/component-lab/images/slider-ocean-maximum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-maximum-regular-1x.png b/site/public/component-lab/images/slider-ocean-maximum-regular-1x.png index 12e125a1..9bf4b0e1 100644 Binary files a/site/public/component-lab/images/slider-ocean-maximum-regular-1x.png and b/site/public/component-lab/images/slider-ocean-maximum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-maximum-regular-2x.png b/site/public/component-lab/images/slider-ocean-maximum-regular-2x.png index 6c5bde73..bd2ae312 100644 Binary files a/site/public/component-lab/images/slider-ocean-maximum-regular-2x.png and b/site/public/component-lab/images/slider-ocean-maximum-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-middle-narrow-1x.png b/site/public/component-lab/images/slider-ocean-middle-narrow-1x.png index fe395074..efed7954 100644 Binary files a/site/public/component-lab/images/slider-ocean-middle-narrow-1x.png and b/site/public/component-lab/images/slider-ocean-middle-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-middle-narrow-2x.png b/site/public/component-lab/images/slider-ocean-middle-narrow-2x.png index 857934c3..2d8f2f69 100644 Binary files a/site/public/component-lab/images/slider-ocean-middle-narrow-2x.png and b/site/public/component-lab/images/slider-ocean-middle-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-middle-regular-1x.png b/site/public/component-lab/images/slider-ocean-middle-regular-1x.png index d8f0b635..1b1f9e7a 100644 Binary files a/site/public/component-lab/images/slider-ocean-middle-regular-1x.png and b/site/public/component-lab/images/slider-ocean-middle-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-middle-regular-2x.png b/site/public/component-lab/images/slider-ocean-middle-regular-2x.png index fd630960..6ef3b98c 100644 Binary files a/site/public/component-lab/images/slider-ocean-middle-regular-2x.png and b/site/public/component-lab/images/slider-ocean-middle-regular-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-minimum-narrow-1x.png b/site/public/component-lab/images/slider-ocean-minimum-narrow-1x.png index 7d1a2958..65e57b6c 100644 Binary files a/site/public/component-lab/images/slider-ocean-minimum-narrow-1x.png and b/site/public/component-lab/images/slider-ocean-minimum-narrow-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-minimum-narrow-2x.png b/site/public/component-lab/images/slider-ocean-minimum-narrow-2x.png index cb2dbdc3..12cabcdc 100644 Binary files a/site/public/component-lab/images/slider-ocean-minimum-narrow-2x.png and b/site/public/component-lab/images/slider-ocean-minimum-narrow-2x.png differ diff --git a/site/public/component-lab/images/slider-ocean-minimum-regular-1x.png b/site/public/component-lab/images/slider-ocean-minimum-regular-1x.png index 58af57fa..cca9b194 100644 Binary files a/site/public/component-lab/images/slider-ocean-minimum-regular-1x.png and b/site/public/component-lab/images/slider-ocean-minimum-regular-1x.png differ diff --git a/site/public/component-lab/images/slider-ocean-minimum-regular-2x.png b/site/public/component-lab/images/slider-ocean-minimum-regular-2x.png index d8a89a77..16190a07 100644 Binary files a/site/public/component-lab/images/slider-ocean-minimum-regular-2x.png and b/site/public/component-lab/images/slider-ocean-minimum-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-dark-off-narrow-1x.png b/site/public/component-lab/images/toggle-dark-off-narrow-1x.png index 088e9a5f..ca38f0c7 100644 Binary files a/site/public/component-lab/images/toggle-dark-off-narrow-1x.png and b/site/public/component-lab/images/toggle-dark-off-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-dark-off-narrow-2x.png b/site/public/component-lab/images/toggle-dark-off-narrow-2x.png index bfbe969d..506ead0e 100644 Binary files a/site/public/component-lab/images/toggle-dark-off-narrow-2x.png and b/site/public/component-lab/images/toggle-dark-off-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-dark-off-regular-1x.png b/site/public/component-lab/images/toggle-dark-off-regular-1x.png index 4d47aa64..820e9137 100644 Binary files a/site/public/component-lab/images/toggle-dark-off-regular-1x.png and b/site/public/component-lab/images/toggle-dark-off-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-dark-off-regular-2x.png b/site/public/component-lab/images/toggle-dark-off-regular-2x.png index d6eb445b..b6e0247b 100644 Binary files a/site/public/component-lab/images/toggle-dark-off-regular-2x.png and b/site/public/component-lab/images/toggle-dark-off-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-dark-on-narrow-1x.png b/site/public/component-lab/images/toggle-dark-on-narrow-1x.png index 27f952e0..c5ffdc06 100644 Binary files a/site/public/component-lab/images/toggle-dark-on-narrow-1x.png and b/site/public/component-lab/images/toggle-dark-on-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-dark-on-narrow-2x.png b/site/public/component-lab/images/toggle-dark-on-narrow-2x.png index 2c1cbed9..0668167f 100644 Binary files a/site/public/component-lab/images/toggle-dark-on-narrow-2x.png and b/site/public/component-lab/images/toggle-dark-on-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-dark-on-regular-1x.png b/site/public/component-lab/images/toggle-dark-on-regular-1x.png index d2dd1732..a12e0f95 100644 Binary files a/site/public/component-lab/images/toggle-dark-on-regular-1x.png and b/site/public/component-lab/images/toggle-dark-on-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-dark-on-regular-2x.png b/site/public/component-lab/images/toggle-dark-on-regular-2x.png index 05448f3c..8cd17643 100644 Binary files a/site/public/component-lab/images/toggle-dark-on-regular-2x.png and b/site/public/component-lab/images/toggle-dark-on-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-ember-off-narrow-1x.png b/site/public/component-lab/images/toggle-ember-off-narrow-1x.png index 41038fc5..46ca7d70 100644 Binary files a/site/public/component-lab/images/toggle-ember-off-narrow-1x.png and b/site/public/component-lab/images/toggle-ember-off-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-ember-off-narrow-2x.png b/site/public/component-lab/images/toggle-ember-off-narrow-2x.png index 21bf01d4..bb3ff56d 100644 Binary files a/site/public/component-lab/images/toggle-ember-off-narrow-2x.png and b/site/public/component-lab/images/toggle-ember-off-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-ember-off-regular-1x.png b/site/public/component-lab/images/toggle-ember-off-regular-1x.png index 06169bd8..f7883e5d 100644 Binary files a/site/public/component-lab/images/toggle-ember-off-regular-1x.png and b/site/public/component-lab/images/toggle-ember-off-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-ember-off-regular-2x.png b/site/public/component-lab/images/toggle-ember-off-regular-2x.png index 04f98b99..46c872fd 100644 Binary files a/site/public/component-lab/images/toggle-ember-off-regular-2x.png and b/site/public/component-lab/images/toggle-ember-off-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-ember-on-narrow-1x.png b/site/public/component-lab/images/toggle-ember-on-narrow-1x.png index 7dcda5c2..a74082e1 100644 Binary files a/site/public/component-lab/images/toggle-ember-on-narrow-1x.png and b/site/public/component-lab/images/toggle-ember-on-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-ember-on-narrow-2x.png b/site/public/component-lab/images/toggle-ember-on-narrow-2x.png index 18510555..5ced6333 100644 Binary files a/site/public/component-lab/images/toggle-ember-on-narrow-2x.png and b/site/public/component-lab/images/toggle-ember-on-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-ember-on-regular-1x.png b/site/public/component-lab/images/toggle-ember-on-regular-1x.png index 7bb6fc32..ff85e344 100644 Binary files a/site/public/component-lab/images/toggle-ember-on-regular-1x.png and b/site/public/component-lab/images/toggle-ember-on-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-ember-on-regular-2x.png b/site/public/component-lab/images/toggle-ember-on-regular-2x.png index 3f23c132..07b18090 100644 Binary files a/site/public/component-lab/images/toggle-ember-on-regular-2x.png and b/site/public/component-lab/images/toggle-ember-on-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-forest-off-narrow-1x.png b/site/public/component-lab/images/toggle-forest-off-narrow-1x.png index e0fdcf41..725917f1 100644 Binary files a/site/public/component-lab/images/toggle-forest-off-narrow-1x.png and b/site/public/component-lab/images/toggle-forest-off-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-forest-off-narrow-2x.png b/site/public/component-lab/images/toggle-forest-off-narrow-2x.png index fb8584f9..1d4b1914 100644 Binary files a/site/public/component-lab/images/toggle-forest-off-narrow-2x.png and b/site/public/component-lab/images/toggle-forest-off-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-forest-off-regular-1x.png b/site/public/component-lab/images/toggle-forest-off-regular-1x.png index ddba7f2d..f279fb01 100644 Binary files a/site/public/component-lab/images/toggle-forest-off-regular-1x.png and b/site/public/component-lab/images/toggle-forest-off-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-forest-off-regular-2x.png b/site/public/component-lab/images/toggle-forest-off-regular-2x.png index 897f6fe6..b4ea1eaa 100644 Binary files a/site/public/component-lab/images/toggle-forest-off-regular-2x.png and b/site/public/component-lab/images/toggle-forest-off-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-forest-on-narrow-1x.png b/site/public/component-lab/images/toggle-forest-on-narrow-1x.png index fe977b3c..3d327887 100644 Binary files a/site/public/component-lab/images/toggle-forest-on-narrow-1x.png and b/site/public/component-lab/images/toggle-forest-on-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-forest-on-narrow-2x.png b/site/public/component-lab/images/toggle-forest-on-narrow-2x.png index 77cda138..2e3322ad 100644 Binary files a/site/public/component-lab/images/toggle-forest-on-narrow-2x.png and b/site/public/component-lab/images/toggle-forest-on-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-forest-on-regular-1x.png b/site/public/component-lab/images/toggle-forest-on-regular-1x.png index aa6a8bac..ffca69bc 100644 Binary files a/site/public/component-lab/images/toggle-forest-on-regular-1x.png and b/site/public/component-lab/images/toggle-forest-on-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-forest-on-regular-2x.png b/site/public/component-lab/images/toggle-forest-on-regular-2x.png index 256591c9..6720c7e8 100644 Binary files a/site/public/component-lab/images/toggle-forest-on-regular-2x.png and b/site/public/component-lab/images/toggle-forest-on-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-light-off-narrow-1x.png b/site/public/component-lab/images/toggle-light-off-narrow-1x.png index 690664df..535b6f02 100644 Binary files a/site/public/component-lab/images/toggle-light-off-narrow-1x.png and b/site/public/component-lab/images/toggle-light-off-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-light-off-narrow-2x.png b/site/public/component-lab/images/toggle-light-off-narrow-2x.png index 8347b7ad..a563d2e0 100644 Binary files a/site/public/component-lab/images/toggle-light-off-narrow-2x.png and b/site/public/component-lab/images/toggle-light-off-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-light-off-regular-1x.png b/site/public/component-lab/images/toggle-light-off-regular-1x.png index cb41448f..4dc4c6d1 100644 Binary files a/site/public/component-lab/images/toggle-light-off-regular-1x.png and b/site/public/component-lab/images/toggle-light-off-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-light-off-regular-2x.png b/site/public/component-lab/images/toggle-light-off-regular-2x.png index e67dcd9f..2830c2e1 100644 Binary files a/site/public/component-lab/images/toggle-light-off-regular-2x.png and b/site/public/component-lab/images/toggle-light-off-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-light-on-narrow-1x.png b/site/public/component-lab/images/toggle-light-on-narrow-1x.png index 055453ec..6dcc08bd 100644 Binary files a/site/public/component-lab/images/toggle-light-on-narrow-1x.png and b/site/public/component-lab/images/toggle-light-on-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-light-on-narrow-2x.png b/site/public/component-lab/images/toggle-light-on-narrow-2x.png index 69238284..1b16ef85 100644 Binary files a/site/public/component-lab/images/toggle-light-on-narrow-2x.png and b/site/public/component-lab/images/toggle-light-on-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-light-on-regular-1x.png b/site/public/component-lab/images/toggle-light-on-regular-1x.png index 5dee88b5..f2736d33 100644 Binary files a/site/public/component-lab/images/toggle-light-on-regular-1x.png and b/site/public/component-lab/images/toggle-light-on-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-light-on-regular-2x.png b/site/public/component-lab/images/toggle-light-on-regular-2x.png index 59f30873..41fbd3dd 100644 Binary files a/site/public/component-lab/images/toggle-light-on-regular-2x.png and b/site/public/component-lab/images/toggle-light-on-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-off-narrow-1x.png b/site/public/component-lab/images/toggle-ocean-off-narrow-1x.png index 3d0cbf4d..f1d83b9c 100644 Binary files a/site/public/component-lab/images/toggle-ocean-off-narrow-1x.png and b/site/public/component-lab/images/toggle-ocean-off-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-off-narrow-2x.png b/site/public/component-lab/images/toggle-ocean-off-narrow-2x.png index aebc2c28..55fe84c4 100644 Binary files a/site/public/component-lab/images/toggle-ocean-off-narrow-2x.png and b/site/public/component-lab/images/toggle-ocean-off-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-off-regular-1x.png b/site/public/component-lab/images/toggle-ocean-off-regular-1x.png index 5ca75330..ede05ac8 100644 Binary files a/site/public/component-lab/images/toggle-ocean-off-regular-1x.png and b/site/public/component-lab/images/toggle-ocean-off-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-off-regular-2x.png b/site/public/component-lab/images/toggle-ocean-off-regular-2x.png index 0ed74e02..a65dcdf4 100644 Binary files a/site/public/component-lab/images/toggle-ocean-off-regular-2x.png and b/site/public/component-lab/images/toggle-ocean-off-regular-2x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-on-narrow-1x.png b/site/public/component-lab/images/toggle-ocean-on-narrow-1x.png index 78c3aee8..c06011d3 100644 Binary files a/site/public/component-lab/images/toggle-ocean-on-narrow-1x.png and b/site/public/component-lab/images/toggle-ocean-on-narrow-1x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-on-narrow-2x.png b/site/public/component-lab/images/toggle-ocean-on-narrow-2x.png index e6b6269f..dbb1a4ab 100644 Binary files a/site/public/component-lab/images/toggle-ocean-on-narrow-2x.png and b/site/public/component-lab/images/toggle-ocean-on-narrow-2x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-on-regular-1x.png b/site/public/component-lab/images/toggle-ocean-on-regular-1x.png index 7751300a..6d59a760 100644 Binary files a/site/public/component-lab/images/toggle-ocean-on-regular-1x.png and b/site/public/component-lab/images/toggle-ocean-on-regular-1x.png differ diff --git a/site/public/component-lab/images/toggle-ocean-on-regular-2x.png b/site/public/component-lab/images/toggle-ocean-on-regular-2x.png index bc0856e1..4ee05240 100644 Binary files a/site/public/component-lab/images/toggle-ocean-on-regular-2x.png and b/site/public/component-lab/images/toggle-ocean-on-regular-2x.png differ diff --git a/site/public/component-lab/manifest.json b/site/public/component-lab/manifest.json index ab9bf077..7e047424 100644 --- a/site/public/component-lab/manifest.json +++ b/site/public/component-lab/manifest.json @@ -26,7 +26,7 @@ "inputs": { "configs/lucent/palettes.json": "8cbcea6386bb65f92673d48a379df869b417d0b45d2a6af8f9fc12d911870c3b", "design/tokens.json": "6bca133253d845990df42b847b33b921d7c6d29c85c3f298516bd30a1c78fd44", - "lucent/Cargo.lock": "9ee99922ec5d1fabfcc30618b97a5907796df2a3ad05eb6ce60e77a57a2dd340", + "lucent/Cargo.lock": "159d7cb9aba0726fae8d0d5089e104c54538ee83c63052481b4dde48df78766b", "lucent/Cargo.toml": "07968fb527905a09bdacb6302f2ff5901df101985eeadc53d48751351be3c68f", "lucent/apps/lucent-desktop/assets/LucentDisplay.ttf": "3e40a6e1feae6e125aef026cc29057fcd7ddf0d1302b2a3ac8b53738d6a45535", "lucent/apps/lucent-desktop/assets/LucentSans.ttf": "ecaf4fa883c8a1367af3a154584c3e5db0424046c0aad553f11098bada589494", @@ -37,7 +37,7 @@ "lucent/apps/lucent-lab/src/stories.rs": "25186bfddd1aaf2ed6014bfe1835b4453907ff71354d75766de841be81ed6791", "lucent/apps/lucent-lab/src/tests.rs": "b98b6df9c524597d8d0690fd0f49c970c8862f7272ff424dc6a8196ae06ada54", "lucent/apps/lucent-menu/Cargo.toml": "e3cbe5f27d59a7e638ad22041e27b2dbec4d68658964ae45c60e91a0622ea986", - "lucent/apps/lucent-menu/src/lib.rs": "ad01875b1a8cc64015dd08721af89b62fbb56d2c8e23ab220531903836e2ebb0", + "lucent/apps/lucent-menu/src/lib.rs": "14a040d00298fd04a355332e1c728a826000973256b509107269a8a2d3e11f21", "lucent/apps/lucent-menu/src/main.rs": "5647761585b12eda5bd907f558c8c51de51c991b03d0a48f6b2a80c8a2d37f92", "lucent/crates/lucent-api/Cargo.toml": "080d7f28845d04f37483d2461c5db3e17f951e366b78520fb6751503fc82f4cb", "lucent/crates/lucent-api/src/activation.rs": "1aef399526d35ffe8345e1260316d4c75a20db4b29499e6b5de00f61bc023c45", @@ -47,7 +47,8 @@ "lucent/crates/lucent-api/src/image.rs": "61bb4429ea95f7e21787bc6982263f73603d909583c8fac96b380c89547fdaca", "lucent/crates/lucent-api/src/input.rs": "b1e2334a2d5a56c73655dd1285483165a76a48a9dd97c2fb487e3f32bea6dbf2", "lucent/crates/lucent-api/src/input_release.rs": "7a06cf7d62c9f638bf068deab5978d9e02043dcc0b754cd28c9571f42914768a", - "lucent/crates/lucent-api/src/lib.rs": "bac450ac84779d5296dab510a0ec7f051799d6f27672204eb06fc9803356e21f", + "lucent/crates/lucent-api/src/keyboard_focus.rs": "81dec987b7213682b047ba05d98e55d86a5742c1aba803df220ac56f189b7612", + "lucent/crates/lucent-api/src/lib.rs": "61e5c2763e0366f5032c437f93d369f9abe0ba5bff0e6fbaa38f594673592915", "lucent/crates/lucent-api/src/output.rs": "3ff5263afa02aafd92227dfd62505c0323b9e0a8282fc29841224d852b57cbb7", "lucent/crates/lucent-api/src/overlay.rs": "80d05aa5e827cea67a56d082fc55d0ada59eaa9432ab88d45ff969443d4e582d", "lucent/crates/lucent-api/src/rich_text.rs": "7254217b6b5391ed752f1195c40f575edf0891b7e96abf1bca121c7f177b2c7e", @@ -114,11 +115,13 @@ "lucent/crates/lucent-ui/assets/fallback-fonts.json": "436a74324211c317d3c7f8e95a4cf2c384b2555189c2a3122676695dc9d2d98b", "lucent/crates/lucent-ui/assets/test-fonts.json": "72ffe688515b399195307f0f7a6eda9a518e37797eb450c8bf7bf7fc9f71c0f4", "lucent/crates/lucent-ui/src/composition.rs": "92ca56833fa3756f944c4f2174dff2d883f1c7d683a09ef013a74b9380b288aa", + "lucent/crates/lucent-ui/src/focus_presentation.rs": "18e336ea5e38dc510a8b2edc8e3400c30491206b8a2bb94c07b3abac5e83cac4", "lucent/crates/lucent-ui/src/input_tests.rs": "15afe37be6b7ee43d2b179da14f0920037058f95523d9e9ee7532ad8498cd73e", - "lucent/crates/lucent-ui/src/lib.rs": "7eb363c8bcd0c4c0dd3b558f4d68f0be6bfbfe7806b11c122614b843c0b0edd6", - "lucent/crates/lucent-ui/src/overlay.rs": "876f4093ce5cacc221bfe5aa0488d4c43518c426819d1115d472c2f387d4d5cd", + "lucent/crates/lucent-ui/src/lib.rs": "c1764dc96902bad53f7de08954833f78dc8c1f3bad54365e680e7a8950c7091b", + "lucent/crates/lucent-ui/src/overlay.rs": "3b7250eb6acfce4356a96b5661dccf8e463923165e64b7fc6ef7d8ff40abb59d", "lucent/crates/lucent-ui/src/pointer.rs": "a04926f1690aceb5d6107ad353c58ee294d4fda3a3b3050a9957bdc7a57bbe2f", - "lucent/crates/lucent-ui/src/rich_text.rs": "03a1f4f35492a4a9a3bb0f80e082a1550a8883d3feddc2d9ea117c2acef6c05d", + "lucent/crates/lucent-ui/src/press_observation.rs": "8ec567919277f301926bf33e11101ea744f08b142254e8353b46b8582d95cdd9", + "lucent/crates/lucent-ui/src/rich_text.rs": "d324706c2f2f6c436fab9f593a94298e78d289173b81e1da61a8da7d91d5a297", "lucent/crates/lucent-ui/src/scroll.rs": "89b1ac7bb3a4db3fb39f238d432d9e0100b31f0cf6f9690f09cc299378ca47c5", "lucent/crates/lucent-ui/src/slider.rs": "7b761d0ee1e0038b4da680942416d4ecef533fae0e9364586213d40694a76c94", "lucent/crates/lucent-ui/src/text.rs": "f289f81a5bef1e62d7c7f42198731d3274fd4129cb04fcb991dff2bed7f3a423", @@ -144,7 +147,7 @@ "lucent/crates/lucent-usecases/src/widgets.rs": "146a59d9911213f6b9ced12f3b5eec8d8295c318faff161f0d9e4f942cc284b0" }, "scope": "offscreen-native", - "source_commit": "3640bd86c6ec9115cd71c6afacaedea78f6e94d9", + "source_commit": "ba5b8a51f960e07507520a77534d1eccbce9e40c", "token_sha256": "6bca133253d845990df42b847b33b921d7c6d29c85c3f298516bd30a1c78fd44" }, "schema_version": 1, @@ -176,7 +179,7 @@ "image": { "height": 512, "path": "images/buttons-dark-default-regular-1x.png", - "sha256": "eb1ca2b35747edfbfbc96b1518c0dd8087898d88f27fb37fb6fb9155df2e35ef", + "sha256": "788e1de5be373e6b2bafefd002b759822c8062b4d29ba853a1a52a638fc71c75", "width": 800 }, "palette": "dark", @@ -197,7 +200,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-default-regular-2x.png", - "sha256": "6d410ec691eff5fbd5c900f990b068958766d7bb4d27e889888a42ffe0259c5a", + "sha256": "1c97106bceaa9cce8e75a6d7f05341a0b64f40cbc7749dadbd02e798c3667e5f", "width": 1600 }, "palette": "dark", @@ -218,7 +221,7 @@ "image": { "height": 512, "path": "images/buttons-dark-default-narrow-1x.png", - "sha256": "f27c0823572b012607de96e1e98a923d7e1297d9d8348f2eb98f765d8df1f836", + "sha256": "da85adb8d24831ace498edde64ec3ed5db5366e04b2e70c5534b7f27a1881b18", "width": 352 }, "palette": "dark", @@ -239,7 +242,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-default-narrow-2x.png", - "sha256": "924804917c4d8a16bcee26affddc116ee84a609d9d01a271e4ba343319628858", + "sha256": "09ffa7a802430486ddb9aa2407caa54122c7812bb8565b77470d8444a436b826", "width": 704 }, "palette": "dark", @@ -260,7 +263,7 @@ "image": { "height": 512, "path": "images/buttons-dark-hover-regular-1x.png", - "sha256": "d10058157b4634caad33b4b7254e570117712ca3a4490c7f6ffb9064dd32cf27", + "sha256": "ac13421bb265a05e70cb7e3bc7c64b5e68f82a4005029bddc4414fc54f4d9ea3", "width": 800 }, "palette": "dark", @@ -281,7 +284,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-hover-regular-2x.png", - "sha256": "8bee9042d513bb07ce3237531a194ed14ce612b8844140ed8d12796e699fd7fd", + "sha256": "2215e85678e61ac5c6d772a062d753416f53c5868a8573457377f47d39063fa3", "width": 1600 }, "palette": "dark", @@ -302,7 +305,7 @@ "image": { "height": 512, "path": "images/buttons-dark-hover-narrow-1x.png", - "sha256": "84aba9580ca9d5fc5c7c9f6ad3249ffbd2791b5308dc7bde50b9f2872781300c", + "sha256": "8dab5c540e7f9412f240ff6a0a2f670a3f288fd41bd7699f3a33d77f06b32fab", "width": 352 }, "palette": "dark", @@ -323,7 +326,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-hover-narrow-2x.png", - "sha256": "b4544559667866d764365da2005b36ef122ef5702fa3f035bd3bce452dbb11c5", + "sha256": "3b0ca97f2fb95ae10ba47b242ecf05503e9557d5ed925880789ebb5b61f6daa9", "width": 704 }, "palette": "dark", @@ -344,7 +347,7 @@ "image": { "height": 512, "path": "images/buttons-dark-focus-regular-1x.png", - "sha256": "d1baae166bdf7fe2036c380055d8f5a4419090f74b6ae617602d5129ff93a2a4", + "sha256": "63d3f6adfd8af84cd0309f1c769f8a2d042fddb738e47c8faa7826b85d1ba19d", "width": 800 }, "palette": "dark", @@ -365,7 +368,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-focus-regular-2x.png", - "sha256": "f0afbbe85723e0f89d4adc090fc89b7b93aac285e08ea0d2510650c78a5a58d8", + "sha256": "e6c561a7b47c3ba1d09686e1df3e78c13a7ad77a416fd4f2f038527dbbf0a31c", "width": 1600 }, "palette": "dark", @@ -386,7 +389,7 @@ "image": { "height": 512, "path": "images/buttons-dark-focus-narrow-1x.png", - "sha256": "a92b1a5f454bb48216ee3e787f5d41f891828333923beaf386ff0f4f3f1e6ad8", + "sha256": "bff4f27e39d393a94e598e85fee17433c2533300088528de2569a1b417a1b38c", "width": 352 }, "palette": "dark", @@ -407,7 +410,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-focus-narrow-2x.png", - "sha256": "96e1b2980c6f63ade01b43400fe5c43df64d1e8dd15a5991381de05c339bb1e3", + "sha256": "c9c328a9f6befc05701f7f7985a41ffd224a422ce8b57d47ea7af8d5a971da46", "width": 704 }, "palette": "dark", @@ -428,7 +431,7 @@ "image": { "height": 512, "path": "images/buttons-dark-disabled-regular-1x.png", - "sha256": "0623df6428c8eb034d5fa790f5ac28d09a8be1b7e6f6656927e39958de04500e", + "sha256": "c05ef3936980dabcfc45cdd61c87e243a1dd4ef15c085981847a69c5a5369689", "width": 800 }, "palette": "dark", @@ -449,7 +452,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-disabled-regular-2x.png", - "sha256": "0a7783ff3a95056aecaee967738dd6a6cb98986e37252a3a2da6a2d01baa46af", + "sha256": "271a7eae344065c0081f9ccb8e042b905d77472de316b7290ab1c6c5a8fe57c9", "width": 1600 }, "palette": "dark", @@ -470,7 +473,7 @@ "image": { "height": 512, "path": "images/buttons-dark-disabled-narrow-1x.png", - "sha256": "d57a32023266c08f00b243b6e386c4b4ae07e7e19a9aac891acb4c7e2b4f0f43", + "sha256": "172e271db20edf530598c475c159aab3bdbd007ddb1348b0bc40992e6319d8ec", "width": 352 }, "palette": "dark", @@ -491,7 +494,7 @@ "image": { "height": 1024, "path": "images/buttons-dark-disabled-narrow-2x.png", - "sha256": "c8270ce713e2b9451a74d61c2627e75b70ad3c2e529421b3ef99ae53ecfedffb", + "sha256": "44270f50dc251d336c12e243e592b0cb2f5c932b06dc0354c6142b9482711cd9", "width": 704 }, "palette": "dark", @@ -512,7 +515,7 @@ "image": { "height": 512, "path": "images/buttons-light-default-regular-1x.png", - "sha256": "1d1b6248998e9e43dd7b944e20edeb3c2d6b256ab53bf0292d4d9e9e08239c83", + "sha256": "6af8d1856a832d756eba9ea71a436ead093661d2eb2434409233aa690735c339", "width": 800 }, "palette": "light", @@ -533,7 +536,7 @@ "image": { "height": 1024, "path": "images/buttons-light-default-regular-2x.png", - "sha256": "3ed46c461b3fa86d6aaf2d250a25328e3f7cc680b2f41246d1be1fb0d849a6eb", + "sha256": "ac58c90370d8c10a28dee521f4aa51ccf1b407d706a2a698df2390d291fb48d8", "width": 1600 }, "palette": "light", @@ -554,7 +557,7 @@ "image": { "height": 512, "path": "images/buttons-light-default-narrow-1x.png", - "sha256": "bd1a6225bf79c64f7484a338882677e71ed6b9478079c2a01ac386b73c47e16e", + "sha256": "1996a432dc66c27f7825297a239ac7603464b527c73875434ebc0f27846fc80b", "width": 352 }, "palette": "light", @@ -575,7 +578,7 @@ "image": { "height": 1024, "path": "images/buttons-light-default-narrow-2x.png", - "sha256": "07abf9e2cc090ab01114ea7836fe72bb78049d60a846740b6b318d3adb987d56", + "sha256": "cd995763cc5c049b941df86fcb60ee7b550dcb447e61775591db4acb2bba5380", "width": 704 }, "palette": "light", @@ -596,7 +599,7 @@ "image": { "height": 512, "path": "images/buttons-light-hover-regular-1x.png", - "sha256": "f729638aae842d508669f0af7abaf807e8824e21556ca9cc71fc238fb23c151a", + "sha256": "f53ece4dcf0b005aff68f6fa35d351bc03f894c7e16267700f029c5f17b11aca", "width": 800 }, "palette": "light", @@ -617,7 +620,7 @@ "image": { "height": 1024, "path": "images/buttons-light-hover-regular-2x.png", - "sha256": "a1a8f0d35c37161429bb996505ce3b4da0fe5c94ee6d96bb851df5abe7cb48ef", + "sha256": "ccd606ac31eac68ea7c8f42405c5815c03c91d452dd80c19142276683233f336", "width": 1600 }, "palette": "light", @@ -638,7 +641,7 @@ "image": { "height": 512, "path": "images/buttons-light-hover-narrow-1x.png", - "sha256": "727a1121fe8a6397a26edb8aabd80f5f0241d9fce951a53159273c49784a27f9", + "sha256": "268269b3ac5a5419ea606e6fa9aa7b4c6ab8c3da1a28855ba73486309e219e18", "width": 352 }, "palette": "light", @@ -659,7 +662,7 @@ "image": { "height": 1024, "path": "images/buttons-light-hover-narrow-2x.png", - "sha256": "04d7b80062ddad169546ba0a41795636ab5ecd136a546886162460b414833dce", + "sha256": "56eae4f61ca13f033f371de8a2fea7b44e64637977658d88465b1ea09d08c97e", "width": 704 }, "palette": "light", @@ -680,7 +683,7 @@ "image": { "height": 512, "path": "images/buttons-light-focus-regular-1x.png", - "sha256": "f50c8fc8ce96474f37c00c00d7fe9f35ee7a841e9053fc0cb6cc6b1633a68b2f", + "sha256": "38ce7b80b7a527f562ef9fb108b508e85e2b997047e05c4e587bf73bb029610c", "width": 800 }, "palette": "light", @@ -701,7 +704,7 @@ "image": { "height": 1024, "path": "images/buttons-light-focus-regular-2x.png", - "sha256": "92b9c95663f39c5b51b47671c95965d504964da786d9a725bd972a0404af10d9", + "sha256": "5a9927b8f0e480ea04a5422b700363d8d2d01fed2bdda3c6f0de2b1aa36335d3", "width": 1600 }, "palette": "light", @@ -722,7 +725,7 @@ "image": { "height": 512, "path": "images/buttons-light-focus-narrow-1x.png", - "sha256": "c0dc94808303d75cc9bb94d9e5e55e67e31e5efd8fc3dd5544f7696b8504d39d", + "sha256": "8ef963b8c0484dfe7b9d0a53f68f451d68ece1a96b916c812ce40556a5474a4f", "width": 352 }, "palette": "light", @@ -743,7 +746,7 @@ "image": { "height": 1024, "path": "images/buttons-light-focus-narrow-2x.png", - "sha256": "81e2c87d9d91577706e35130d2600bc398d1317803b89ff279ee306bad21c3c6", + "sha256": "faefa77c5f3ecace90bb6ac4f33c8b90fd60f9b3f9acb9cb38d019af4570c365", "width": 704 }, "palette": "light", @@ -764,7 +767,7 @@ "image": { "height": 512, "path": "images/buttons-light-disabled-regular-1x.png", - "sha256": "a3b02af006235a31008f3c0310c75ed52cd1c1699812d1a5f28124ae28b7657e", + "sha256": "bbe3cd6d53829f3337381e19651d83e57fe6952a68b4d235950a5c41ed8bc1cc", "width": 800 }, "palette": "light", @@ -785,7 +788,7 @@ "image": { "height": 1024, "path": "images/buttons-light-disabled-regular-2x.png", - "sha256": "459cc72dec01299c28cbf5fe102d8ade2145774c2d3c5dce19f971f4b1144f35", + "sha256": "956adc8326d13866ac69910597e9c091f171c1101a8503cb6bbfdbee51e88ad3", "width": 1600 }, "palette": "light", @@ -806,7 +809,7 @@ "image": { "height": 512, "path": "images/buttons-light-disabled-narrow-1x.png", - "sha256": "7cf0d4479f6f6da0dfc794e422bcb459483630cfc914661f7d3f33611b892583", + "sha256": "183d0680a69d9fd87a676a781e1c76eed7a2a50b39df0cc5791e8b192f5ad8e7", "width": 352 }, "palette": "light", @@ -827,7 +830,7 @@ "image": { "height": 1024, "path": "images/buttons-light-disabled-narrow-2x.png", - "sha256": "589a403545be1f810305e3743784bee0c5b3daa07a52e4552bd6eb6cf02d348c", + "sha256": "f2604d778b30a7c667b4a908b5c76ba4340935234679e6aac846c7ac92ad0fd4", "width": 704 }, "palette": "light", @@ -848,7 +851,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-default-regular-1x.png", - "sha256": "4d0822e61cb124cb5c82a5083a5188b0ff82948d78cb451fd6740460c2ebc7ab", + "sha256": "2af3baa31b9e68267179903ddb46c98987fc25015b494bbf04a6ce6358b9cae6", "width": 800 }, "palette": "ocean", @@ -869,7 +872,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-default-regular-2x.png", - "sha256": "2581e2ec155155a74909f4667efeb941da38d58d59bda4a84b2070237007aef3", + "sha256": "44d57fde8f5a167bf7458f2acd1f35b9e61267d9518395709235cd756b395a81", "width": 1600 }, "palette": "ocean", @@ -890,7 +893,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-default-narrow-1x.png", - "sha256": "036112ebaa586244f504f4dd02faea00f5d8291abb260e7f6be6d1dace7fbe65", + "sha256": "bcb8e1a2e395d9c886368f31eb5e8513ef88772b01c4fee685aa7431263126ca", "width": 352 }, "palette": "ocean", @@ -911,7 +914,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-default-narrow-2x.png", - "sha256": "e7e6984c648f9aa1016fbaec6c3872682d96de0869c14e86938ea1a733a2b2f8", + "sha256": "47f54498ee89d1d2c46e217cdf82da1d4cd774430e6438c4e708d7b1477ceeb8", "width": 704 }, "palette": "ocean", @@ -932,7 +935,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-hover-regular-1x.png", - "sha256": "eb79c2e356a8f6ffd83182095c93371aba57d23df5364c45282d719b6167540c", + "sha256": "9d3cf4060926386797dfb0127860152e57625a69f786143dc3297b7a71f1ac95", "width": 800 }, "palette": "ocean", @@ -953,7 +956,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-hover-regular-2x.png", - "sha256": "b4a4f5e2981f42810bd827be6d7823379127ea0ced2ad2f354306fb8fa566615", + "sha256": "97ace3b70d195eedd51c81e3ac04c36c740bd4bddfec0cabf0597530f316d861", "width": 1600 }, "palette": "ocean", @@ -974,7 +977,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-hover-narrow-1x.png", - "sha256": "dcb4c655cc50f1cb7e887e4c15e2efe50dd57feb7c5a55bf542030ac218bd4df", + "sha256": "77112919c2a4cd3ed2d85cbeeeb4b82a829717fe4b794725713a9527863f6b6c", "width": 352 }, "palette": "ocean", @@ -995,7 +998,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-hover-narrow-2x.png", - "sha256": "357c6fe1d39502d3d46e27bf81fff2e3a9c50fd7ddc5ed56f5af8fbde24e8b77", + "sha256": "ad2896cd80b640d5c716ef735fd40bdc2e966fe6ae0cb85726ff7281ca4cae70", "width": 704 }, "palette": "ocean", @@ -1016,7 +1019,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-focus-regular-1x.png", - "sha256": "5db464e5c23244407de9e400dc2ab565c80269ae692701185163ef728d381231", + "sha256": "959c99c990c3305f7c0e4a52d9246cb30be542453ba8e4785d55c9d0ebf8df14", "width": 800 }, "palette": "ocean", @@ -1037,7 +1040,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-focus-regular-2x.png", - "sha256": "9c0969f372ac085a5ddbeb9556482bfadeebd93ce8348ad1a6edf5f17b1c26ea", + "sha256": "ee6bb1d4d2e5a3d204f57f0a77fa62f91ba83de7e6405709cc04493153b8ba60", "width": 1600 }, "palette": "ocean", @@ -1058,7 +1061,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-focus-narrow-1x.png", - "sha256": "779c15f35912553c36ff763db93842fd4db985b1e894a57b72ba53515ff1dcb4", + "sha256": "a59894df3c55969d6ebd156be53267b22974925b0b26a149ed15306b24e609f0", "width": 352 }, "palette": "ocean", @@ -1079,7 +1082,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-focus-narrow-2x.png", - "sha256": "09f69fda465854e0c545ffd14d6456444c489266aa6ade04b9b980e300e670f4", + "sha256": "e76577f7cf6e53f072854a43c4c39da148fefdf2723f1f64a04e1d2c4bf0c332", "width": 704 }, "palette": "ocean", @@ -1100,7 +1103,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-disabled-regular-1x.png", - "sha256": "5a73f94d64857ddc12072fb7488fb817ae42c8b0460fbd079eff26535a33f18c", + "sha256": "d1d4ac2d1725c6b247c3eb884110e0f46c91eb48791644e4e33b3decaa878ef6", "width": 800 }, "palette": "ocean", @@ -1121,7 +1124,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-disabled-regular-2x.png", - "sha256": "c04f57d630e9ecef5d50341fa51338a255f49555a12c4215e5dd497e1904f973", + "sha256": "44bbea3fbcc29a2fa86a63643dba1d755defa01a8698bcc0cf3298c456e67fe3", "width": 1600 }, "palette": "ocean", @@ -1142,7 +1145,7 @@ "image": { "height": 512, "path": "images/buttons-ocean-disabled-narrow-1x.png", - "sha256": "a3914217502d18d3ed030347655ba82333058424a490d895d82d348327bc19ba", + "sha256": "e5a8dafb8691773a492c12c479fd2b17a988a166ef2e5be90a99f8b528ae3921", "width": 352 }, "palette": "ocean", @@ -1163,7 +1166,7 @@ "image": { "height": 1024, "path": "images/buttons-ocean-disabled-narrow-2x.png", - "sha256": "e1242742574e21f4e6ab4be14334be825a262bee2bb25513f4e10d3b54640294", + "sha256": "62f354dcb4177d64507a7d77870ca43673d145f22d5966dee6ff5c9abb359b72", "width": 704 }, "palette": "ocean", @@ -1184,7 +1187,7 @@ "image": { "height": 512, "path": "images/buttons-forest-default-regular-1x.png", - "sha256": "a0ea08d2a5b679f2a1153bea7e02adbd84ddd653d9892f9de4f6eb5d2b9aacaa", + "sha256": "1f234f0c71785ce9e7100b61b6fec75d7fc4786d2a7a6cbe82fb455c590e2d74", "width": 800 }, "palette": "forest", @@ -1205,7 +1208,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-default-regular-2x.png", - "sha256": "81c1e3c534597ecccfc57d946a11b5fb05a8f968e24e882cbcdba9fd1a9af64e", + "sha256": "0becb6475d84d0a2d1cbda9a5e7d42d4edeecbe6daad78d0997f015def55a6f6", "width": 1600 }, "palette": "forest", @@ -1226,7 +1229,7 @@ "image": { "height": 512, "path": "images/buttons-forest-default-narrow-1x.png", - "sha256": "3dcec8494803abbb541f526a43b5d3ee3d05d9481544c8f414b7e15cffcfb011", + "sha256": "0349ae6a7dca260de6384ca2f31db13b8e25c8b76c092029fb519f43f53e5505", "width": 352 }, "palette": "forest", @@ -1247,7 +1250,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-default-narrow-2x.png", - "sha256": "431d39e0099b0e61f49a1c1f318bb9617515c9dc30baaafddd0f9943d73bbd45", + "sha256": "6d0cc9982b504631482b2a5b817ba5ebdb8ba4b1969bfac1ed2e57ce10cbfa67", "width": 704 }, "palette": "forest", @@ -1268,7 +1271,7 @@ "image": { "height": 512, "path": "images/buttons-forest-hover-regular-1x.png", - "sha256": "760540573f9f15c2995eafa8cf7a08d9849b0d64be422bed1d854a9797ec3091", + "sha256": "b3d830df0fcdc905bd5197acc67705871b0fbb4649c91dd3d6a0fd3426625389", "width": 800 }, "palette": "forest", @@ -1289,7 +1292,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-hover-regular-2x.png", - "sha256": "7f35175a9c97daf81aa0b1f57d904252f5d4394824fa768480af874698aea6c0", + "sha256": "b49b4219f1e1016c6712c1dc9e41cdb0a3e525b9adbd2d3cb8cb699376ad1478", "width": 1600 }, "palette": "forest", @@ -1310,7 +1313,7 @@ "image": { "height": 512, "path": "images/buttons-forest-hover-narrow-1x.png", - "sha256": "30b708ab504dc5509e72810f4400ba54eb21fc644217b5de21fbe13765458a31", + "sha256": "82b3ca53f3e52e8dd4e9b1eeba53529f8f39797c2fbdf141584903c71fbd0ff9", "width": 352 }, "palette": "forest", @@ -1331,7 +1334,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-hover-narrow-2x.png", - "sha256": "cb8daf5754705a151a9088b8e32c66998a33a50c2dcec04d3db2aa2030d2d1f0", + "sha256": "7b963377c849bea0d06089d6950f6a17fb42c20b4fce1311e671709851e8541a", "width": 704 }, "palette": "forest", @@ -1352,7 +1355,7 @@ "image": { "height": 512, "path": "images/buttons-forest-focus-regular-1x.png", - "sha256": "99df7facc0305122d375536b45b45496213b06c9e595eac10b0c9aa0d1675f25", + "sha256": "4ec9e655447cce5db4c15dd85e85f9f1c99d2f551f848c3eba887af9da0d5074", "width": 800 }, "palette": "forest", @@ -1373,7 +1376,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-focus-regular-2x.png", - "sha256": "3e31bc4bdfa870eeb72d229f3ef813ebf8e724ae51c292ec55a777d45d64fd0b", + "sha256": "fb1ebab78be7cbecfcb9d48ed128df7e15e2a49be8a08cb960d71d1461dadfc8", "width": 1600 }, "palette": "forest", @@ -1394,7 +1397,7 @@ "image": { "height": 512, "path": "images/buttons-forest-focus-narrow-1x.png", - "sha256": "ccc76d3aee304e827db1ce6f97a64460d9f3b5744f7a99b7dd97166d3ad8a3ad", + "sha256": "542891f92042ff873b1a0fed3a61e85d533fbdff9507c92e76928865a3237d52", "width": 352 }, "palette": "forest", @@ -1415,7 +1418,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-focus-narrow-2x.png", - "sha256": "545994d7cdbe038818df187ae7117e845400e94003a08a208cef39ea1e28a658", + "sha256": "b277e7722de206e89c6b9da6b52b2019c0a665f970a911caff1e04b2d5185ac5", "width": 704 }, "palette": "forest", @@ -1436,7 +1439,7 @@ "image": { "height": 512, "path": "images/buttons-forest-disabled-regular-1x.png", - "sha256": "06231fe52c7ca05ca04e15e84527b2a99335bb74b19e2591c911e1f34b358d5b", + "sha256": "30c388b14bdd268ee726a2904e6c4948b852e8ffa80a541bdd245bff3d3026cc", "width": 800 }, "palette": "forest", @@ -1457,7 +1460,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-disabled-regular-2x.png", - "sha256": "0942c31de1f7daeb0db3f7fcdc43c6769026c79d7a33b119f399a48d27043637", + "sha256": "e77e3d77055d3d99dbec70012cdaf8961471bc1641580cc35948a8e39f02db34", "width": 1600 }, "palette": "forest", @@ -1478,7 +1481,7 @@ "image": { "height": 512, "path": "images/buttons-forest-disabled-narrow-1x.png", - "sha256": "c3228ad31918ed6de1286ceb89576db867fa451eb1ca9d8d20e46ae647ba21d0", + "sha256": "6522c60a14ff35f474240799f27abbcdd5343d8e0bd4d947bcde57860e3b6c25", "width": 352 }, "palette": "forest", @@ -1499,7 +1502,7 @@ "image": { "height": 1024, "path": "images/buttons-forest-disabled-narrow-2x.png", - "sha256": "b7f9d4948290347d1d91aeacc3b07f4226607e3d991b1102e4267fffb57e36a9", + "sha256": "f4cb039de8e62190c9e3c7d3095fc34bb2f3a5f8a8a8b1d0ac3bc1110e13397b", "width": 704 }, "palette": "forest", @@ -1520,7 +1523,7 @@ "image": { "height": 512, "path": "images/buttons-ember-default-regular-1x.png", - "sha256": "cd42388bdc736840289b3268996e4b531659bec53dbf1b93ae811c4aeeecd3f9", + "sha256": "d70ce09ccb0d938bad8f95ad7bed5e5219a1dd4a8ec2ef4458f9e45bde60d8cd", "width": 800 }, "palette": "ember", @@ -1541,7 +1544,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-default-regular-2x.png", - "sha256": "e4f85fe05c7f35ecf74a5909947aaf1567bab565edd255caca0a753e677b23ae", + "sha256": "c85ed65a4ecd62ed8b4c466571a4c09799a712eeae540c605053d1337405d336", "width": 1600 }, "palette": "ember", @@ -1562,7 +1565,7 @@ "image": { "height": 512, "path": "images/buttons-ember-default-narrow-1x.png", - "sha256": "f36f41bfbc65368663737a7b7e3966aeb62d3ccf937ff55ff58d442212968fd4", + "sha256": "da4de294620757b40659c9425d830e01012a02f464a4112995ed456bc63dcb2b", "width": 352 }, "palette": "ember", @@ -1583,7 +1586,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-default-narrow-2x.png", - "sha256": "b65507c31567bfdb13a930c89bdcd10926dce997c63a813ae74af54025e34ade", + "sha256": "f0372c7a3a77ea1c7ae4860d841343ae3b8f5adfef3edb0c0985095535bcbf60", "width": 704 }, "palette": "ember", @@ -1604,7 +1607,7 @@ "image": { "height": 512, "path": "images/buttons-ember-hover-regular-1x.png", - "sha256": "aeedcf3a1a95565ded9fd8b448d803fd19205a6764c8a3cdd33332da206bd99f", + "sha256": "571b54f32d3daa63563edc06d9715450ecdd3ee4a3c1b935107a1f0ad91c0582", "width": 800 }, "palette": "ember", @@ -1625,7 +1628,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-hover-regular-2x.png", - "sha256": "6ffec71390638a6705dd6f8c7d15c67acbb938b8b017187fb1e21416fca56518", + "sha256": "e8fadd6740576a0cbe5fd62caf86017b07df50069a391c0b292eb4f345cf5bbb", "width": 1600 }, "palette": "ember", @@ -1646,7 +1649,7 @@ "image": { "height": 512, "path": "images/buttons-ember-hover-narrow-1x.png", - "sha256": "f1b7b7195b7d05475891a4660e76f42823b7bc9417868665990a5b3c4d3a91b8", + "sha256": "a147d54bed8d5a8de4e9defcea2e7fe0492c11e8957ab08a699b81e919cbd162", "width": 352 }, "palette": "ember", @@ -1667,7 +1670,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-hover-narrow-2x.png", - "sha256": "8aa66fcd8d288c6e5e6a658a58752c3b5b340beb44e54ac090a5e3b848eec630", + "sha256": "fb078e3f7eee006a6e90ce52f9972ff886bf98fd81034ed9168e495c63c7cf38", "width": 704 }, "palette": "ember", @@ -1688,7 +1691,7 @@ "image": { "height": 512, "path": "images/buttons-ember-focus-regular-1x.png", - "sha256": "452ff2860c11028d3d13aef117161a68f2527575195cf3eaafa8327fe4fd56f6", + "sha256": "d3c8a34fccb2d4b9f3723283c3ec05cde0589393663fb813f2abe253f12f49cb", "width": 800 }, "palette": "ember", @@ -1709,7 +1712,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-focus-regular-2x.png", - "sha256": "49988fbecdf797dcaff2ebf02933412ffe616f49cbfb204553563692932de9a1", + "sha256": "bcce206c3f79ddd6c7b5660c0bc5bcc322752d2c4dbe5226829fc1b8345c26d2", "width": 1600 }, "palette": "ember", @@ -1730,7 +1733,7 @@ "image": { "height": 512, "path": "images/buttons-ember-focus-narrow-1x.png", - "sha256": "be1e33e5f2c3567401e23067ad07a1864e00a1e2f1a6efcb75f7d709970d5b48", + "sha256": "9b42c188ba3179a4b419033669098a66404bc5e2afba82d432d70844c3f61505", "width": 352 }, "palette": "ember", @@ -1751,7 +1754,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-focus-narrow-2x.png", - "sha256": "65682583be85e51317814d25da0c7b36a2a9303db27dd797357c49c93c987805", + "sha256": "6da164a805b7b4cda45ff9399418ebf05d0d6b46ac5e22c3720c8203240eb792", "width": 704 }, "palette": "ember", @@ -1772,7 +1775,7 @@ "image": { "height": 512, "path": "images/buttons-ember-disabled-regular-1x.png", - "sha256": "137c2db7024c16bdfca2587718d8849c7e0ee4e4569c3889c7d63265e3251bd9", + "sha256": "918eefb8b68b2d046352c93bb567fe81abbc0ccca09666e5ee48221bee0d2374", "width": 800 }, "palette": "ember", @@ -1793,7 +1796,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-disabled-regular-2x.png", - "sha256": "0323b8b68176de5fc136e2cd710ed5758629e73dbc76d851a5f46564fe1946d2", + "sha256": "9c2e237d89c319940a617804f1669f039c7733ffeb226931a75cb5a450124f06", "width": 1600 }, "palette": "ember", @@ -1814,7 +1817,7 @@ "image": { "height": 512, "path": "images/buttons-ember-disabled-narrow-1x.png", - "sha256": "14cb9fdddd7b9e1e8b2b9112f99f73859cbd424e4216d3e6908a518a50e01b3c", + "sha256": "ba593e73fa9550cf203bb3dad2c7f0918e7480d04651eef8c1dbf34b9e41b722", "width": 352 }, "palette": "ember", @@ -1835,7 +1838,7 @@ "image": { "height": 1024, "path": "images/buttons-ember-disabled-narrow-2x.png", - "sha256": "99cb3baa38ed1de9a8f174da64cf55dfeb882afec9013e441f21ba89b3223b2d", + "sha256": "7718e6d1059270fbaa0065442600cdeadad05116543324348cff6226a4a78a4d", "width": 704 }, "palette": "ember", @@ -1875,7 +1878,7 @@ "image": { "height": 512, "path": "images/input-dark-filled-regular-1x.png", - "sha256": "ff8dc35761e2cb1c4362920b8702c91a27834e69faabb8553907c0bbd70bee96", + "sha256": "1c8f076abf31896aa72b7fb387245beb4a145f1b9c341d31eaf2589eaa9db0c0", "width": 800 }, "palette": "dark", @@ -1896,7 +1899,7 @@ "image": { "height": 1024, "path": "images/input-dark-filled-regular-2x.png", - "sha256": "be142494cbc4388b86dbc6c71ce49bbf547ac131b525437034c05d411c90a293", + "sha256": "7d9f6b3edf0f2292ca88c335e95d502de08e1e27772ccf00f1f6c43d3d7338c9", "width": 1600 }, "palette": "dark", @@ -1917,7 +1920,7 @@ "image": { "height": 512, "path": "images/input-dark-filled-narrow-1x.png", - "sha256": "0342091be4a7993662929da259fd80fbcfb9cbb82b57a5e2fce636719b8ecf90", + "sha256": "e185f9fc9a1c4bf27ead1105ebb164ec44a85e46ccfdcde04553871eb78ee012", "width": 352 }, "palette": "dark", @@ -1938,7 +1941,7 @@ "image": { "height": 1024, "path": "images/input-dark-filled-narrow-2x.png", - "sha256": "8eac4ad324a59df5faf45dedcc86a9ecfa0c39d654d49119ed48db60d7e4f6d8", + "sha256": "e82832f720ace50a893ba361c60c426e06f27c2d3510638343c58d6f79f76b35", "width": 704 }, "palette": "dark", @@ -1959,7 +1962,7 @@ "image": { "height": 512, "path": "images/input-dark-empty-regular-1x.png", - "sha256": "76bb165d21b55a63ee3720b69499d6b5d1dc147d435d93665780bf36dfeccb26", + "sha256": "09c83c2246ae40b57c6abbe7df6043b830190d733c5fc479b7652dfa9e82c251", "width": 800 }, "palette": "dark", @@ -1980,7 +1983,7 @@ "image": { "height": 1024, "path": "images/input-dark-empty-regular-2x.png", - "sha256": "643925ef1e9a80bee1b4e420c43e004e884887941755e0db6dba252ad19c0019", + "sha256": "d5d9314bceeebec94b8966d6d274d6e9e992b1162fc2cdc9363596b91cf08daf", "width": 1600 }, "palette": "dark", @@ -2001,7 +2004,7 @@ "image": { "height": 512, "path": "images/input-dark-empty-narrow-1x.png", - "sha256": "d78c46d8365221f16223505b146f3692d47c58301b1ddb12c3d39c91a342f0bb", + "sha256": "88979989e7964bbd480890f3bf96e0f330c4d8bd992e0c633ae1c5d87192564d", "width": 352 }, "palette": "dark", @@ -2022,7 +2025,7 @@ "image": { "height": 1024, "path": "images/input-dark-empty-narrow-2x.png", - "sha256": "bd8f7ae89eb1d324a1a4f8140f7e8caba1e82f43922e1edd68b2633ce80e1770", + "sha256": "0c20aad34231c9adb573f5b4da5b3fdefe036903c54952b78e9483c84d47aafd", "width": 704 }, "palette": "dark", @@ -2043,7 +2046,7 @@ "image": { "height": 512, "path": "images/input-dark-error-regular-1x.png", - "sha256": "43eb3a77af8e53b7fbd375f546a650356eb8eab63a6c09e516e05321fceb8cd3", + "sha256": "01f676bc0dfc0ed94410ad4138200e509b56bde21213d160f5c719649bcf0b48", "width": 800 }, "palette": "dark", @@ -2064,7 +2067,7 @@ "image": { "height": 1024, "path": "images/input-dark-error-regular-2x.png", - "sha256": "b8fca2a1c45c61d308d4d45d7eb7611f833445e0c43a4b1cfa529eb76cde7ad8", + "sha256": "63a539f1b9e7f6ef3ff67cd3c628cd6c138f750402b6b71a4a85866a6a96f85d", "width": 1600 }, "palette": "dark", @@ -2085,7 +2088,7 @@ "image": { "height": 512, "path": "images/input-dark-error-narrow-1x.png", - "sha256": "b046557fff8b071e08105079c0648874de181a63c6e0918a977a4407de9d032d", + "sha256": "4ae7bf474259bc8ba0ef7533945e4e7c9fe9f4a8ff6ad219c4cec94bd584d028", "width": 352 }, "palette": "dark", @@ -2106,7 +2109,7 @@ "image": { "height": 1024, "path": "images/input-dark-error-narrow-2x.png", - "sha256": "63b975e01d18d53a2d3cef97f85afa7f6b6db81f25845e0135ff726c5f1841d2", + "sha256": "4fe4ca1eb0b8d40e5618951d6c2f314abd9b5b5d7c88390b1ee3b4915e99f706", "width": 704 }, "palette": "dark", @@ -2127,7 +2130,7 @@ "image": { "height": 512, "path": "images/input-light-filled-regular-1x.png", - "sha256": "42a4899e5f648bbee30aa719ade0fed2eb8141359c9d0235401ed512a250e81b", + "sha256": "37bd9ba79e7f6766c01fdee2f2c251e4c4747b08cac2b0bc70525a8ea79ba1d3", "width": 800 }, "palette": "light", @@ -2148,7 +2151,7 @@ "image": { "height": 1024, "path": "images/input-light-filled-regular-2x.png", - "sha256": "6ec2c78da9ac55aa8de2532eb4220abc1b3ce7e5ba760febb8b4e69854e8b78a", + "sha256": "7e3ada403c4be108d90cdba273d0824610b454691b4bb1075a200423786a0ac9", "width": 1600 }, "palette": "light", @@ -2169,7 +2172,7 @@ "image": { "height": 512, "path": "images/input-light-filled-narrow-1x.png", - "sha256": "c569964d886c807b504af212eada5f001d8dac3a59cb846598822ee8ef201f12", + "sha256": "ba05f53c9d3961a7b2289cf688b105ba92a59929d284dded1b55c25d65490ebb", "width": 352 }, "palette": "light", @@ -2190,7 +2193,7 @@ "image": { "height": 1024, "path": "images/input-light-filled-narrow-2x.png", - "sha256": "7afb9c20c6c70c5c96a3d35404f2041ea9ce7224925126ed667c54b9dbf1a265", + "sha256": "03f8958b807f691739187949ded58b07c6814f88d76ad3efbfb677c177e80ebe", "width": 704 }, "palette": "light", @@ -2211,7 +2214,7 @@ "image": { "height": 512, "path": "images/input-light-empty-regular-1x.png", - "sha256": "c271129916c2e3d4e2b86b46419030020982c8ce47606907280a0eb1b393d4ca", + "sha256": "0ac79c7a79be832d85ae9fca9f1e3e84ac66d5b998e6cea3d274125c46f8cb3a", "width": 800 }, "palette": "light", @@ -2232,7 +2235,7 @@ "image": { "height": 1024, "path": "images/input-light-empty-regular-2x.png", - "sha256": "0d0e625cacae771609ec9956866701546c9cc7e959377ca1a3d9cd577edc67bf", + "sha256": "7c46c8235946adf04821c77f29839e886be8280a0c75ed9f01a2ac574e239065", "width": 1600 }, "palette": "light", @@ -2253,7 +2256,7 @@ "image": { "height": 512, "path": "images/input-light-empty-narrow-1x.png", - "sha256": "29e6c55143ad88a5b7668291bab0d61e6d825a0e6f570940970039616311ad9a", + "sha256": "cea7985e43dda1932a7c993897b3b203956313a5316d9d9f8c04215ff893abe9", "width": 352 }, "palette": "light", @@ -2274,7 +2277,7 @@ "image": { "height": 1024, "path": "images/input-light-empty-narrow-2x.png", - "sha256": "9c8eb53af5ab3e9d2bb7c33ce16e783a7f3792ed001bf6ac97e6e13023e8de91", + "sha256": "59f0f55b9ab2d7707b390e7ef5f899e8b0e9f0462ff5a68c004680235922adc0", "width": 704 }, "palette": "light", @@ -2295,7 +2298,7 @@ "image": { "height": 512, "path": "images/input-light-error-regular-1x.png", - "sha256": "b609a97a7eda234170099e012fe3dc73679405f5b7b84c510aa956700d217346", + "sha256": "b649ff376145d4cbd0c0ad6e1ef55dc3580f4dc82dded788174a6ebc1af3bb53", "width": 800 }, "palette": "light", @@ -2316,7 +2319,7 @@ "image": { "height": 1024, "path": "images/input-light-error-regular-2x.png", - "sha256": "63a9bae0a87b001983c5985d71979797e7343d4cea11d38c04638a89203af5f0", + "sha256": "e3f4e70632bb45d1e9b82c257922d4624bb7505a4b5babfb28b62c38add25761", "width": 1600 }, "palette": "light", @@ -2337,7 +2340,7 @@ "image": { "height": 512, "path": "images/input-light-error-narrow-1x.png", - "sha256": "abeb389d48851780092013e86c4063d3b43d36f59af258cf7ca9bc41fa9f00bc", + "sha256": "5a219d8c4670718d93f30a2e6c77b160bf4b725fd7aa94d61e138c1f0b52094d", "width": 352 }, "palette": "light", @@ -2358,7 +2361,7 @@ "image": { "height": 1024, "path": "images/input-light-error-narrow-2x.png", - "sha256": "f2e56e23d364f68225af8580b0ea6ccd00ddf332dde9069fe3f9e83552b4b74e", + "sha256": "0e287bae08eb65f59a62cda7f5f2f626ac7300ed8eb6d912edd0c4066babbacc", "width": 704 }, "palette": "light", @@ -2379,7 +2382,7 @@ "image": { "height": 512, "path": "images/input-ocean-filled-regular-1x.png", - "sha256": "b5361124fc8037f7902e51cbb3af7ed6eea5c5a51d558a1387b8decf006f7c3c", + "sha256": "ad0dc9378d5e78d6ff61be8f6580b5cfd887c18385bc160e3ebfca69c8a5c7d7", "width": 800 }, "palette": "ocean", @@ -2400,7 +2403,7 @@ "image": { "height": 1024, "path": "images/input-ocean-filled-regular-2x.png", - "sha256": "1bc2fee338a9f7e575fc1da354a2dc6135aa9185df39f369bd8c3a1d5597f0fe", + "sha256": "2c29dcb2f1fdb9fcbd60983043da38d870c46c87205e7a47ab322492a1720611", "width": 1600 }, "palette": "ocean", @@ -2421,7 +2424,7 @@ "image": { "height": 512, "path": "images/input-ocean-filled-narrow-1x.png", - "sha256": "191b022546b047cac8d573107f8d1123e04bb6b5dddb4874e7c9c602eecfe036", + "sha256": "643f7143df32646f79b49e503bdf8d815cb356e667194a3360277a6501dabdd9", "width": 352 }, "palette": "ocean", @@ -2442,7 +2445,7 @@ "image": { "height": 1024, "path": "images/input-ocean-filled-narrow-2x.png", - "sha256": "97a209be72c0069754c471880e936d183db251bed3581ceb87ee3f25aa4c2f20", + "sha256": "6743da58bf9178ce9761ca1a1fc4e6122e6ec3ab727b78bd7f9a66a448fab916", "width": 704 }, "palette": "ocean", @@ -2463,7 +2466,7 @@ "image": { "height": 512, "path": "images/input-ocean-empty-regular-1x.png", - "sha256": "4fb15791d8eb744893679b9ab89c8d336643cc8ccf3c644cbd197d3ef6b0f300", + "sha256": "895d002be72e3a9677e3e2ae23822b1f04046777d9a181a5705dac6224354b07", "width": 800 }, "palette": "ocean", @@ -2484,7 +2487,7 @@ "image": { "height": 1024, "path": "images/input-ocean-empty-regular-2x.png", - "sha256": "31ce59a158b47178027d15a1a0436473528437ec03dc5bf344e77f6431cedbfc", + "sha256": "b1a99de0039abab4c9936202d0ea7d65f6add4219bdcdf8e26f6b1a0f2822379", "width": 1600 }, "palette": "ocean", @@ -2505,7 +2508,7 @@ "image": { "height": 512, "path": "images/input-ocean-empty-narrow-1x.png", - "sha256": "78c1629c6c3acbe0b818403540fc375839d2d6978160b4aeb270388b90224baf", + "sha256": "2f2f7453293e73f9d93bcadc85c218f2994effb9fc5c93f3f9a5030a6df5ece2", "width": 352 }, "palette": "ocean", @@ -2526,7 +2529,7 @@ "image": { "height": 1024, "path": "images/input-ocean-empty-narrow-2x.png", - "sha256": "b3c6c9d280bf13d1bfb781623091a11e9235df053dbf3cdc93c2770d2d185f99", + "sha256": "4ef8d172a497bbf9429e845f5070d69ebc5db34038bffaafe8237f76744f2bc8", "width": 704 }, "palette": "ocean", @@ -2547,7 +2550,7 @@ "image": { "height": 512, "path": "images/input-ocean-error-regular-1x.png", - "sha256": "07194f294326ba68085b0632b430f49ae8a9d093b0e85b5fa3aeda18c1b67245", + "sha256": "b9a6588b2813042f50d056ec809f533dc2c603d67541a1b15f6190a5a4c35d6a", "width": 800 }, "palette": "ocean", @@ -2568,7 +2571,7 @@ "image": { "height": 1024, "path": "images/input-ocean-error-regular-2x.png", - "sha256": "17a0f2aa76a5ec70017035a05301e68824e3d6b3f50eb3f3623d5f8807a8e7eb", + "sha256": "41da047150341ccb04bde515729b3d4bbec4d659c355670bc08840f1dfc38ae4", "width": 1600 }, "palette": "ocean", @@ -2589,7 +2592,7 @@ "image": { "height": 512, "path": "images/input-ocean-error-narrow-1x.png", - "sha256": "591b9036f2c9a63ff900c8238a25412d0f5316bf8f1d04932667d0f287b69ff9", + "sha256": "e0c06f8c6dd6a24f86e24bdb355191cffd94ac9f72c7cea13f12b7ed13c28350", "width": 352 }, "palette": "ocean", @@ -2610,7 +2613,7 @@ "image": { "height": 1024, "path": "images/input-ocean-error-narrow-2x.png", - "sha256": "c48675c7ed1c71b743fc74e4163797a69f344fdbb53907a8c724bdd70fa8dc3e", + "sha256": "ba124f307b069e002928bf3429bd0dcdf09d71f455ffea35a94ebc3d1fb4b017", "width": 704 }, "palette": "ocean", @@ -2631,7 +2634,7 @@ "image": { "height": 512, "path": "images/input-forest-filled-regular-1x.png", - "sha256": "b265b616dcfb80e84808f597d4f2ecdb7918fe6d1b3f3bba1d1ba2dd3058eb7c", + "sha256": "992f887e086e918a2c07903dec70724dd82f44a520f240f79b2e3a38a79a38d5", "width": 800 }, "palette": "forest", @@ -2652,7 +2655,7 @@ "image": { "height": 1024, "path": "images/input-forest-filled-regular-2x.png", - "sha256": "bbefa68a91a9d4d2f505d0c521f20c3f0f89c3cfcee2bd3a21b1ff3018c610a6", + "sha256": "e580485c17b1cbbb0af92fe2cae0eed9e001b5026b143269a57d51984a498f2f", "width": 1600 }, "palette": "forest", @@ -2673,7 +2676,7 @@ "image": { "height": 512, "path": "images/input-forest-filled-narrow-1x.png", - "sha256": "18e742821e70e384c55135dac2da38f196ada003f6d35a38ac1539a535cdd5a5", + "sha256": "f8ca085b781f6d7251af6d5e1145399c516abc2171da71402ca1d56c65dcd59e", "width": 352 }, "palette": "forest", @@ -2694,7 +2697,7 @@ "image": { "height": 1024, "path": "images/input-forest-filled-narrow-2x.png", - "sha256": "ead0afe06bc270e39c50804925050edebcb87e711d8b8fbdc0e435ef7f8d61f0", + "sha256": "648ed8dd8f50ab4b3de7d36a0e8c9dff9dd7904af151dea2b5964e21cc5521fd", "width": 704 }, "palette": "forest", @@ -2715,7 +2718,7 @@ "image": { "height": 512, "path": "images/input-forest-empty-regular-1x.png", - "sha256": "0cf60193e6df3f7c848f639c2e136153a119add37d5b957333f986f4bacb40f4", + "sha256": "d948c65e0356560c64844f57fc6ec9ab1c0d6a4f73777c1bac6c98ac5c6314a6", "width": 800 }, "palette": "forest", @@ -2736,7 +2739,7 @@ "image": { "height": 1024, "path": "images/input-forest-empty-regular-2x.png", - "sha256": "7c05a12ebc500bd28b4282ac5fce061e61f779b99f7817e622b3b699d93fcf1d", + "sha256": "7e672ffd44de366164c28c158fe9d07c57433542a81bb51284da8f4476cbcbbd", "width": 1600 }, "palette": "forest", @@ -2757,7 +2760,7 @@ "image": { "height": 512, "path": "images/input-forest-empty-narrow-1x.png", - "sha256": "a6935c9bb392e2931be75d036bc54b0a18a890b8e9b2f799491fcf573a2ba159", + "sha256": "49832be3036e7c925adadd7c9348707c4eabed2a8f9085548eb1a2c8c57eb99b", "width": 352 }, "palette": "forest", @@ -2778,7 +2781,7 @@ "image": { "height": 1024, "path": "images/input-forest-empty-narrow-2x.png", - "sha256": "f4d8da1c1eda90a37e76e8ddfe3f1eda9f799d2359d0d2be5387305e3a08628f", + "sha256": "5bbda6ef502c79c5388013018eb65fde48775eecb0aabd96c72f133af8509c73", "width": 704 }, "palette": "forest", @@ -2799,7 +2802,7 @@ "image": { "height": 512, "path": "images/input-forest-error-regular-1x.png", - "sha256": "8cb89f77bf9c36dec9bd471328b263b0a59f96c809f956108ba763a024b46215", + "sha256": "65a926a1d604105dbee040f9e702661103707c602b06dea3a975dd6c4a3840c9", "width": 800 }, "palette": "forest", @@ -2820,7 +2823,7 @@ "image": { "height": 1024, "path": "images/input-forest-error-regular-2x.png", - "sha256": "08a6883447cfabdc90dcf777c1118d1157f899250b4bf0fca136cc3db3db0b94", + "sha256": "42146860384d6d4b87e01fcdb7435498550536616c5b1bf1a6d4ef51a6eb5056", "width": 1600 }, "palette": "forest", @@ -2841,7 +2844,7 @@ "image": { "height": 512, "path": "images/input-forest-error-narrow-1x.png", - "sha256": "e6f9e8f9467a6507aedbdd57c6ffd8c748909e7525a1fd6b262818f11f85ff4d", + "sha256": "e35aa054f66065225876ab9b051f53a313cf5718dba2b613fffbd42de247c47c", "width": 352 }, "palette": "forest", @@ -2862,7 +2865,7 @@ "image": { "height": 1024, "path": "images/input-forest-error-narrow-2x.png", - "sha256": "a6ca0ba9d91a24a300355eaf66f3ad569104174af9d3cfb75356bafcc7c01ac3", + "sha256": "6100b6eb53acbf437379e9272444aa81e451c25b9c3346d08934ddf9b42a1d60", "width": 704 }, "palette": "forest", @@ -2883,7 +2886,7 @@ "image": { "height": 512, "path": "images/input-ember-filled-regular-1x.png", - "sha256": "7418372443483f18d1c8f6fba627dfa3775de160d2624b07e66d6629a8f73eb0", + "sha256": "0a3de2fa5bca3c67c77c1245200d9597e8ecabf92ebb3e38aab8f2b00e35f7b5", "width": 800 }, "palette": "ember", @@ -2904,7 +2907,7 @@ "image": { "height": 1024, "path": "images/input-ember-filled-regular-2x.png", - "sha256": "e0628405b5ae2a030845a01ed9801246da61a91c4333247ed67611c5460a6d46", + "sha256": "034abbdd184a4c8e11624f6c174e4c5bad0b2ae1ba9e3a0ecaad45f140dcbf88", "width": 1600 }, "palette": "ember", @@ -2925,7 +2928,7 @@ "image": { "height": 512, "path": "images/input-ember-filled-narrow-1x.png", - "sha256": "65dc4d3f854e95e5edbc00ab10c039a4d1ae34523b113fcd345c3f0d2c574393", + "sha256": "f18df0855ac4911a4653be05107b455b407ca84119ca664a260a7528dcdb9d72", "width": 352 }, "palette": "ember", @@ -2946,7 +2949,7 @@ "image": { "height": 1024, "path": "images/input-ember-filled-narrow-2x.png", - "sha256": "4745bfb205c9227518097ff9718ebfc4efb45d308b601831db3d60f79286a7fb", + "sha256": "24104473c555f70561a0997c73006590d4d19969787c36ee4684bfcb3b5b15e9", "width": 704 }, "palette": "ember", @@ -2967,7 +2970,7 @@ "image": { "height": 512, "path": "images/input-ember-empty-regular-1x.png", - "sha256": "7dec587cf34f7f719c8ecc0607c1f6b0902575dc896a50d31106f63f2ab35556", + "sha256": "9e8e485dcf73c28cbdd0f7f8bed5255f9cf1c957e6d6931c2854a8ae2cd1768a", "width": 800 }, "palette": "ember", @@ -2988,7 +2991,7 @@ "image": { "height": 1024, "path": "images/input-ember-empty-regular-2x.png", - "sha256": "2f66d928ddbbb00d6493dfc66351690a2a48436192137a2c35497275dec6fc02", + "sha256": "19f2e76c67ebfd5f048585d64fae3a4faa2ae36b98fa44e13039666b2e4a8e96", "width": 1600 }, "palette": "ember", @@ -3009,7 +3012,7 @@ "image": { "height": 512, "path": "images/input-ember-empty-narrow-1x.png", - "sha256": "832feb2c8d0821bdb2c4dab5ccac6663eb3f314a0873a198cbf472438c9b3d92", + "sha256": "18f2d885715ae0c2e93800c32ae39cea889abe115c931c1513af8dd09ef1a3e0", "width": 352 }, "palette": "ember", @@ -3030,7 +3033,7 @@ "image": { "height": 1024, "path": "images/input-ember-empty-narrow-2x.png", - "sha256": "ff6d4b9bb4452135dd8cde7d57017de49a1f9842eb5d8da510b5d672f31ffdfc", + "sha256": "75fab8a7ae113c36e3dacfad47362c452caa5f27896203a925f3a35248a6483f", "width": 704 }, "palette": "ember", @@ -3051,7 +3054,7 @@ "image": { "height": 512, "path": "images/input-ember-error-regular-1x.png", - "sha256": "cfb67612944770b2146c184164aabca82fdfa0209b8a73e031e86ad3ee3872a7", + "sha256": "59229037e405f51882e4514fd2dfc0de996169c1920482579b01bdb32ea1da86", "width": 800 }, "palette": "ember", @@ -3072,7 +3075,7 @@ "image": { "height": 1024, "path": "images/input-ember-error-regular-2x.png", - "sha256": "7e0735ee9e04b8a6869ed5f3393fe48d9e2d7cede0f8964d2106d7b8f56d8ed5", + "sha256": "0db54bc18a1acfbe163b3182e1586f3969d2006cb3f1fc5c33a26efde3397379", "width": 1600 }, "palette": "ember", @@ -3093,7 +3096,7 @@ "image": { "height": 512, "path": "images/input-ember-error-narrow-1x.png", - "sha256": "1f0f72c297a108ba7ab0a78c1e0ec5ba7e5d9a01259d2e4eb8e1991f67ac5d02", + "sha256": "9625968468a970b6f05edf8df77b1780d7955dbe116c232f95a9b943a3623a2a", "width": 352 }, "palette": "ember", @@ -3114,7 +3117,7 @@ "image": { "height": 1024, "path": "images/input-ember-error-narrow-2x.png", - "sha256": "6a8a793458af29d0d5cc2d0bc5b888840f27dfc617c0353adda358f3771fa91a", + "sha256": "c26b18740c3ebb81570e2fa16d388f0cc8aeba4e89a528b03ee247b171a05a8d", "width": 704 }, "palette": "ember", @@ -3153,7 +3156,7 @@ "image": { "height": 512, "path": "images/input-group-dark-filled-regular-1x.png", - "sha256": "25a95f73b8573b5255b281d120e7232a76bae4d8d1105413409791b5eff89414", + "sha256": "41b0f44b59015640ce971bbebd630748c4f97e5c676378c86c2cd0ede7dec452", "width": 800 }, "palette": "dark", @@ -3174,7 +3177,7 @@ "image": { "height": 1024, "path": "images/input-group-dark-filled-regular-2x.png", - "sha256": "c0c6b8ee1034aac826ae41583d98e74f74d804999c13f3f3d2402ff35cdd4c89", + "sha256": "f5bd8d3de1071564d9c534ced0fa830dccf6816404b6c616ebebad9e95cdda54", "width": 1600 }, "palette": "dark", @@ -3195,7 +3198,7 @@ "image": { "height": 512, "path": "images/input-group-dark-filled-narrow-1x.png", - "sha256": "b1900764bc04acc49e116c7c46d577e9b9cc6c367ed03dea3700470d77e0ca84", + "sha256": "5c151b25ea4f08d78b68461ed63d17c90eb60d69751e411f2f0777e2e3fa52db", "width": 352 }, "palette": "dark", @@ -3216,7 +3219,7 @@ "image": { "height": 1024, "path": "images/input-group-dark-filled-narrow-2x.png", - "sha256": "e346d7fc99e44efc6270d45070620878fbcac35c806edd46673d7f8349f06a95", + "sha256": "ee159ca2129f4796edfc69f2134ba1926f262fe5c08e208a9e3668d78dc5484e", "width": 704 }, "palette": "dark", @@ -3237,7 +3240,7 @@ "image": { "height": 512, "path": "images/input-group-dark-empty-regular-1x.png", - "sha256": "fe12fcc67342944bf81c8a0a32d4ee61de8c94af655cade159bd1dd591b06b6a", + "sha256": "f49c6311ccb6c6d2a11626f75fbba88d3185b9e01c14c3c485fc5f5a78fec03e", "width": 800 }, "palette": "dark", @@ -3258,7 +3261,7 @@ "image": { "height": 1024, "path": "images/input-group-dark-empty-regular-2x.png", - "sha256": "66ee8a30f7dfa540b60d704dc5ed9bbc4f723bd4889fdb82583208dde1e4b7e9", + "sha256": "9d38177f85bffc13ffe130c45e1fc21cf64d108c1aa72db58fb148d1c4135322", "width": 1600 }, "palette": "dark", @@ -3279,7 +3282,7 @@ "image": { "height": 512, "path": "images/input-group-dark-empty-narrow-1x.png", - "sha256": "6239d722ee01f5d73afc6be13cc834346cef26350db17fcbb7f68f04336169d9", + "sha256": "ee6a7798a7a134aa51babab3970766cbb3170807d47492ff4faade2baa611852", "width": 352 }, "palette": "dark", @@ -3300,7 +3303,7 @@ "image": { "height": 1024, "path": "images/input-group-dark-empty-narrow-2x.png", - "sha256": "aac09f1b3b7a93b7379c8d0869c2299259c9362ea28957f494b6af5f85803fc7", + "sha256": "6b12a280db4dc38b6924b5244285abd474754382955014830837762772609def", "width": 704 }, "palette": "dark", @@ -3321,7 +3324,7 @@ "image": { "height": 512, "path": "images/input-group-light-filled-regular-1x.png", - "sha256": "ee0f0412daed5981e9cff3c25bad248606e0d6fbad05f397a6932c5e516cdaa6", + "sha256": "db4121162ee3112b3eb0911ec9005525d2a2c75e90aceaef2c88b336c9801f7c", "width": 800 }, "palette": "light", @@ -3342,7 +3345,7 @@ "image": { "height": 1024, "path": "images/input-group-light-filled-regular-2x.png", - "sha256": "c1d2cc0fe73ed6696f3b01b978f56677df2c03e839df6d8e11af303476c54c8e", + "sha256": "0bf0bf3fde128616174f8a5793de4a69932a27abb2150ac668eb7ec74cf10356", "width": 1600 }, "palette": "light", @@ -3363,7 +3366,7 @@ "image": { "height": 512, "path": "images/input-group-light-filled-narrow-1x.png", - "sha256": "dde5cc6623c96df480386e186a627e6834919c5d4802ce512ae2e44c8cc19d5a", + "sha256": "b2a720d94e204e5e5217bdd09a3fcb6d4d58b851953740c0df49d34e3ce6e8eb", "width": 352 }, "palette": "light", @@ -3384,7 +3387,7 @@ "image": { "height": 1024, "path": "images/input-group-light-filled-narrow-2x.png", - "sha256": "03b30d9cae6752b5f93824a0f875366099ea5d933e2279a3e4a269f5bd1ebfb4", + "sha256": "82beb63375d7f08697c07f173e4b89a77f61cdf8482a78713b6884d7bdb8f532", "width": 704 }, "palette": "light", @@ -3405,7 +3408,7 @@ "image": { "height": 512, "path": "images/input-group-light-empty-regular-1x.png", - "sha256": "e8bc7d8a1deb5819648c58a0464d0aa2d830f60bbdcf7984a94e823c3770e573", + "sha256": "49ee347ddda1337b23cb813f0b46b6f227d2a172e609119b491004fa95c19ab6", "width": 800 }, "palette": "light", @@ -3426,7 +3429,7 @@ "image": { "height": 1024, "path": "images/input-group-light-empty-regular-2x.png", - "sha256": "f36971ae4cc086c6d5c1e886383ccafabc906234b8ed72a9b74da3a7391cc3ed", + "sha256": "b696791187a35ac1f612824b2f0f0e5cd5bfaa1e5cd25dcb7b626031718a2348", "width": 1600 }, "palette": "light", @@ -3447,7 +3450,7 @@ "image": { "height": 512, "path": "images/input-group-light-empty-narrow-1x.png", - "sha256": "58db3ca0f503275ecdcf14ad8e5beef3bd0eb8d981e02a1cd643d3623453e84d", + "sha256": "411b9a02fdeec7c9622c517fa8ed9da74b788f572550dd3c52498dd989d787eb", "width": 352 }, "palette": "light", @@ -3468,7 +3471,7 @@ "image": { "height": 1024, "path": "images/input-group-light-empty-narrow-2x.png", - "sha256": "698ddba0c15a75fcb1243079a0117e10c393a8ff3cca633b1d8a9e387fdbea1b", + "sha256": "684401fc81b4bfbfc595c544162ae4df37c8db37214bdea083d3063bb7b62d9b", "width": 704 }, "palette": "light", @@ -3489,7 +3492,7 @@ "image": { "height": 512, "path": "images/input-group-ocean-filled-regular-1x.png", - "sha256": "7968778486221d9f764ebebb418886181b39960eae62a54f60d2b54e86d6810a", + "sha256": "abf9b94a2b90e24a02aa8e803e5a93f74e9cda39f7384bf091db6040ba2f7514", "width": 800 }, "palette": "ocean", @@ -3510,7 +3513,7 @@ "image": { "height": 1024, "path": "images/input-group-ocean-filled-regular-2x.png", - "sha256": "3390ac912722d595ece0ef3241270875611b2e45469824d694d5721771bed6f8", + "sha256": "b8d43b4b7b9195e7c3b8064776a60094a4b332b49f795a226185e4369067dc46", "width": 1600 }, "palette": "ocean", @@ -3531,7 +3534,7 @@ "image": { "height": 512, "path": "images/input-group-ocean-filled-narrow-1x.png", - "sha256": "17e465494f5bfb44bbc609af5ebaabf9a5a641ee686db38073d5e4633371903a", + "sha256": "6c7eee0ffe4255036ccc0c187d936159f40e9470825104d743874fc1977fa503", "width": 352 }, "palette": "ocean", @@ -3552,7 +3555,7 @@ "image": { "height": 1024, "path": "images/input-group-ocean-filled-narrow-2x.png", - "sha256": "b6e0f882c2652cd1431429baa337211861a2eda22b8ea65ccd1c936820c65c26", + "sha256": "d3825ef8e63bebf9d609a041a12f0dbe3049bf618d8b4c68918266243b8a76c6", "width": 704 }, "palette": "ocean", @@ -3573,7 +3576,7 @@ "image": { "height": 512, "path": "images/input-group-ocean-empty-regular-1x.png", - "sha256": "95d71f83bd44b02dbae0f6a3a7ec7bac0dd3da249128312ca84e3608c49c3096", + "sha256": "391fcc0a38b41e58f2dffc1ea5412fe01d4fa2dad37f92a32c28f9b0f5ade9ad", "width": 800 }, "palette": "ocean", @@ -3594,7 +3597,7 @@ "image": { "height": 1024, "path": "images/input-group-ocean-empty-regular-2x.png", - "sha256": "ba21d83aa6ff6f3de7929ff18c4f627a6ff5e9e586e18fee513d0ae226408fed", + "sha256": "bb30f50fc8bcdfe2f4ce6aec77650fd02fbe771874534415f31ff4a31cd14e74", "width": 1600 }, "palette": "ocean", @@ -3615,7 +3618,7 @@ "image": { "height": 512, "path": "images/input-group-ocean-empty-narrow-1x.png", - "sha256": "c62615e4dbf168bd90b75189712ef871f0076c041ed50b01fd96fc574fd100d4", + "sha256": "132dcd8479d6ce973174f4406ab3cead43d0d3734bd595f625a1cb5dbae0c6a3", "width": 352 }, "palette": "ocean", @@ -3636,7 +3639,7 @@ "image": { "height": 1024, "path": "images/input-group-ocean-empty-narrow-2x.png", - "sha256": "537af5b6d7cb4525b395ae70d55ecb0aefbc45edc7ceeedb6fd1270e07096bcf", + "sha256": "df6150e51d65b8a1750956155189b24833bf2bb4057f1b78885718625b1add44", "width": 704 }, "palette": "ocean", @@ -3657,7 +3660,7 @@ "image": { "height": 512, "path": "images/input-group-forest-filled-regular-1x.png", - "sha256": "a986fc855c8087344039da7141dd324635e5bba1b029765c5acccbcdcb644dd7", + "sha256": "6c83ab603b5741ece7ab9cdd7ab4b6885f17f8d8a0c6cc9bea26ce6119c0cf08", "width": 800 }, "palette": "forest", @@ -3678,7 +3681,7 @@ "image": { "height": 1024, "path": "images/input-group-forest-filled-regular-2x.png", - "sha256": "c44e0eb4deb92f98a27a3728269461bcca7c4d0ac1adc0dac61cdc0c17e892d5", + "sha256": "b952403543d430153164a3533168df6611050404655d749418284240160adc60", "width": 1600 }, "palette": "forest", @@ -3699,7 +3702,7 @@ "image": { "height": 512, "path": "images/input-group-forest-filled-narrow-1x.png", - "sha256": "a7e9ffb027c6663c123e97ac8b561d9610b7f5eee95471f25892a7442f0fe3e8", + "sha256": "74f8308e453032b1ece348dd2a9c4c3963341e6a0c83f573fc6fc5ecd68a6fec", "width": 352 }, "palette": "forest", @@ -3720,7 +3723,7 @@ "image": { "height": 1024, "path": "images/input-group-forest-filled-narrow-2x.png", - "sha256": "9613245964742672d5a880a739f856d6e71dac55799f5fb8d14e744ba7647fbf", + "sha256": "ecc8b2f525c92c7f65efed0001b9b9803fe5d2c5d3b6ff275b61a1064408cf8d", "width": 704 }, "palette": "forest", @@ -3741,7 +3744,7 @@ "image": { "height": 512, "path": "images/input-group-forest-empty-regular-1x.png", - "sha256": "9f8d691f668dd2c6d4c38ec6fbdde343b5ac30b2e25c5d1199ec64d744a801ce", + "sha256": "55d0281f77060986a3610feebe39b34c3808942dccdf5231b9fdd649cf59248d", "width": 800 }, "palette": "forest", @@ -3762,7 +3765,7 @@ "image": { "height": 1024, "path": "images/input-group-forest-empty-regular-2x.png", - "sha256": "a018642c1dd4985ef6f7a21ab351d861d2eb345265bdc5d2c7c9c8e98571f0eb", + "sha256": "0aec44735c6e2dab1a424213f36e850336d54fb8a92498eb397e5a0a3c0ffde7", "width": 1600 }, "palette": "forest", @@ -3783,7 +3786,7 @@ "image": { "height": 512, "path": "images/input-group-forest-empty-narrow-1x.png", - "sha256": "b27cae62cfcbfe0d7a8e9c6d90daed5d0982b053cccd4d40d2accfb1ed9b0610", + "sha256": "18710fee2cd3b576c095180922b7918dfefdaa76a2bf9cf554684f50fcbaa5bb", "width": 352 }, "palette": "forest", @@ -3804,7 +3807,7 @@ "image": { "height": 1024, "path": "images/input-group-forest-empty-narrow-2x.png", - "sha256": "ad1ad798c5a5189e18fd93689952c8c184294eedf1790d39acc7d72ab16f1374", + "sha256": "db2c327f7b6d7a2706c229c0cbfc511d9c1745d80917f91ae31a60d9975b81aa", "width": 704 }, "palette": "forest", @@ -3825,7 +3828,7 @@ "image": { "height": 512, "path": "images/input-group-ember-filled-regular-1x.png", - "sha256": "3f646acfaed60b35e5786025159a4e767639b350430eb4e61a0d5f9d965618de", + "sha256": "299b26d96b7b2e36a9716f8872247d1323c4bc2c09ac5799a397d116f2317e5f", "width": 800 }, "palette": "ember", @@ -3846,7 +3849,7 @@ "image": { "height": 1024, "path": "images/input-group-ember-filled-regular-2x.png", - "sha256": "cf46781672574981926d33309678b1bb1a9ce81122a7696baee89791c172b3c6", + "sha256": "0717106fa94e0174433c161ebdcb1d9578a1c62843eb5cca9308ad58a3f19091", "width": 1600 }, "palette": "ember", @@ -3867,7 +3870,7 @@ "image": { "height": 512, "path": "images/input-group-ember-filled-narrow-1x.png", - "sha256": "763bbaecc29b243f1c53eb2503cc2c6d5fbf15b71f8b4af5aa6a1fd2e15fe8a2", + "sha256": "01c6abe44e5a055c2366bd226677d4e1481deb08e20f2a1ddd709ae70d924df6", "width": 352 }, "palette": "ember", @@ -3888,7 +3891,7 @@ "image": { "height": 1024, "path": "images/input-group-ember-filled-narrow-2x.png", - "sha256": "42f8fc222136d0f8597d5e684fe80c8b326da7f613a4f76f25456ea4320846c3", + "sha256": "1148587659ce1419845951ddfdf020f8a99d81c305c852b222ba60550ed7e90b", "width": 704 }, "palette": "ember", @@ -3909,7 +3912,7 @@ "image": { "height": 512, "path": "images/input-group-ember-empty-regular-1x.png", - "sha256": "bddc0c01aa095a2aa5980337625ec53064c6e03860631e4c6817b532aa9b1d99", + "sha256": "6f531956cdbafe287f93eb2c9e942512da27553c83a948dcf070ca9f799e44c0", "width": 800 }, "palette": "ember", @@ -3930,7 +3933,7 @@ "image": { "height": 1024, "path": "images/input-group-ember-empty-regular-2x.png", - "sha256": "bf968a7f8846b131c9ea7da67fd0a98669db2a7f6796dcc37fed37dcecc3c8c2", + "sha256": "3a4a08e5ce2e4bd2c102cf1343a79c527e9ee433c4735eea11237d5a5af55147", "width": 1600 }, "palette": "ember", @@ -3951,7 +3954,7 @@ "image": { "height": 512, "path": "images/input-group-ember-empty-narrow-1x.png", - "sha256": "78065a7b6295245d5fe398090ee3b645c4ed250f9c0b6c5c729dd37338620eeb", + "sha256": "85b170ef8c387bd4ee95d7180dba411f0772c70c74894f28d8dc13df7430d067", "width": 352 }, "palette": "ember", @@ -3972,7 +3975,7 @@ "image": { "height": 1024, "path": "images/input-group-ember-empty-narrow-2x.png", - "sha256": "b26bfef9c07e442f2ced9b6bd0a3521c8d90b912a5e5c13cf683e25833c85ad6", + "sha256": "cd376b5c2ceeb92660cfca501b1da17f07189e31c17a9f30412d8ef96a51e5e7", "width": 704 }, "palette": "ember", @@ -4011,7 +4014,7 @@ "image": { "height": 512, "path": "images/toggle-dark-off-regular-1x.png", - "sha256": "7801289fa59cc449ea38c74bd3a9c1301674ccabe425b16ecc028e758ab8ccb3", + "sha256": "0145e98120ccb075e77ff0671c95f90997b71686c00afa2811cf0e93b76c788b", "width": 800 }, "palette": "dark", @@ -4032,7 +4035,7 @@ "image": { "height": 1024, "path": "images/toggle-dark-off-regular-2x.png", - "sha256": "02f28ef8d89964698c5b7778c5061f1f44e49e2dd37158fc8a9f5e5129f6e4ee", + "sha256": "aa11bd988733cb235278d3b281bd8b8a21859684432c01db1e8ec2788cf1c0c1", "width": 1600 }, "palette": "dark", @@ -4053,7 +4056,7 @@ "image": { "height": 512, "path": "images/toggle-dark-off-narrow-1x.png", - "sha256": "550902049d93cc87be7857d138e8a50dce1f150a7bf90c95f23d75af0b11de53", + "sha256": "8a2500ed4781382c1629c058c27e7f93bba6c1f3a53d1b9276353e9a852f89f5", "width": 352 }, "palette": "dark", @@ -4074,7 +4077,7 @@ "image": { "height": 1024, "path": "images/toggle-dark-off-narrow-2x.png", - "sha256": "5a8b266738aea94375d3c4c43b7a27445a06148f8eab5874dc6ea938c44fe02f", + "sha256": "e3e25dcf2a5ca800962a20e11f0be0e5a1819089c8d5a77a1abfef254e6013fc", "width": 704 }, "palette": "dark", @@ -4095,7 +4098,7 @@ "image": { "height": 512, "path": "images/toggle-dark-on-regular-1x.png", - "sha256": "64237b6d114b57b89587255c312e7fbb710e57a5a738c4f90ff06b929b2adc71", + "sha256": "7cef736cc026aa009128c8af92dbe61c8704dbe48981319db7e092b35c44532e", "width": 800 }, "palette": "dark", @@ -4116,7 +4119,7 @@ "image": { "height": 1024, "path": "images/toggle-dark-on-regular-2x.png", - "sha256": "e9397af36851a2aaaa9a59b48ade34991270a2583056ff22de81456bd02ea7ab", + "sha256": "1fee0acd2ec8f68ac5d4c5bbf79bce093d16a72f26d8bb31441563ed2205a05e", "width": 1600 }, "palette": "dark", @@ -4137,7 +4140,7 @@ "image": { "height": 512, "path": "images/toggle-dark-on-narrow-1x.png", - "sha256": "f6f208fdadc8794f7c004eddb1c07b1865b3e46adcf140adc9901ec5962f2b05", + "sha256": "aab7991b5740730ecd9de986d382beba5427d47519c929abf60fbc4060bfb226", "width": 352 }, "palette": "dark", @@ -4158,7 +4161,7 @@ "image": { "height": 1024, "path": "images/toggle-dark-on-narrow-2x.png", - "sha256": "ae4c18bf1ab2fe8eb62c3cee5a8a02cf7f370a7457135b1d475171abb35db0fc", + "sha256": "19788907ae25d2bc4974f00e9494d394a583e504885c2cfc7865df3b1cdaf55c", "width": 704 }, "palette": "dark", @@ -4179,7 +4182,7 @@ "image": { "height": 512, "path": "images/toggle-light-off-regular-1x.png", - "sha256": "d85eb916c802584569fbce8dccbf93250e57cde6bad1ae8a65a44ad50831eea6", + "sha256": "93d0b1e17806390bd39038cbba5950f714702e2df0e52fe43241e8c088506fd4", "width": 800 }, "palette": "light", @@ -4200,7 +4203,7 @@ "image": { "height": 1024, "path": "images/toggle-light-off-regular-2x.png", - "sha256": "ef5578013369d4dedc9a6905b20a2b269cce9789d23807f58f103d87aabf4c53", + "sha256": "48a0d6f2e3febebf439fdda4b43daa773236bcf536091eb00a32178da53572e8", "width": 1600 }, "palette": "light", @@ -4221,7 +4224,7 @@ "image": { "height": 512, "path": "images/toggle-light-off-narrow-1x.png", - "sha256": "cae898a7b43457e311940dfb5c5fb942e1c7873dc8ae15c08cc5f7ee0ab562b0", + "sha256": "ef4b264df213db7812653d6ad03fe3f0cde10bb81d7ae86840835ca832875225", "width": 352 }, "palette": "light", @@ -4242,7 +4245,7 @@ "image": { "height": 1024, "path": "images/toggle-light-off-narrow-2x.png", - "sha256": "042a2324415f29aa3d132b030acf2b0379ef0803fbd46c45846364e5578a4ece", + "sha256": "918b8da959b6ca78f1e7e7bb08002ca1c73b03a961f252d9f11b3dd6bef3add0", "width": 704 }, "palette": "light", @@ -4263,7 +4266,7 @@ "image": { "height": 512, "path": "images/toggle-light-on-regular-1x.png", - "sha256": "c6552fed26de77e5fb2580b4dd3d64476872cc516623d0aa9836e541a0a091d3", + "sha256": "fa28c98d966fdac35c42f97c3e3f08c0b2e76900f4cbc2240f9fd64d9554c8ca", "width": 800 }, "palette": "light", @@ -4284,7 +4287,7 @@ "image": { "height": 1024, "path": "images/toggle-light-on-regular-2x.png", - "sha256": "2f7bc2e0f49b6a49b99a5d9eb04dc6c0a5934ce4abb742b2b106594f169df9ae", + "sha256": "d90b68a841892c1e1199f61c08476f82b3ef60678c07d52bf6b24a6bace5cffe", "width": 1600 }, "palette": "light", @@ -4305,7 +4308,7 @@ "image": { "height": 512, "path": "images/toggle-light-on-narrow-1x.png", - "sha256": "d7995da26aa252c0e3da01cb1fb0053d83204d5c5c9dc8803efdd260dd0ce68b", + "sha256": "952e738a18a738f2c4099d5f9c69939f30adb5cabd8639adcf3df2147fcf8230", "width": 352 }, "palette": "light", @@ -4326,7 +4329,7 @@ "image": { "height": 1024, "path": "images/toggle-light-on-narrow-2x.png", - "sha256": "2d174ea46e9970b659cd97d28eb27d12476403076984ee41cefd59b1fbed73b4", + "sha256": "7c03d9a42b3a580405f1cc1a89cb3df606c709a72a0478bbb6426e6969ae6203", "width": 704 }, "palette": "light", @@ -4347,7 +4350,7 @@ "image": { "height": 512, "path": "images/toggle-ocean-off-regular-1x.png", - "sha256": "02bb2eaee33fb2a8e5a62baa2bee2ba1f5f87a3061031b4fd1dcf1958dbcc9df", + "sha256": "053ab06fb2d4e6f488625a3d2705a6814859857b30cd78805b606881c6f2d505", "width": 800 }, "palette": "ocean", @@ -4368,7 +4371,7 @@ "image": { "height": 1024, "path": "images/toggle-ocean-off-regular-2x.png", - "sha256": "3f7e104a5903a964541b5ef754ebce8b2454341e81f105b42516413e21e803cd", + "sha256": "4fb039202a277d0033f6fcdfed561d6d52578ef8dd66de416ead954f0dbded17", "width": 1600 }, "palette": "ocean", @@ -4389,7 +4392,7 @@ "image": { "height": 512, "path": "images/toggle-ocean-off-narrow-1x.png", - "sha256": "2c1f61feb9ca18c3adfc8bf4efb4e30435d8fa857dc6742f262963ae88e00ea3", + "sha256": "9323f7dc031df3f62e39fdbaad2177489b6cec674b3bf7e333720a7bbde4a624", "width": 352 }, "palette": "ocean", @@ -4410,7 +4413,7 @@ "image": { "height": 1024, "path": "images/toggle-ocean-off-narrow-2x.png", - "sha256": "f7b1389207c4ee1fda3089dc3aeb47b189db6686aa8459cd28fbc74ab950d1e0", + "sha256": "cd468906701ef4a81a03f3a3869ef9bb638c08ee8091211a01e87d17e43be0e7", "width": 704 }, "palette": "ocean", @@ -4431,7 +4434,7 @@ "image": { "height": 512, "path": "images/toggle-ocean-on-regular-1x.png", - "sha256": "c6e036b1bace78cd6826d831009409fd3f1926bc71aedfa3b7dcc4552d49df97", + "sha256": "18a5a4fe13230f95cffa36a9a67199992d66ca9c501476462110f97dfe7c3279", "width": 800 }, "palette": "ocean", @@ -4452,7 +4455,7 @@ "image": { "height": 1024, "path": "images/toggle-ocean-on-regular-2x.png", - "sha256": "09df97cbd81ab170497ef685641a09ec8aaf4908dbd65d81852ad0994721e08f", + "sha256": "4ddcb0995dfc2a65678c29fb8fb05e1ab9140ed902fabbd775048f673728e4ca", "width": 1600 }, "palette": "ocean", @@ -4473,7 +4476,7 @@ "image": { "height": 512, "path": "images/toggle-ocean-on-narrow-1x.png", - "sha256": "1c47d14cb07a25760db297a15a08e55baf9fa56ec0aeb39704f941077d0ee543", + "sha256": "0357528a6e0fbf5183d1dad962c268d26fbb863555ebe861097dd71a316810ee", "width": 352 }, "palette": "ocean", @@ -4494,7 +4497,7 @@ "image": { "height": 1024, "path": "images/toggle-ocean-on-narrow-2x.png", - "sha256": "2324e1298463389a152513cd767bd6ae2a44f1694f644538aca4cec39f9e5c92", + "sha256": "9e6b86798ba573b7da8c95a2e0ff299862510ccb0fb4fadd620c38861bd6eae4", "width": 704 }, "palette": "ocean", @@ -4515,7 +4518,7 @@ "image": { "height": 512, "path": "images/toggle-forest-off-regular-1x.png", - "sha256": "440f05fca7efc0bc0ca13cfa9933dea11e81ce2c37505f73fad92dbcbe5e3821", + "sha256": "4d42007ea4983b893160f9a093c91a342f420284254e8458bf81792d1dd5c219", "width": 800 }, "palette": "forest", @@ -4536,7 +4539,7 @@ "image": { "height": 1024, "path": "images/toggle-forest-off-regular-2x.png", - "sha256": "2227423816c5a74119c9f44770060ad81aff83cae040e323fe5a65352dcf25e3", + "sha256": "bfabcd986277f3736d107772d4f9d71e72c156e9b671ff51f02503378cf81404", "width": 1600 }, "palette": "forest", @@ -4557,7 +4560,7 @@ "image": { "height": 512, "path": "images/toggle-forest-off-narrow-1x.png", - "sha256": "c75519985bf49ef2661b19162f053ad331c2cd80a6278c4f00f90c81505b319c", + "sha256": "599a890cfadac040d40826609134b652c7870c2bac08581f40bd97daebe95916", "width": 352 }, "palette": "forest", @@ -4578,7 +4581,7 @@ "image": { "height": 1024, "path": "images/toggle-forest-off-narrow-2x.png", - "sha256": "04293a9e1374e441a678edbeb5cdf5a5a84bff0032b04b35e84bf118cb1d775e", + "sha256": "cf912609830b1be7781400af52296a6a9c527ea982a221ebe65eedc927d3507e", "width": 704 }, "palette": "forest", @@ -4599,7 +4602,7 @@ "image": { "height": 512, "path": "images/toggle-forest-on-regular-1x.png", - "sha256": "638a57f46acbcfb3c4e8537acd109e1d12e35f86005140ac9392ba7d52a4eefc", + "sha256": "147a50fdd40521f7d0dc64e064ad5aabc1ecf07bcf749e5e6df5dafbaab94b7e", "width": 800 }, "palette": "forest", @@ -4620,7 +4623,7 @@ "image": { "height": 1024, "path": "images/toggle-forest-on-regular-2x.png", - "sha256": "286240c3407ef243e471c9fc5b6cb7c6dde250387979e16408f22f456490b7ee", + "sha256": "150a5a6ecb5d1678928adcae4e161c9507932a9476b5533f74c529e9a7a3fcd2", "width": 1600 }, "palette": "forest", @@ -4641,7 +4644,7 @@ "image": { "height": 512, "path": "images/toggle-forest-on-narrow-1x.png", - "sha256": "fc71cd3c8471c677ade8aed4c6cacf594a2962e487fdacad2375023e8f8ebb9d", + "sha256": "2e19ceade9f9b73b6754558e1c47901419f58d74cf487889e139c26fb152cc11", "width": 352 }, "palette": "forest", @@ -4662,7 +4665,7 @@ "image": { "height": 1024, "path": "images/toggle-forest-on-narrow-2x.png", - "sha256": "36ea6101fee2113e7f2f5efbc2f9f1dce070387a55315f38a3295f5a9c8ad629", + "sha256": "8d0016c78f5e6a26b21efc05b3ca7cdb287dd1ed6c456f890bc0af016606ba21", "width": 704 }, "palette": "forest", @@ -4683,7 +4686,7 @@ "image": { "height": 512, "path": "images/toggle-ember-off-regular-1x.png", - "sha256": "078196feaeb35eb58f0754110821ac25eebf3e74eda325d211622d7002e7252b", + "sha256": "7237df4cbf857ccc1ae5b5cd2949f9a143d986b5561c7319e12e9839e7df3117", "width": 800 }, "palette": "ember", @@ -4704,7 +4707,7 @@ "image": { "height": 1024, "path": "images/toggle-ember-off-regular-2x.png", - "sha256": "a1103a9ba6ddf38155543783fca8ab525b9381555d4d597ab73cdc11b718149e", + "sha256": "974e5ffb1bfc927854a094de7a7e15d99a8814e170fde10b46c26a24c77f64b6", "width": 1600 }, "palette": "ember", @@ -4725,7 +4728,7 @@ "image": { "height": 512, "path": "images/toggle-ember-off-narrow-1x.png", - "sha256": "a62636847eb418ca150ca4c68ac83007741aa2b9439714a0f6aec35421de2066", + "sha256": "2c21a8361f4d15077bba09cce37bee118b58fa6c921b650d1c8b0341e579c152", "width": 352 }, "palette": "ember", @@ -4746,7 +4749,7 @@ "image": { "height": 1024, "path": "images/toggle-ember-off-narrow-2x.png", - "sha256": "4c70842292ae40550ae4208866e2270a3f40fe94cf1dbd65cb949c80d77c409b", + "sha256": "082d85ae6ac396b8545cd5e6a42a9638963b0f3965b295348504706cb4a8ac02", "width": 704 }, "palette": "ember", @@ -4767,7 +4770,7 @@ "image": { "height": 512, "path": "images/toggle-ember-on-regular-1x.png", - "sha256": "5ba199bc92970915eb19908738744266eaae9382fb282c59a5394c7decd092e0", + "sha256": "d9964cec651faa44acd892a99ac1ea2643262bd41043fc5931a997b7fe7ddb85", "width": 800 }, "palette": "ember", @@ -4788,7 +4791,7 @@ "image": { "height": 1024, "path": "images/toggle-ember-on-regular-2x.png", - "sha256": "e0cff377253e719178f428027b82e28715fe0760d5f46e80b527d033cf682432", + "sha256": "00b70da0ff4a689c024dfc3fb64a50dbfc5c9ee66c167ac62dd83144ddefc798", "width": 1600 }, "palette": "ember", @@ -4809,7 +4812,7 @@ "image": { "height": 512, "path": "images/toggle-ember-on-narrow-1x.png", - "sha256": "efdf52b2c70bb1d1f3ced7b53da4ac9a22df572e96c61c77227bdc8fc1b9ce30", + "sha256": "ad58082a1feca93adc95c17175395c2f9da4c5791359ada860aead1d44a851c8", "width": 352 }, "palette": "ember", @@ -4830,7 +4833,7 @@ "image": { "height": 1024, "path": "images/toggle-ember-on-narrow-2x.png", - "sha256": "d331ec9ea98d5f01fb543a81c19a832ef7ce96d2dadafc2730e0fb54f41c5728", + "sha256": "111e3447f9b8ff38cb5b4243268596c62019918dfd49a03d7f32b38b3fcc3971", "width": 704 }, "palette": "ember", @@ -4869,7 +4872,7 @@ "image": { "height": 512, "path": "images/slider-dark-middle-regular-1x.png", - "sha256": "599ca0a80bc01ce4c115b78ac2e931b46b2d4531538b6b985760aa37e70445f5", + "sha256": "a73248947c4e43e5aa20fc7b81cbe050857445c9623f52df310245ec0b8bfd7f", "width": 800 }, "palette": "dark", @@ -4890,7 +4893,7 @@ "image": { "height": 1024, "path": "images/slider-dark-middle-regular-2x.png", - "sha256": "779554bfb6753a7a08197c782f04ac7efefd681524557dd100e57bacf3859391", + "sha256": "9e4d582672faa19fedc1f78b5a06d1f1fcbf97cc3be9c5ee39dc5acae10b2c1c", "width": 1600 }, "palette": "dark", @@ -4911,7 +4914,7 @@ "image": { "height": 512, "path": "images/slider-dark-middle-narrow-1x.png", - "sha256": "3cc5ec3468e801d21e8906995e8f09d3830f5bd30793e7a3c5d43e155de86bdf", + "sha256": "33ae39502055bad4dddde5da7c8a9bd2b8891a5d50853496894ac7b488b11db4", "width": 352 }, "palette": "dark", @@ -4932,7 +4935,7 @@ "image": { "height": 1024, "path": "images/slider-dark-middle-narrow-2x.png", - "sha256": "3b113b241e35cca6217af60097a2d2c0359a3d7978733d3cb24b7d4c820633b5", + "sha256": "657d83300f7ff049077327cbb6c3ba27077fcc4f39cafd4c9f35565b6cafe358", "width": 704 }, "palette": "dark", @@ -4953,7 +4956,7 @@ "image": { "height": 512, "path": "images/slider-dark-minimum-regular-1x.png", - "sha256": "a49f1ca9be16df3cd0519b33e090bce41e1423ec8ccb771369ebdba941a54889", + "sha256": "ccb2ac9ebdfdf8f49de5f0c66681c3874698028b7a1f810e2946592518849701", "width": 800 }, "palette": "dark", @@ -4974,7 +4977,7 @@ "image": { "height": 1024, "path": "images/slider-dark-minimum-regular-2x.png", - "sha256": "44f9e8bc00b066fa15e73670b1cf4bb5d9517639156fdcf2776466509aee1443", + "sha256": "6c224fb7dfdb7930a1f5f5b61aec6e082a51a37b393d832ed1cac6090223a6bb", "width": 1600 }, "palette": "dark", @@ -4995,7 +4998,7 @@ "image": { "height": 512, "path": "images/slider-dark-minimum-narrow-1x.png", - "sha256": "694329e57adfac65acc0fe11d809df53bc88755c866e5f6cbab3dd153830a8d6", + "sha256": "d8c21a218846d9bfa50d956e9b7bf133439f41dd36c9f0dc56389de4db14d611", "width": 352 }, "palette": "dark", @@ -5016,7 +5019,7 @@ "image": { "height": 1024, "path": "images/slider-dark-minimum-narrow-2x.png", - "sha256": "7ff471fdec6c79af340312b22841de7d5cf1321bd64430f3dd471ca37ade9163", + "sha256": "462c354781348c5f2e8b7344d03d70860465448c009b0f84267492166ad7eabd", "width": 704 }, "palette": "dark", @@ -5037,7 +5040,7 @@ "image": { "height": 512, "path": "images/slider-dark-maximum-regular-1x.png", - "sha256": "396d06a3839fb066040a60e2ba9242efe68bbe2e32fd10386cf95de2a6ad8901", + "sha256": "821dfc8e0067e29d9df5b1a707a2b2b04fc8474bce5cbf86ee5871605344a8d8", "width": 800 }, "palette": "dark", @@ -5058,7 +5061,7 @@ "image": { "height": 1024, "path": "images/slider-dark-maximum-regular-2x.png", - "sha256": "b60a75aadcaeb80cb900f8be5443dc3adb5b87367ad277a4f715c44f97f004cc", + "sha256": "67f8670eaeb8f541e9427abcc37f22f2ed0822e9ce9280b1493c6179eaeb12d6", "width": 1600 }, "palette": "dark", @@ -5079,7 +5082,7 @@ "image": { "height": 512, "path": "images/slider-dark-maximum-narrow-1x.png", - "sha256": "e32874141809a43b6686590867f86499ee5fa94d7a03870753cf8ff98e723c99", + "sha256": "6719bae12808bbb12602249d53901f1fd9788e28bc68054663a1c7f36a6639a6", "width": 352 }, "palette": "dark", @@ -5100,7 +5103,7 @@ "image": { "height": 1024, "path": "images/slider-dark-maximum-narrow-2x.png", - "sha256": "e7e1e1015e8b6facf55172fad37b911a11a60ea891899234738bd66a8a4a0afd", + "sha256": "3c5848deb45f32d4b780381e41fca5eafd4564dc5dd48b2dad4b5dc3b19170d7", "width": 704 }, "palette": "dark", @@ -5121,7 +5124,7 @@ "image": { "height": 512, "path": "images/slider-light-middle-regular-1x.png", - "sha256": "f9648f7a2883b972c2b993307caa55cf1287e2620fa084b305d07c71ea6874e7", + "sha256": "90bb0332aeeb013a77c18028e60d679ec41025deffded735d527c9b1d84afd9c", "width": 800 }, "palette": "light", @@ -5142,7 +5145,7 @@ "image": { "height": 1024, "path": "images/slider-light-middle-regular-2x.png", - "sha256": "1f688bc11005e19e954f44476e9819ea58bd3dd77fa2743c8be46f1f724d42a3", + "sha256": "fc67dd548822b97b523e4522c602c83dbe497198a65d4089770baf666e919917", "width": 1600 }, "palette": "light", @@ -5163,7 +5166,7 @@ "image": { "height": 512, "path": "images/slider-light-middle-narrow-1x.png", - "sha256": "857016e0b9aed13b6a4b58029a42c6c79ba155fac118e1b24ed0afada33966ba", + "sha256": "485b4ca4db4092eadd5bbdac70a970b5a1832f78e7f38a3f2e932d88fac4c58f", "width": 352 }, "palette": "light", @@ -5184,7 +5187,7 @@ "image": { "height": 1024, "path": "images/slider-light-middle-narrow-2x.png", - "sha256": "f60dee55863fb1a4887aef9b23082048658c4c7a95cab1d52a2a4e115fdc8192", + "sha256": "1a54eb60c0b33fce9f09e896732e2bd4c0da0993043516610080bf746d4a9ea2", "width": 704 }, "palette": "light", @@ -5205,7 +5208,7 @@ "image": { "height": 512, "path": "images/slider-light-minimum-regular-1x.png", - "sha256": "e1c5f1f0d3846fa2ecd488df54869ab2a615218b00781bc8cf8196ca50fd81fd", + "sha256": "77be49500ce5dfc1df44640c9612e2bde4c800af2d746d4785568659e90f3a4b", "width": 800 }, "palette": "light", @@ -5226,7 +5229,7 @@ "image": { "height": 1024, "path": "images/slider-light-minimum-regular-2x.png", - "sha256": "97f15d20b247e2de7f4dd4343e6f85a0bdf6afe731c486bcb8ca34e5405051b6", + "sha256": "621f574b1c0084e71efb1363f1470df63f5f8ee42bc3b5ccdda5f8c8146bfb11", "width": 1600 }, "palette": "light", @@ -5247,7 +5250,7 @@ "image": { "height": 512, "path": "images/slider-light-minimum-narrow-1x.png", - "sha256": "b7a21331be286369fb89102e8e05a879d7c8cf6e0a61f1b3ac953b0ee4cec8ea", + "sha256": "3c9807241426461876a82ddf60247d72a61aa911ef2c92db17d78f794413b02e", "width": 352 }, "palette": "light", @@ -5268,7 +5271,7 @@ "image": { "height": 1024, "path": "images/slider-light-minimum-narrow-2x.png", - "sha256": "6114dde91ab6b9c8c01e6310e322b5a3d7006c5b2ced81d441ec1de98f1aeaf7", + "sha256": "c92944ceebca216836a26573dfec4784edeabb159a63bca361d23a6e22bb7b81", "width": 704 }, "palette": "light", @@ -5289,7 +5292,7 @@ "image": { "height": 512, "path": "images/slider-light-maximum-regular-1x.png", - "sha256": "6c1f7a0b46e68de66e7f4b96a757cc06327f8c2aea0b2056f482ee99d866cc8d", + "sha256": "637acfaa569112930a6c4c743be783ed075341216a694af0aff7dc32e9f4fc95", "width": 800 }, "palette": "light", @@ -5310,7 +5313,7 @@ "image": { "height": 1024, "path": "images/slider-light-maximum-regular-2x.png", - "sha256": "c85821f885a2c30bd254840f09b3df5d9121a4b5750e1d18bc65c0aff6072d5f", + "sha256": "bd687ed5a6e1413ef5554a9b51642ae0e82ef9d17e4928edd59c5d4df85999b7", "width": 1600 }, "palette": "light", @@ -5331,7 +5334,7 @@ "image": { "height": 512, "path": "images/slider-light-maximum-narrow-1x.png", - "sha256": "7f5eecb19bc1ed7e0874b219655c8a18c8145092b54881391b4e0eba11d2161e", + "sha256": "dd0125cc966f011df4aebbf9ec04e05d7ea1b7e2ef8c97c825196cf598761a8b", "width": 352 }, "palette": "light", @@ -5352,7 +5355,7 @@ "image": { "height": 1024, "path": "images/slider-light-maximum-narrow-2x.png", - "sha256": "7eb83d1a29a7d8ebb36403f149badd49b660983ddf0f7c7df7abc877f356a722", + "sha256": "578d3173e2f34cffece159314c1000b5dc102da6bbf974f0f68847b85020a79b", "width": 704 }, "palette": "light", @@ -5373,7 +5376,7 @@ "image": { "height": 512, "path": "images/slider-ocean-middle-regular-1x.png", - "sha256": "52f73b360e7f203719d25a49ffa93dc4147c49fd0db6d117fb5f5107239e1dce", + "sha256": "080b31a81686c4bb0d20946ea14c5eb523ce13f3b83dd26fc5732a425b173853", "width": 800 }, "palette": "ocean", @@ -5394,7 +5397,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-middle-regular-2x.png", - "sha256": "ba47f4bf3e0c053373167894bf91b33481fa2c7eb333dc80386a98646d70e5d0", + "sha256": "ae69740112a7d8e70c4908da50566339191a35bcb5c935b6a430804919ad4992", "width": 1600 }, "palette": "ocean", @@ -5415,7 +5418,7 @@ "image": { "height": 512, "path": "images/slider-ocean-middle-narrow-1x.png", - "sha256": "c6398324b2e0a96c71a9f9b357b6c62bda7ad6ea7c92b2db1e1280fd99f18ccc", + "sha256": "c1d1f24c29b41c870530ce3a9d3e17e870fdc67226753d32f59258874d5b3bb8", "width": 352 }, "palette": "ocean", @@ -5436,7 +5439,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-middle-narrow-2x.png", - "sha256": "9067df8302d04496b1e76df89ee5dd8c39e049d85f6c80edf2987a9caa329b0d", + "sha256": "0a4c0567c0459ff84edaca24ebf28155a47b46431fa9217066786ac91b1054c3", "width": 704 }, "palette": "ocean", @@ -5457,7 +5460,7 @@ "image": { "height": 512, "path": "images/slider-ocean-minimum-regular-1x.png", - "sha256": "8406db435b18552d56a3b2ee4058d0e7312046f1fb7694802f0eff87284e3f6d", + "sha256": "a18666f66d0840e366df49bdefc960738f6f1df3ab3244d0c834fe8f69f29cb5", "width": 800 }, "palette": "ocean", @@ -5478,7 +5481,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-minimum-regular-2x.png", - "sha256": "c8f71c1485f749e48e967ddb2122b4fc3413e8aec220595603ddd6fd2fd50fa6", + "sha256": "c6a3a4863c9dc8a9bc963b8786e422542946b44a75fc77b256861160665fdc0e", "width": 1600 }, "palette": "ocean", @@ -5499,7 +5502,7 @@ "image": { "height": 512, "path": "images/slider-ocean-minimum-narrow-1x.png", - "sha256": "5f4c682d8179c68040bd1e027118c37ae55aec5813acc2cb25a7d7fc8361e0e4", + "sha256": "568804bb60cb0fd18953e9b3a74c744a5cdd346b3aee32e40bec3f2fccdf65f8", "width": 352 }, "palette": "ocean", @@ -5520,7 +5523,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-minimum-narrow-2x.png", - "sha256": "d972c0bd928c5484bdd3a4d1f5f226bd628582af53bc3d0e8f2ae5931dfa7bf8", + "sha256": "15460b68e2469877f352d64616de9f85abb77a047fe05970e4293e13d5e01ab3", "width": 704 }, "palette": "ocean", @@ -5541,7 +5544,7 @@ "image": { "height": 512, "path": "images/slider-ocean-maximum-regular-1x.png", - "sha256": "8e45fd84f8afb14f6a85324d20a1ef62403bcae985253d211ce163deefa647e0", + "sha256": "0ace1121add965769c06ea29c3df8315bd3431b99c9276ca5e03d7c809912c8f", "width": 800 }, "palette": "ocean", @@ -5562,7 +5565,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-maximum-regular-2x.png", - "sha256": "c9e915b77b6ce8fb62d1a51b88ab78b887253d1738f786305a2f0751e601ed07", + "sha256": "3f9c80962a5252a70c958f7d8a84cc4f3c4e75e2103a36fb09a4b0a2f156473d", "width": 1600 }, "palette": "ocean", @@ -5583,7 +5586,7 @@ "image": { "height": 512, "path": "images/slider-ocean-maximum-narrow-1x.png", - "sha256": "ec433e3592abab86b5e831fd9cfe89c80b3217555ea5c595f7a4d2325e34712e", + "sha256": "29c1d6ed8900f400358117044d855c0b90aaf1f332a711abc65380c29f2f9ba2", "width": 352 }, "palette": "ocean", @@ -5604,7 +5607,7 @@ "image": { "height": 1024, "path": "images/slider-ocean-maximum-narrow-2x.png", - "sha256": "2f6ac84bb852cbbcca21dce52c6142744687d74c279fd9fd5add84ca2c79e3a5", + "sha256": "b740785b62734c64880d77c8f49a271c5d5e3132d6908a529d7804d1cc088665", "width": 704 }, "palette": "ocean", @@ -5625,7 +5628,7 @@ "image": { "height": 512, "path": "images/slider-forest-middle-regular-1x.png", - "sha256": "e8a8aa8b35923b3fa4741d31d6b36bb52f419de9c1c857bd5a44f88d468930ec", + "sha256": "9f165c94c2abd282913e8e93f050b95761cac976772bcb62586a61acbd49541d", "width": 800 }, "palette": "forest", @@ -5646,7 +5649,7 @@ "image": { "height": 1024, "path": "images/slider-forest-middle-regular-2x.png", - "sha256": "eae9d230b0130cee6fb18006e0c77e5930475b8beddd56482032d6716034bb23", + "sha256": "e5d602a18f3349c1488d96360587ffaf3a9d841ee3bc7fef3a45ab079bf019d2", "width": 1600 }, "palette": "forest", @@ -5667,7 +5670,7 @@ "image": { "height": 512, "path": "images/slider-forest-middle-narrow-1x.png", - "sha256": "4ef8f10141b2c6cd78c2b12c918b71f76dda89f69e6670ed71082f6095e7b6b3", + "sha256": "7eb0c5d6450f0449a08111bdad1eb8aa3ef070a4688f0778f57ed90ac3289370", "width": 352 }, "palette": "forest", @@ -5688,7 +5691,7 @@ "image": { "height": 1024, "path": "images/slider-forest-middle-narrow-2x.png", - "sha256": "f3ed7a2d6d65ccea5df362edd9c0b878cd9a0023ade9364ea0a90d575c68ca15", + "sha256": "12777cd5f9bb18a6e421c9e6d378b49a59f4711d2b140354aabbb974ea52ea3a", "width": 704 }, "palette": "forest", @@ -5709,7 +5712,7 @@ "image": { "height": 512, "path": "images/slider-forest-minimum-regular-1x.png", - "sha256": "38b351c2cfd80309422e92aabad20b1b38d9a3f6403dec80df06b22cd94f8a1f", + "sha256": "b675cb59d5f77befb4b19bf34e5f551ff667ede24ce0692b9f7998ba8d4f6f7d", "width": 800 }, "palette": "forest", @@ -5730,7 +5733,7 @@ "image": { "height": 1024, "path": "images/slider-forest-minimum-regular-2x.png", - "sha256": "7775ec6c4630881e9a28d3e47b9d5c43d917b1e737bdbd75035fca0ad9016836", + "sha256": "806aa4cbe30144ab0752c25c4919a1278e1443ac0142d698269b6ee484e2778f", "width": 1600 }, "palette": "forest", @@ -5751,7 +5754,7 @@ "image": { "height": 512, "path": "images/slider-forest-minimum-narrow-1x.png", - "sha256": "07e4ebdab1a92ea42760edae0cafe3abfb60120655455a48706612474274b020", + "sha256": "9a26bf0b4e96bd8abca26330db47fefb2419079dfd102ed8707ecea56e667ee1", "width": 352 }, "palette": "forest", @@ -5772,7 +5775,7 @@ "image": { "height": 1024, "path": "images/slider-forest-minimum-narrow-2x.png", - "sha256": "b7e15d79f2dfc35bb15870524da545167be3218928647a81f846040660c6b7d8", + "sha256": "7c9493bb407bd3c947b7972a149b4ed4ae9325defbf574f9a2709788bf907b6f", "width": 704 }, "palette": "forest", @@ -5793,7 +5796,7 @@ "image": { "height": 512, "path": "images/slider-forest-maximum-regular-1x.png", - "sha256": "64296d9651fb9e5b4fd3d17dd47d2c70bb373c8a6fe58e8cb10db9db4e38eb6d", + "sha256": "2fb84f4e28e8f03edb1e097b38502499caf2b09dcfb17b80714880a10b49f1db", "width": 800 }, "palette": "forest", @@ -5814,7 +5817,7 @@ "image": { "height": 1024, "path": "images/slider-forest-maximum-regular-2x.png", - "sha256": "c438ba6e7c024f551170507cbd558971eb24b4e11e969f5f6a240d9b992babb2", + "sha256": "9e17406f4f9deaab1bed30ae79934b82d6732a197148ca89b36712bbcca814f4", "width": 1600 }, "palette": "forest", @@ -5835,7 +5838,7 @@ "image": { "height": 512, "path": "images/slider-forest-maximum-narrow-1x.png", - "sha256": "05b7bd850d7ab5f300dab51787b0a1212377a8b96911330a1bb3a17aea88fb80", + "sha256": "51eb635b96957126b09424e39ea95a5b45bded1c17ae7b5b0eda2b3061b1fd9b", "width": 352 }, "palette": "forest", @@ -5856,7 +5859,7 @@ "image": { "height": 1024, "path": "images/slider-forest-maximum-narrow-2x.png", - "sha256": "446ff22a7c153daf301e64a63efe79d3be0bdb74719fe20dea73caf18f0056ff", + "sha256": "ce8d911d4d7abad94f97983f260cc4b4d417b4b5f81c5940e3b8d2a9163696b1", "width": 704 }, "palette": "forest", @@ -5877,7 +5880,7 @@ "image": { "height": 512, "path": "images/slider-ember-middle-regular-1x.png", - "sha256": "411381b30c70a9996a7f589e3d18933475addeac90ee1f4a049a970c9b10c5e6", + "sha256": "c8cf727c4ba92020bf4566286c64c322ef144232add77c9db8f7b82c55e5514b", "width": 800 }, "palette": "ember", @@ -5898,7 +5901,7 @@ "image": { "height": 1024, "path": "images/slider-ember-middle-regular-2x.png", - "sha256": "b68154f49f6f47064706d39cf8a23fd4081151232c22566a41fb0d26b7301962", + "sha256": "6eac5dbc14129681e75b4f886ace1b83a7a11eb758d82e76e4011820451a91de", "width": 1600 }, "palette": "ember", @@ -5919,7 +5922,7 @@ "image": { "height": 512, "path": "images/slider-ember-middle-narrow-1x.png", - "sha256": "aec688612ab5e22c58503bc91fdce6fc6e1a8e0ab53bbc1b81c030967dfa4318", + "sha256": "38d8bed4f4cd51253fd43dfd29d38619cb83e4b6b8f73bbd3803ca2be3821ad7", "width": 352 }, "palette": "ember", @@ -5940,7 +5943,7 @@ "image": { "height": 1024, "path": "images/slider-ember-middle-narrow-2x.png", - "sha256": "28d1cb40ff7e89d4e98dd846c10d49f0e75c1b0a1ee45134a2c1e0ead2e278c4", + "sha256": "0aefc10af449d4cbdbf10e32050ee45c0ea10380ec7103b4900f7917854ebbf8", "width": 704 }, "palette": "ember", @@ -5961,7 +5964,7 @@ "image": { "height": 512, "path": "images/slider-ember-minimum-regular-1x.png", - "sha256": "0ca777798a713d4e9991474a69a8d40208f6c3ee18b7b39957175119389940c5", + "sha256": "d47e498f47825efccef3bf0f7933cb38704946258f011776b8cd1ae1e622fc8b", "width": 800 }, "palette": "ember", @@ -5982,7 +5985,7 @@ "image": { "height": 1024, "path": "images/slider-ember-minimum-regular-2x.png", - "sha256": "99ddea9a7922d5428f5a427da1f322e84b388dce3686fa951241f415a97f3758", + "sha256": "b9a27e69e42457ebef6dfdc6576328bc0eb25148cdaf3bbc7383a1d42ea94200", "width": 1600 }, "palette": "ember", @@ -6003,7 +6006,7 @@ "image": { "height": 512, "path": "images/slider-ember-minimum-narrow-1x.png", - "sha256": "f795ee4ef4178f0ada1f3aa825720feb96206b7393851da460f26bcfd9958c42", + "sha256": "8d384cc096107c891680d19cbb427423d4b7db6e02bd00a4462a4e4a410e30ff", "width": 352 }, "palette": "ember", @@ -6024,7 +6027,7 @@ "image": { "height": 1024, "path": "images/slider-ember-minimum-narrow-2x.png", - "sha256": "4e360f23fe475d58f57b740c834a2a8f16abc13eae100d2a924b5fac07fbdb27", + "sha256": "840504b1bf862c90b7e712261014e6350f1e8938e0deddb66d098a1d72434c74", "width": 704 }, "palette": "ember", @@ -6045,7 +6048,7 @@ "image": { "height": 512, "path": "images/slider-ember-maximum-regular-1x.png", - "sha256": "d431c82764932e7773208b36531ce5b493272cd72f7f894f6bfb87847672bff9", + "sha256": "83c0e80abe5ab2eca74f85189ef924e8d4e3a2d6806c09b3b81fb359609a402a", "width": 800 }, "palette": "ember", @@ -6066,7 +6069,7 @@ "image": { "height": 1024, "path": "images/slider-ember-maximum-regular-2x.png", - "sha256": "bd504d4dbc43a9aa9252e8a2e2d0721692ee361ad3e27e56de82aeca475f8a31", + "sha256": "594084d0d2a745283bd2e61d551d6a5d0633baac6f2fa8090a70cf3bebb6a288", "width": 1600 }, "palette": "ember", @@ -6087,7 +6090,7 @@ "image": { "height": 512, "path": "images/slider-ember-maximum-narrow-1x.png", - "sha256": "5b09f623fe65c4b8f7c91ea4c6533e425725cf91a1b8ca59f51693f532b189c5", + "sha256": "25ed73f2f770f0c4989781b754272103005676c4b775a4cf35f6a21f9bc24cf2", "width": 352 }, "palette": "ember", @@ -6108,7 +6111,7 @@ "image": { "height": 1024, "path": "images/slider-ember-maximum-narrow-2x.png", - "sha256": "fc2ddf62ea4801c8f38bbe29a09e435818737337de7367a1b1fb8d0daf09b2ea", + "sha256": "7333b35955c1c8407025ea323ef3e9721cb57a5dd64c69fcfdf0242bfb8c992c", "width": 704 }, "palette": "ember", @@ -6147,7 +6150,7 @@ "image": { "height": 512, "path": "images/scroll-dark-top-regular-1x.png", - "sha256": "ceb7c59662a4d0c0dbb95241ab402f45c303648744aeae0c938030118525f88d", + "sha256": "2267535fd4337e619252af6a9a53cb3fe46497e61a4b9e938613355a954b171b", "width": 800 }, "palette": "dark", @@ -6168,7 +6171,7 @@ "image": { "height": 1024, "path": "images/scroll-dark-top-regular-2x.png", - "sha256": "3683229e19bf677e680784b7b62f01193a1f6cde57d71ee5d1be27c7ebb582a1", + "sha256": "7977ad1a67b7f2c54acfee893b1a0d73f557c39c9efdfefa0d4c4c935bfb4b7b", "width": 1600 }, "palette": "dark", @@ -6189,7 +6192,7 @@ "image": { "height": 512, "path": "images/scroll-dark-top-narrow-1x.png", - "sha256": "07ff23692b06169550611126a462e9f1df596dc3d4c9dd5cd7723efc43df0e68", + "sha256": "0c92af905113cecee9d3d22229e0d338f85b5e0a0f676bcd299e8d20474d729f", "width": 352 }, "palette": "dark", @@ -6210,7 +6213,7 @@ "image": { "height": 1024, "path": "images/scroll-dark-top-narrow-2x.png", - "sha256": "b1457743faa851722d9c4d579d2e6f7835758e7fcc4662282753e134aa47ecef", + "sha256": "8c3e0af3794bf4daa994f153fa7864baafacf115566e9fc8ac09da61693bd342", "width": 704 }, "palette": "dark", @@ -6231,7 +6234,7 @@ "image": { "height": 512, "path": "images/scroll-dark-bottom-regular-1x.png", - "sha256": "f5b85260b6f1ac1967e6b71130634185a084713e3bf73dbe3746c48eedf88d6f", + "sha256": "6cfededfc71fdc546e754859c34d61f7e1bebdec92fc93a5e51ee3d4a1ff45a6", "width": 800 }, "palette": "dark", @@ -6252,7 +6255,7 @@ "image": { "height": 1024, "path": "images/scroll-dark-bottom-regular-2x.png", - "sha256": "a1531590434fbe6864d119767b6d5d1c8499c1e5b01364b1a0037cffe26f3634", + "sha256": "0267b189feec210e6532f994ac79939fd378a55648f2e4cdf5a66297156e7dd5", "width": 1600 }, "palette": "dark", @@ -6273,7 +6276,7 @@ "image": { "height": 512, "path": "images/scroll-dark-bottom-narrow-1x.png", - "sha256": "56d271ac385c4ed18bc4133619695f2135dbbd47d6f816a6d51a4ed1ed891d9e", + "sha256": "99c03bd1cfb8c88ef7f0dda52aba60831ea5973abedd339d2205a4f55c2a41e2", "width": 352 }, "palette": "dark", @@ -6294,7 +6297,7 @@ "image": { "height": 1024, "path": "images/scroll-dark-bottom-narrow-2x.png", - "sha256": "a142f74166d6ed01876181cb2a94742daf1f9ea69af78bb802816a61c19288d0", + "sha256": "54bf8d8d60e0c812fae0bc633562f71249c51bc5a0edc4b37ce1aeeaaf402a0b", "width": 704 }, "palette": "dark", @@ -6315,7 +6318,7 @@ "image": { "height": 512, "path": "images/scroll-light-top-regular-1x.png", - "sha256": "2958a54155e3bfb8ddb4e5b17d6cf4f319dc3bce8d92c1e6ca93e3249505ce2c", + "sha256": "89697589810ee0b357e25e6a7d384428174fbc8ef5038c65df5934f6dd2d5159", "width": 800 }, "palette": "light", @@ -6336,7 +6339,7 @@ "image": { "height": 1024, "path": "images/scroll-light-top-regular-2x.png", - "sha256": "b114a9c1a5525832aa58143654cfb35dc981ea7377e8903bf9a6005e265e35f4", + "sha256": "2c8d8b3d6cfec1d62eaf12ceeab95b5a0e70e8630d2dead25446fca1c6758bf3", "width": 1600 }, "palette": "light", @@ -6357,7 +6360,7 @@ "image": { "height": 512, "path": "images/scroll-light-top-narrow-1x.png", - "sha256": "a7e5075fccb57b514773723f9272ba62270664a5539246118dc6a51433e58196", + "sha256": "8950ac40a3b271a8c4a8af805dc4a38c4d81e6784d5c307be3d60150624b203a", "width": 352 }, "palette": "light", @@ -6378,7 +6381,7 @@ "image": { "height": 1024, "path": "images/scroll-light-top-narrow-2x.png", - "sha256": "3a3ee4adf1e6c973c6b9cd0b9709dd0a179976907360592d39fcc4c096a91a7a", + "sha256": "09b91b4fefe4dabb232e927632f670735e6d0f7c4475de3fa0f358f1b433814b", "width": 704 }, "palette": "light", @@ -6399,7 +6402,7 @@ "image": { "height": 512, "path": "images/scroll-light-bottom-regular-1x.png", - "sha256": "cc13979114d04c9d593891fe33b58c074b1be5202b5d039d282ff8ecf04ec21e", + "sha256": "54ababd7653005fafa4403c71b18580ea3f229dcb1c652a7ea62bcbc218ecbd5", "width": 800 }, "palette": "light", @@ -6420,7 +6423,7 @@ "image": { "height": 1024, "path": "images/scroll-light-bottom-regular-2x.png", - "sha256": "74bd5cc1f10043ab5837fc97b33fc35c7784b3b97740d313fc6836eb1759d5ed", + "sha256": "ade35f59a9fdb98627d7fdd8b6fade52e421e0cfb9ba9b22de632ad5678bc7e3", "width": 1600 }, "palette": "light", @@ -6441,7 +6444,7 @@ "image": { "height": 512, "path": "images/scroll-light-bottom-narrow-1x.png", - "sha256": "4dd364ef32216fbe02f6d9d2d8ffb0b2c4065abbe341284a13bfbdeeef91190b", + "sha256": "4a855e6f697f770382c2fd6fdc60c497118f6d9d77264ac6f41615461a2b341a", "width": 352 }, "palette": "light", @@ -6462,7 +6465,7 @@ "image": { "height": 1024, "path": "images/scroll-light-bottom-narrow-2x.png", - "sha256": "b1a5c692d3f6d23e754d6085327156c55338745e59a2fe63abdf2948f27d5745", + "sha256": "f0b6921deac69be86ebfe860400360c88d5616ed6870b3f514fed093e49abd70", "width": 704 }, "palette": "light", @@ -6483,7 +6486,7 @@ "image": { "height": 512, "path": "images/scroll-ocean-top-regular-1x.png", - "sha256": "31a1361da86098d105da1175c51884c4839972bb343ec0bee5f8177ac0b4013a", + "sha256": "5c7fce3bc1f202d460a466bcc8c120d22238f9c2cd181ce7f0328324021281d3", "width": 800 }, "palette": "ocean", @@ -6504,7 +6507,7 @@ "image": { "height": 1024, "path": "images/scroll-ocean-top-regular-2x.png", - "sha256": "ae00f72c52c964849957be2df92415fd2c8cf184bfce595cbc8beea9d757af8a", + "sha256": "49bb00b1a5adfe0da89c6d9b89244d73a609ae9caead7ac8077ecbdc4473be66", "width": 1600 }, "palette": "ocean", @@ -6525,7 +6528,7 @@ "image": { "height": 512, "path": "images/scroll-ocean-top-narrow-1x.png", - "sha256": "31ba9cc6a8ae5287619265133e3de0b24171ed165aa61c37d315d0495f3801ce", + "sha256": "99395274ed4e693889b2edd2a478884f2a917eed7a8a179407085bb363aa2e3a", "width": 352 }, "palette": "ocean", @@ -6546,7 +6549,7 @@ "image": { "height": 1024, "path": "images/scroll-ocean-top-narrow-2x.png", - "sha256": "c5a43c3cda23dba3b6a26b0f3ad085ecffb0be3b2f997d75ef249068ffd40aea", + "sha256": "a720587b12d080d5425532b060bd39e6705aa969fee57b22c0388d07622efb27", "width": 704 }, "palette": "ocean", @@ -6567,7 +6570,7 @@ "image": { "height": 512, "path": "images/scroll-ocean-bottom-regular-1x.png", - "sha256": "084af7862df768c06c21051e0946e341d3701db1857e0202b1631713c8046fed", + "sha256": "91c836efd098244a203b0957bafc70fc4e83ec68d741f4372535f6738c8895a5", "width": 800 }, "palette": "ocean", @@ -6588,7 +6591,7 @@ "image": { "height": 1024, "path": "images/scroll-ocean-bottom-regular-2x.png", - "sha256": "c3b087dc2d7bc16532995c40b76aa13058cc8396874824e34a508b9f299e9c9a", + "sha256": "0b225c0ddccb6cd95c06c6c8736769585a934279302b128f12878ecd22279bcf", "width": 1600 }, "palette": "ocean", @@ -6609,7 +6612,7 @@ "image": { "height": 512, "path": "images/scroll-ocean-bottom-narrow-1x.png", - "sha256": "cbaf6d28f5953e07615a6785f010b47c88e318857a742b754feaf1566e8e0327", + "sha256": "965647cedb2977a4160791daee7a5862478275989887ca50500a537c97690baa", "width": 352 }, "palette": "ocean", @@ -6630,7 +6633,7 @@ "image": { "height": 1024, "path": "images/scroll-ocean-bottom-narrow-2x.png", - "sha256": "e1f020538268d6a6e12696a4055503f825cd23a05c8a19090a999e2b7a56ff0e", + "sha256": "ee6fa212713cd83e1b8fd6c70936977ad6c50b0d47e94096537b7384ba036d59", "width": 704 }, "palette": "ocean", @@ -6651,7 +6654,7 @@ "image": { "height": 512, "path": "images/scroll-forest-top-regular-1x.png", - "sha256": "776181e323d10d6a2fc5172679e09172aa67bb355e00cec01c53338ca7d4c4bd", + "sha256": "aa22795dafffa75af614bc79cc941541d07382de53be42219c5ba0708af922e9", "width": 800 }, "palette": "forest", @@ -6672,7 +6675,7 @@ "image": { "height": 1024, "path": "images/scroll-forest-top-regular-2x.png", - "sha256": "d9f3dfaf46cf606d90c3213b63bb9f2ed461e113d9c214f9b11738eec0c598ff", + "sha256": "5dcacf4b325b488554922160e6db0eeaad23f3ef775caa8a6e62cd8f110da6e4", "width": 1600 }, "palette": "forest", @@ -6693,7 +6696,7 @@ "image": { "height": 512, "path": "images/scroll-forest-top-narrow-1x.png", - "sha256": "65f74f14e39f5afa1af9d4ea08b863ae66b87761551404528eda8eda581d7b0e", + "sha256": "45a8b5a5e309abbf0fa92e7bf376b1145952e3eb94e3c75467c4bc1a4811a36d", "width": 352 }, "palette": "forest", @@ -6714,7 +6717,7 @@ "image": { "height": 1024, "path": "images/scroll-forest-top-narrow-2x.png", - "sha256": "1d61b6f2acd06559380a6b334fbedccd51f293f03b91fd961e8a6eb60183722e", + "sha256": "2ebd95a492e37ef7f04fc7dc03d070e9abdc2932c4e44b70c11d0dbfcd9f33b8", "width": 704 }, "palette": "forest", @@ -6735,7 +6738,7 @@ "image": { "height": 512, "path": "images/scroll-forest-bottom-regular-1x.png", - "sha256": "077310efb3f747c60b640479497e8f0c87390be46be7cfda3b954988d69c5592", + "sha256": "772a29f3d793a081e477c19b8413040e85d86d370a06dee3f7129d17afdfa99b", "width": 800 }, "palette": "forest", @@ -6756,7 +6759,7 @@ "image": { "height": 1024, "path": "images/scroll-forest-bottom-regular-2x.png", - "sha256": "909e2c93d314a80e4cc28bde659cd9a528722f77b6f91c18c5a01c749730228f", + "sha256": "d726a0cc80ddae3531ad7bc05c203336bdfa39d24a92d99147e50d33b3d8bd17", "width": 1600 }, "palette": "forest", @@ -6777,7 +6780,7 @@ "image": { "height": 512, "path": "images/scroll-forest-bottom-narrow-1x.png", - "sha256": "c3696fc039189895eb79079e4399d325c7d7f65e74366939609b13e30a0afd82", + "sha256": "14db91a7125255cdf35f750b4e0a5ffacfb642ae54a000744f4c003fc287f6ce", "width": 352 }, "palette": "forest", @@ -6798,7 +6801,7 @@ "image": { "height": 1024, "path": "images/scroll-forest-bottom-narrow-2x.png", - "sha256": "3015bdcce5b680c2c98cd3d45b4311cd12021cdd345670736471212e1c64b512", + "sha256": "cd39eb17a50fdaa05ef07a6b2f892c0e1af5a9babcef5f7f2b461288a954bf5a", "width": 704 }, "palette": "forest", @@ -6819,7 +6822,7 @@ "image": { "height": 512, "path": "images/scroll-ember-top-regular-1x.png", - "sha256": "f46b30d077f1d52576fe1950c2389afec6c2dc89cc1739090f80eaa6b0e9c00c", + "sha256": "6a4a980eceeeccb13c41946915dfa8dd0011d9b3cceaa2019f598d98ced1d759", "width": 800 }, "palette": "ember", @@ -6840,7 +6843,7 @@ "image": { "height": 1024, "path": "images/scroll-ember-top-regular-2x.png", - "sha256": "2dc86b6531f09faab06df9e96abd6424c59ae891e35b318f7ed520f7896ea468", + "sha256": "0d56f74edef8d8f245294f9e0f6728a3103bf420ebedd3688a19a6988d2b8a84", "width": 1600 }, "palette": "ember", @@ -6861,7 +6864,7 @@ "image": { "height": 512, "path": "images/scroll-ember-top-narrow-1x.png", - "sha256": "c00f1ac8439597211e99c370ebe040367f36a466411790076004a06ed5a336fe", + "sha256": "ee489a851bbdf20dd13ac7da03eddfe948f2293cd5c1ccc65683b3144d4ab3cd", "width": 352 }, "palette": "ember", @@ -6882,7 +6885,7 @@ "image": { "height": 1024, "path": "images/scroll-ember-top-narrow-2x.png", - "sha256": "e92f3db0a7e3f7f7ef7215697d3e5d76a1fe485726247d4b1b3b2582d78d0bcc", + "sha256": "426cf6a20f99f874891c80bdf385cd45370584e9b1e344739f3d329479d68f83", "width": 704 }, "palette": "ember", @@ -6903,7 +6906,7 @@ "image": { "height": 512, "path": "images/scroll-ember-bottom-regular-1x.png", - "sha256": "3f10e7f90f588add27f41e95c6d6354ce31230a2fbe55a85cc2648dd6cc5f791", + "sha256": "47a2013ae4eed5d85d1c2d4aa6d3b651bf2d61c6eab1f962e0a79691a1a6f297", "width": 800 }, "palette": "ember", @@ -6924,7 +6927,7 @@ "image": { "height": 1024, "path": "images/scroll-ember-bottom-regular-2x.png", - "sha256": "980cae5ffe2eb9a51c2eb737e32c2f60dd24ba05186f1acd48e7edcdb7abc8a0", + "sha256": "ee39a2e2e75123327c45a831d71e8dd339628ee3abbb4c9b8740f6882da413da", "width": 1600 }, "palette": "ember", @@ -6945,7 +6948,7 @@ "image": { "height": 512, "path": "images/scroll-ember-bottom-narrow-1x.png", - "sha256": "5f270b52ecc33f9ca80f8b398ea4db90b333fe5ac26b8eb0c7ee072aa9543a00", + "sha256": "66f7c06a79c7a5d7c581c12e463d8837b3057eb73dd9847a83063edbc6308b6d", "width": 352 }, "palette": "ember", @@ -6966,7 +6969,7 @@ "image": { "height": 1024, "path": "images/scroll-ember-bottom-narrow-2x.png", - "sha256": "10788e7acc0960ccaad6f2332eed22f458c632b77d089746f2db07f61657f2b5", + "sha256": "be3d88b892d1af91a3ef4bdb5a69ccb1efedffb029cf0e32921511136b044686", "width": 704 }, "palette": "ember", @@ -7006,7 +7009,7 @@ "image": { "height": 512, "path": "images/popover-dark-open-regular-1x.png", - "sha256": "cfb76d095b6273b6bf722eb8e400ad087bbd41c936f70112dd79ae2cf2d7d63a", + "sha256": "255d728774ccde66300a12d10489256cc59d6688b13be47115e92a1ed23c2546", "width": 800 }, "palette": "dark", @@ -7027,7 +7030,7 @@ "image": { "height": 1024, "path": "images/popover-dark-open-regular-2x.png", - "sha256": "8a69557d4500ed71418e782c5d65509030b5c52790403bf1e13887e26b1bfc07", + "sha256": "eefd57dad58a024a33171bd1998c6751a48cbc09e00c14c74d2883010f076bed", "width": 1600 }, "palette": "dark", @@ -7048,7 +7051,7 @@ "image": { "height": 512, "path": "images/popover-dark-open-narrow-1x.png", - "sha256": "a2838685b501beda090019240607c33f4686edc4bbc692b8ade785bdcea3daa5", + "sha256": "43dc37dbe329e7371fa5c4f7bc6053ef50bf87b7cc5554e22436034b65699e5a", "width": 352 }, "palette": "dark", @@ -7069,7 +7072,7 @@ "image": { "height": 1024, "path": "images/popover-dark-open-narrow-2x.png", - "sha256": "1740775084512c88d7dd4b8e8c696b47f703e56bcf0dd40d96a0bc6b7e140e0a", + "sha256": "d09cc361af8f5b6c269708b3166e195b43cb34beb026a5d59d2f82eab347c458", "width": 704 }, "palette": "dark", @@ -7090,7 +7093,7 @@ "image": { "height": 512, "path": "images/popover-dark-closed-regular-1x.png", - "sha256": "bb0f6076ae8d68925a2e25e54e2e4fa4bbda80f293308f96851df0bf7e1eed09", + "sha256": "9f3487a083db0a0bde50ed3da4de4899d36ea1e92bf1bab7f564c7dff096d8a2", "width": 800 }, "palette": "dark", @@ -7111,7 +7114,7 @@ "image": { "height": 1024, "path": "images/popover-dark-closed-regular-2x.png", - "sha256": "a626c83d02ce674d24d3668a1835482b1f5c2d238f81b7f5e77117f0b3f3179d", + "sha256": "cdcd98b377b0c4bf077e6c2be7433831e65e4dfda2621160ae28ac38c4d63c80", "width": 1600 }, "palette": "dark", @@ -7132,7 +7135,7 @@ "image": { "height": 512, "path": "images/popover-dark-closed-narrow-1x.png", - "sha256": "07d93d4216683d026035919a15c563cff37fb04e458611c288bd33205bfb9fe1", + "sha256": "de888b234babd1801a14ab7c78bb93401a324adaeba683ef24f12fbcca11b532", "width": 352 }, "palette": "dark", @@ -7153,7 +7156,7 @@ "image": { "height": 1024, "path": "images/popover-dark-closed-narrow-2x.png", - "sha256": "bb82504edfa77e430acf0c0d970272f9609023c790f490d989115b32b1d66eb1", + "sha256": "c1507e4c7241ff5ed846827003931cbb361036280dd324eee558fc172ecd14fd", "width": 704 }, "palette": "dark", @@ -7174,7 +7177,7 @@ "image": { "height": 512, "path": "images/popover-light-open-regular-1x.png", - "sha256": "9f5048ca25f35e17934a3ed71a71be76a774e036ebd32415e20a004d14b744b6", + "sha256": "e698d51ef314e04d9dfabbe35d11801170bfe2466759f87cde5c4c74812ee223", "width": 800 }, "palette": "light", @@ -7195,7 +7198,7 @@ "image": { "height": 1024, "path": "images/popover-light-open-regular-2x.png", - "sha256": "a43be2547cd60effee7987cf211e43f0400861a9ee7d3851a525f1b808b24d20", + "sha256": "fb063aa68b3253e24f773dca4a76302555eb05b9dfc983bf7ec84dad39091aba", "width": 1600 }, "palette": "light", @@ -7216,7 +7219,7 @@ "image": { "height": 512, "path": "images/popover-light-open-narrow-1x.png", - "sha256": "7aea70b2a5928a7aa1ca14a8503ce468b076ad5211a66f3ea8073a35e9295de3", + "sha256": "18a8135b98920bad8904196330e86c885f5ef86994604feeebf2797b3d7b8e24", "width": 352 }, "palette": "light", @@ -7237,7 +7240,7 @@ "image": { "height": 1024, "path": "images/popover-light-open-narrow-2x.png", - "sha256": "e5cbdfd7f79185b0f858fb485e32c03401310601d4c9a4cbe2798b6bdc16d30e", + "sha256": "c7aab64667025b155c6f938b5f9e44feb25659acb02fd58c009a235257333bdd", "width": 704 }, "palette": "light", @@ -7258,7 +7261,7 @@ "image": { "height": 512, "path": "images/popover-light-closed-regular-1x.png", - "sha256": "f589150dcaf053fb2cf0fefe6a602e7729709f3d757c914cb9b92b273c066538", + "sha256": "1fd30b85d4cc2faf78cba924f75af60bfd4cce8dd055b9a9605da8b8f3155d19", "width": 800 }, "palette": "light", @@ -7279,7 +7282,7 @@ "image": { "height": 1024, "path": "images/popover-light-closed-regular-2x.png", - "sha256": "72e1cb777ac38b1c840a40de1ba3a80ba48b55656f887672e8e83d498576fc7e", + "sha256": "1aff834548d967fcc96f4d524312b4575534add4b74d24bb0bb2aa1277250a02", "width": 1600 }, "palette": "light", @@ -7300,7 +7303,7 @@ "image": { "height": 512, "path": "images/popover-light-closed-narrow-1x.png", - "sha256": "b4978f009e3003f931ccba30ffc1cbe46a86b4edfb96f2d0edc388fb2658baeb", + "sha256": "db247ef0fb3e44559c5767b165ca674b929b772a0c4c8eb15f11b1ece1c70a27", "width": 352 }, "palette": "light", @@ -7321,7 +7324,7 @@ "image": { "height": 1024, "path": "images/popover-light-closed-narrow-2x.png", - "sha256": "360b21c8c742986806f334f049b75288f66d22399da7de1c5a5c02ee47e47a68", + "sha256": "236a86b6aa10b967c0c838e3d4df31e46fd4957ca0e13d07ac2747e87e5d7d45", "width": 704 }, "palette": "light", @@ -7342,7 +7345,7 @@ "image": { "height": 512, "path": "images/popover-ocean-open-regular-1x.png", - "sha256": "efab018a6cab05c3dade3925e5b4efbb57631ca76007925de7fa3ca7f7512750", + "sha256": "18d9969017d5375c132f03e76cc1a21ed72307aa296605fa8dd233f0884e23e1", "width": 800 }, "palette": "ocean", @@ -7363,7 +7366,7 @@ "image": { "height": 1024, "path": "images/popover-ocean-open-regular-2x.png", - "sha256": "bed95856db4302a634ddf2b9925e0e9e4643014610feb83525f4c60e5bc4d070", + "sha256": "c77f987a739d63366a9e871343b58cad77e9bf687df1121d331fa7312fcbf950", "width": 1600 }, "palette": "ocean", @@ -7384,7 +7387,7 @@ "image": { "height": 512, "path": "images/popover-ocean-open-narrow-1x.png", - "sha256": "36574c97997e38170e177164a75f8fea826842081bfc025cd3a0ef16a5b79d33", + "sha256": "de21bcd42503024bffc8356482a992f912de9869d141b69930aa86f26357218b", "width": 352 }, "palette": "ocean", @@ -7405,7 +7408,7 @@ "image": { "height": 1024, "path": "images/popover-ocean-open-narrow-2x.png", - "sha256": "c9cf6031f1c93d5fc310090b6935461df280e0619639b61655a1c357122a8912", + "sha256": "7db352ed4565ffb8cd3a9305d674ed4cc41f6844de832423b598bcb1dc9e3e84", "width": 704 }, "palette": "ocean", @@ -7426,7 +7429,7 @@ "image": { "height": 512, "path": "images/popover-ocean-closed-regular-1x.png", - "sha256": "3e561ea96c038ede3db548053870f4c7073ce2eaef49b650cda60e79a111b973", + "sha256": "b65460385816a85c4d98fafe0a8c791bc75e096a9c88f91f11267013d5de5a86", "width": 800 }, "palette": "ocean", @@ -7447,7 +7450,7 @@ "image": { "height": 1024, "path": "images/popover-ocean-closed-regular-2x.png", - "sha256": "864df3f035a78d16d156e01a4bfb15c17b1611846cf0d2c3cda71362ca6122e1", + "sha256": "3af1d5313d9814c5cda932d33199a20b3a8f0a3b8088190088053b6b0ec3a73c", "width": 1600 }, "palette": "ocean", @@ -7468,7 +7471,7 @@ "image": { "height": 512, "path": "images/popover-ocean-closed-narrow-1x.png", - "sha256": "05bd37651b592866e02eb394b34fd12d35acf65097ad36c23488db0d00d1a234", + "sha256": "72964e2e4bc0aa6d398f949836df1ed02f124bcaa2764a65016261d428e4933d", "width": 352 }, "palette": "ocean", @@ -7489,7 +7492,7 @@ "image": { "height": 1024, "path": "images/popover-ocean-closed-narrow-2x.png", - "sha256": "9da465ba27d67481900c4956ec07b7729cc4c53e9e351980802fa2b112f393be", + "sha256": "f2dc39921dc3a27ca3946c6e98ffa049b48d288322b71a20689f467bff623176", "width": 704 }, "palette": "ocean", @@ -7510,7 +7513,7 @@ "image": { "height": 512, "path": "images/popover-forest-open-regular-1x.png", - "sha256": "22827dc1494950e1041815fc9f9f02fe55dfdab0072a66687a50310416105df4", + "sha256": "b89f89cb9480061cc6ead25c12aa10725752515bdbd3ed438b75adc42b74892f", "width": 800 }, "palette": "forest", @@ -7531,7 +7534,7 @@ "image": { "height": 1024, "path": "images/popover-forest-open-regular-2x.png", - "sha256": "12eead55d031f147f3e9accabfe30e928889bc2f71e07668d9edf504757697de", + "sha256": "d9eeb3462499b76d1323a97195e9c699ebec6858f078cd37e2447036b636f0eb", "width": 1600 }, "palette": "forest", @@ -7552,7 +7555,7 @@ "image": { "height": 512, "path": "images/popover-forest-open-narrow-1x.png", - "sha256": "da56cb0f5688c3e713dc7ec07e2fc0597d4bd36edc5fdd5f0e417b38bfba38c7", + "sha256": "9e75b416108a1cb383b64fb16c3f9803fca2a790f41c5caca296f1f45f9914f2", "width": 352 }, "palette": "forest", @@ -7573,7 +7576,7 @@ "image": { "height": 1024, "path": "images/popover-forest-open-narrow-2x.png", - "sha256": "6eac95d4dda1be4f91eec14f86284fe773f23feeeb5ddff71c9776159c61dc2b", + "sha256": "6812f0d48231fbf3a74d9e1095129cac1d3ed618815df5e569f2e33e2b468682", "width": 704 }, "palette": "forest", @@ -7594,7 +7597,7 @@ "image": { "height": 512, "path": "images/popover-forest-closed-regular-1x.png", - "sha256": "4dc80e34893deb7cd6cfcce889e2f46711c513ad5bf90c46fac5028f1579dc3d", + "sha256": "3e3337df69bbe65baeaf6a9b3a3462f6206c44597ba9e99f5a1822fa53c84f9c", "width": 800 }, "palette": "forest", @@ -7615,7 +7618,7 @@ "image": { "height": 1024, "path": "images/popover-forest-closed-regular-2x.png", - "sha256": "fe18529b895f91eb452948bc151a2e13de91dfc11fb14ed17e47e0c846bac502", + "sha256": "cab6c822d3679495fb7881a0be506b49fbd1455698c103e1afe5be959d76e77e", "width": 1600 }, "palette": "forest", @@ -7636,7 +7639,7 @@ "image": { "height": 512, "path": "images/popover-forest-closed-narrow-1x.png", - "sha256": "2176a9fc297307d8dc430b3a83823cc43fbecf2996121d594b3e3c8929fed570", + "sha256": "35b48761aa4a6b4c0f911a9dba4ae3a48856652a2ad6e520712dc4b0e52fb6ec", "width": 352 }, "palette": "forest", @@ -7657,7 +7660,7 @@ "image": { "height": 1024, "path": "images/popover-forest-closed-narrow-2x.png", - "sha256": "3c53c9dc29596216507c1fea2d13a5fffb162b498af7555c96bc498081b8e9dd", + "sha256": "2e091a1be3e6ab61c95fbc55ab80be5adab16ba5f99c45fb7b2c06705c7f70aa", "width": 704 }, "palette": "forest", @@ -7678,7 +7681,7 @@ "image": { "height": 512, "path": "images/popover-ember-open-regular-1x.png", - "sha256": "de3187f90d58caec3d705abe265f7bb69200a555c94e6bce14677d05589e2dce", + "sha256": "0978cf5eae31abc69413bdd94f5fc39251bca990a1efd9294125fb3ee340db82", "width": 800 }, "palette": "ember", @@ -7699,7 +7702,7 @@ "image": { "height": 1024, "path": "images/popover-ember-open-regular-2x.png", - "sha256": "460308c9b820b24365d90a7c466d52ff0deee88556bbdad13919d190a7dfe9a4", + "sha256": "1c2f015248f907e225750e1190193244a25b1b89ab0b1114028ead5f7a9d8430", "width": 1600 }, "palette": "ember", @@ -7720,7 +7723,7 @@ "image": { "height": 512, "path": "images/popover-ember-open-narrow-1x.png", - "sha256": "3ccc8ca45f4a19d76f6f0951d2fd9816e048e72ad3d9bef4a861884216d773e9", + "sha256": "9300d500cf92e4d849cd652c4cbbcc4e45d715e21ab0c4505ea4da1991e1352e", "width": 352 }, "palette": "ember", @@ -7741,7 +7744,7 @@ "image": { "height": 1024, "path": "images/popover-ember-open-narrow-2x.png", - "sha256": "2055424c9e23d2d2c44bb47901d83b6640d42ab1f9892fb0e14ba51b26df00db", + "sha256": "f3b9c2b0497c57d71833ff4a4e46d03bf4bfabacce86df8816e2733274a566c2", "width": 704 }, "palette": "ember", @@ -7762,7 +7765,7 @@ "image": { "height": 512, "path": "images/popover-ember-closed-regular-1x.png", - "sha256": "806eb6e970055fb27685b70427abb933f0b02a586a3feecfc148e4c76306fa72", + "sha256": "73d59c1f89827ec7c0a0c1a33d5da614ad1715cc1692bb0eac74cf5e1ac4055e", "width": 800 }, "palette": "ember", @@ -7783,7 +7786,7 @@ "image": { "height": 1024, "path": "images/popover-ember-closed-regular-2x.png", - "sha256": "d2b455adfca9fc732e106f7a2507f6db454ce43080513d0328322a29af7c4703", + "sha256": "2d3d04710c3db321487410f61978e22757ea21c658304745ed923c93057de468", "width": 1600 }, "palette": "ember", @@ -7804,7 +7807,7 @@ "image": { "height": 512, "path": "images/popover-ember-closed-narrow-1x.png", - "sha256": "fb79ff9c456a84dffe52fc3f2496926dc360b5abce022daf5d5a3b863cd6eb9a", + "sha256": "4dd3d3fb5a0b98506e56a5563b7967a1149b3d53f96ae81e98e038699cf285eb", "width": 352 }, "palette": "ember", @@ -7825,7 +7828,7 @@ "image": { "height": 1024, "path": "images/popover-ember-closed-narrow-2x.png", - "sha256": "b5a02a7daa1cd00104165122c79b8ecc959abacbb157e5d379ec9d3cd94a9d11", + "sha256": "36e3a9c10a883ba09308f7af6b768e45b099d9752d5af771ca7cd9eb71890d84", "width": 704 }, "palette": "ember", @@ -7865,7 +7868,7 @@ "image": { "height": 512, "path": "images/menu-dark-populated-regular-1x.png", - "sha256": "1ab6f51839963d5ee24a7d10f30b2007dbdaae78d164a39381cf4a0e9cfa7c35", + "sha256": "0848f130cd5f8a5836181f9d1a253c3dc5b8f6a813081451878c1cad9816efb7", "width": 800 }, "palette": "dark", @@ -7886,7 +7889,7 @@ "image": { "height": 1024, "path": "images/menu-dark-populated-regular-2x.png", - "sha256": "41d18faf40f61f73687f1939c24b3e183e18f8e3b988712e6c9d793146862dab", + "sha256": "8c5730b200d7d146ed170541e99ceef033d39c4e0f1fceb1fa15c22107acb823", "width": 1600 }, "palette": "dark", @@ -7907,7 +7910,7 @@ "image": { "height": 512, "path": "images/menu-dark-populated-narrow-1x.png", - "sha256": "4ac98f74803dff488cf2fd738b4c1388b2d72c62cc3b2a690449d1a5a23be94a", + "sha256": "4aba8d185d657dd8b46d247afb738013e402660a5e40bb5598cc6224c20e058d", "width": 352 }, "palette": "dark", @@ -7928,7 +7931,7 @@ "image": { "height": 1024, "path": "images/menu-dark-populated-narrow-2x.png", - "sha256": "56a44c0ccfb322802ed915e1889441856bb27cb2d31b24363d129ea336cc1f71", + "sha256": "ab5fd918edfe0fda671c3ea5a1012fb61d13def32bae82451e3cf04725095714", "width": 704 }, "palette": "dark", @@ -7949,7 +7952,7 @@ "image": { "height": 512, "path": "images/menu-dark-empty-regular-1x.png", - "sha256": "117773256d4a6ddefdad33464af3f2ee8c7b06f5019bf79775670a5f70191108", + "sha256": "e647bd0cbd141933871f3347974499a9915a29c14aea1451513d98f70bc27a51", "width": 800 }, "palette": "dark", @@ -7970,7 +7973,7 @@ "image": { "height": 1024, "path": "images/menu-dark-empty-regular-2x.png", - "sha256": "748b25680caa498a722a6ec147c5346a3774f71f1ea3660788014d4732be4c69", + "sha256": "41348d02121cdc5b71fea6361ab81f2117d697b1d445ffd3a66597ff1607d5ba", "width": 1600 }, "palette": "dark", @@ -7991,7 +7994,7 @@ "image": { "height": 512, "path": "images/menu-dark-empty-narrow-1x.png", - "sha256": "afd19369e4617af6533e058f5fd702b27cacf941302e2919a5445e1abafa6f75", + "sha256": "bcbe12f738805c84f0a778f42b9f57b3b7d3ce5995e94031195152733ccb92e5", "width": 352 }, "palette": "dark", @@ -8012,7 +8015,7 @@ "image": { "height": 1024, "path": "images/menu-dark-empty-narrow-2x.png", - "sha256": "9299e91d31f40a9b2fb6c710f6efcdb57e8f4d0d7a704f18af76b2422fc5e164", + "sha256": "203c10a124a0a0a6817a6322cea40e594e5846c83abf6ff83f52e268cbaa3a40", "width": 704 }, "palette": "dark", @@ -8033,7 +8036,7 @@ "image": { "height": 512, "path": "images/menu-dark-disabled-regular-1x.png", - "sha256": "7587fc4ece9340d0d24b10cf683503c10fb1bab4a500d324c443f67fad1e9b4e", + "sha256": "f3d266cb1995cc4c68b7661f008f75158429887a0878f3d2f09a7836112c7ed1", "width": 800 }, "palette": "dark", @@ -8054,7 +8057,7 @@ "image": { "height": 1024, "path": "images/menu-dark-disabled-regular-2x.png", - "sha256": "9232a81ec7cf148ae2faff007f418f605f73e420bd79711141266ecccb80b38d", + "sha256": "57c95e07be0740cd479fe1da7013738828fef8169cf1a904ac17ae5e6f2aa7b9", "width": 1600 }, "palette": "dark", @@ -8075,7 +8078,7 @@ "image": { "height": 512, "path": "images/menu-dark-disabled-narrow-1x.png", - "sha256": "c0c665a6fb8e2d2f5bcb6843822435f43c55e4dc4473157c6b4cdd43c932c867", + "sha256": "979cb0be0cce53719f62f74b4eda1ff495927c6d3aa7b1b5d5d5e8d1dafb838c", "width": 352 }, "palette": "dark", @@ -8096,7 +8099,7 @@ "image": { "height": 1024, "path": "images/menu-dark-disabled-narrow-2x.png", - "sha256": "9e7e484b696c224432c02813c68cee8d5fe838b76166c87e28ab07295c5c566d", + "sha256": "d90c5206475c444ff8f643ef25823fbc9183394f03b888f0119e3de81963a7a8", "width": 704 }, "palette": "dark", @@ -8117,7 +8120,7 @@ "image": { "height": 512, "path": "images/menu-light-populated-regular-1x.png", - "sha256": "0c99557b978cf50de70bd19bf6a7ad5eb7ef93c46cca21a050da4a4b12611850", + "sha256": "52ea9f7cf8cc498fdfd5fc60717a2f304839a2d8570a0efd5ca135256af084b7", "width": 800 }, "palette": "light", @@ -8138,7 +8141,7 @@ "image": { "height": 1024, "path": "images/menu-light-populated-regular-2x.png", - "sha256": "9f849b769467c9a94c57b7c6198916a0c6e55c92560eb52e55c7bcb31349e2b4", + "sha256": "d5d36f42d2075b17e29d7f8b390d9361f7b5009b55dc775ecc869c3a04000f3b", "width": 1600 }, "palette": "light", @@ -8159,7 +8162,7 @@ "image": { "height": 512, "path": "images/menu-light-populated-narrow-1x.png", - "sha256": "8263800f63c90cecb86dbe2d7f0e8db8d19dc1eb8d54d078068e3dda53320d49", + "sha256": "bacd4f67655d97aa8961878334af45a2e8ed3fa7e579818395966869a9d969fd", "width": 352 }, "palette": "light", @@ -8180,7 +8183,7 @@ "image": { "height": 1024, "path": "images/menu-light-populated-narrow-2x.png", - "sha256": "dedadaef6b23135968f85690a82b98fec69e67e54c1c6bde4d3dd53bc33c7255", + "sha256": "505040399aa4257fe7d07980e002adb151984c2994dc4dbaf7e14dd94fde4821", "width": 704 }, "palette": "light", @@ -8201,7 +8204,7 @@ "image": { "height": 512, "path": "images/menu-light-empty-regular-1x.png", - "sha256": "6f54463257fe1a1d091a0293f170db54b433057ab8d67a8f099d35d3bc72683e", + "sha256": "09d443338cf3f1b092f0ff99114695d63c72c7fa669b4dd056bd2cd572eecd46", "width": 800 }, "palette": "light", @@ -8222,7 +8225,7 @@ "image": { "height": 1024, "path": "images/menu-light-empty-regular-2x.png", - "sha256": "4c574e93b6a0f9bf56ef8d702056a569cfcb8f121f3766b8295aaba1388a5d52", + "sha256": "b15f111f10054a18d840c68362d43bb6666aad21116b9349c3f34cc3e3455307", "width": 1600 }, "palette": "light", @@ -8243,7 +8246,7 @@ "image": { "height": 512, "path": "images/menu-light-empty-narrow-1x.png", - "sha256": "8f79c7b0f5b67627763dabc85c6dd8694ae2d72bcd3219cb0b20f411a492988f", + "sha256": "b9ec7b24a4477e040481ffd3398a976e51f280d843dcb24c8b2ac7922262333b", "width": 352 }, "palette": "light", @@ -8264,7 +8267,7 @@ "image": { "height": 1024, "path": "images/menu-light-empty-narrow-2x.png", - "sha256": "4b9a2a9f991226e456724064c48361b9be20c1f5e0369261b6ab40d9765fd4a2", + "sha256": "086cdd5ae19191e3e5a52a65901292aaedc44444378cf394c223dbc9077edbc2", "width": 704 }, "palette": "light", @@ -8285,7 +8288,7 @@ "image": { "height": 512, "path": "images/menu-light-disabled-regular-1x.png", - "sha256": "b9fe4d7dcd0a6d8f1212cbde85066cace8d4f2052975efcdb67f43b510136604", + "sha256": "106b6c5840a9bcc1d24d79ed0c55eeada7a8862eb707b137c0f12a95c1374ed8", "width": 800 }, "palette": "light", @@ -8306,7 +8309,7 @@ "image": { "height": 1024, "path": "images/menu-light-disabled-regular-2x.png", - "sha256": "e7583955f1aacd9c409d694a81eb182651492d97165fafeb4d598d4621a881b4", + "sha256": "0b85084035e9754e5c6f756a0907dff1242c6039286778ba521a3c70a0521d6e", "width": 1600 }, "palette": "light", @@ -8327,7 +8330,7 @@ "image": { "height": 512, "path": "images/menu-light-disabled-narrow-1x.png", - "sha256": "3a26e402b0577fcc019d089786026d57ca908696aae9445bb10e6da296fa2da4", + "sha256": "8799b16b37ff25a64047e254fc2e11d8a6e0ab06e26230d34368b5616db32842", "width": 352 }, "palette": "light", @@ -8348,7 +8351,7 @@ "image": { "height": 1024, "path": "images/menu-light-disabled-narrow-2x.png", - "sha256": "ccb558adfb8503a92663da2f0e651dbf89905f26bd9cb38f9e523949b5d11413", + "sha256": "e0b5c89429fc83cb937e31bea83a11fd3520c7062f2957a9cb39ff8f3f6a6811", "width": 704 }, "palette": "light", @@ -8369,7 +8372,7 @@ "image": { "height": 512, "path": "images/menu-ocean-populated-regular-1x.png", - "sha256": "239693f41665ec78820050ba9b2c193ab8abe4500feab908a8b6bf214fbc19e8", + "sha256": "971598fb0c078c233277440e51ac429aa6ffa1c3eb6025eba0c04b22ac53ed02", "width": 800 }, "palette": "ocean", @@ -8390,7 +8393,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-populated-regular-2x.png", - "sha256": "d79da46b86af0ce159e621dc9c5e9c98f1af799b5548f5be00571e6423911ec0", + "sha256": "deb02b2d5d60d51a4cc9dce5d8bdf305a18bb4602f5563fab1300f9a75b8ebcc", "width": 1600 }, "palette": "ocean", @@ -8411,7 +8414,7 @@ "image": { "height": 512, "path": "images/menu-ocean-populated-narrow-1x.png", - "sha256": "542e15ff8b794a54cbbe41b8ccb0c24e1614fe8fbbdaab7717a556355dd0588f", + "sha256": "5a7cde03ba2b4fa7fa0e5a56b251ef5511f1f50c1326f96b2d8f8cd9236ce25b", "width": 352 }, "palette": "ocean", @@ -8432,7 +8435,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-populated-narrow-2x.png", - "sha256": "76fca4da48d8116e144993225f0901baef6970369b29ffad5c1397a9f0bcd12f", + "sha256": "9be775c585cd2ba07664ffe85eb153f45ba438aa8e7ba72f9f89f470470e55dc", "width": 704 }, "palette": "ocean", @@ -8453,7 +8456,7 @@ "image": { "height": 512, "path": "images/menu-ocean-empty-regular-1x.png", - "sha256": "17f04ffe2f604af7d8c66bfb68807719b8db69b7b5bc154431935bd7b872bf75", + "sha256": "45fc74199d31a812b4779a2af7ac5a39b5abecebab0300605837b484bf41c5aa", "width": 800 }, "palette": "ocean", @@ -8474,7 +8477,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-empty-regular-2x.png", - "sha256": "ef76a1118e4392ba82b9dac81af6332eee566d0e4385b7ccc1c011c8bfc399eb", + "sha256": "90bb345bf5ada74d5d3328d8c6a68131bede5228340aab81a5bd5a1dfd3aa2d3", "width": 1600 }, "palette": "ocean", @@ -8495,7 +8498,7 @@ "image": { "height": 512, "path": "images/menu-ocean-empty-narrow-1x.png", - "sha256": "5cfb577458c9aefe9828c9552415e3975254f18927b1a3c58ee94425cdc71cf3", + "sha256": "4449343f419541dbd413a75ff161c7496ccb393451465950facf1916b153ab2b", "width": 352 }, "palette": "ocean", @@ -8516,7 +8519,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-empty-narrow-2x.png", - "sha256": "5947b1e432d07105e76dba97896a1661de805ef318fe789baf504dba6ff433dd", + "sha256": "de3eae53da12f2f927ed7f5dc98d724d3bb352a31fe8f841b30399288670785e", "width": 704 }, "palette": "ocean", @@ -8537,7 +8540,7 @@ "image": { "height": 512, "path": "images/menu-ocean-disabled-regular-1x.png", - "sha256": "f109753e9a23e9fe668b8a0b9bbf22bc3ddfc38be0caf962cda76bf82df6a8b8", + "sha256": "9cecac2df43fcd3db4830467de7ae3c9c992b50b202563decc5fa52f7d82270e", "width": 800 }, "palette": "ocean", @@ -8558,7 +8561,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-disabled-regular-2x.png", - "sha256": "ef443d5af70bfced5582014027728bb2c9889a142d0a04b797a9f2f44537e894", + "sha256": "55fb657b5d576a31d7de900c080d99860cac1d7c88cb90fd3aa4a85a19f620ae", "width": 1600 }, "palette": "ocean", @@ -8579,7 +8582,7 @@ "image": { "height": 512, "path": "images/menu-ocean-disabled-narrow-1x.png", - "sha256": "7247cb36356a2d80bbbc9e4e73755d0aa9623d9981945e382947fab62974ee6f", + "sha256": "9eda2a7f5f66e4e42f7a589994fcea1495f6d195947dc103d34443062eacab8b", "width": 352 }, "palette": "ocean", @@ -8600,7 +8603,7 @@ "image": { "height": 1024, "path": "images/menu-ocean-disabled-narrow-2x.png", - "sha256": "7b7e05434db1c213a7a7fc05bf02f21392d4a2086d9f06fb3da3b478d5d395f1", + "sha256": "362f21467410d3ae3639355caedfd5ddea63537d5af59bad1730cab691ad88f6", "width": 704 }, "palette": "ocean", @@ -8621,7 +8624,7 @@ "image": { "height": 512, "path": "images/menu-forest-populated-regular-1x.png", - "sha256": "6400ba4143ab74aa3a574935a1f6b75ea7ab126e788fa3ae77952208d778667d", + "sha256": "96401beca1137a1e074bf55c6086e8972e885e6df6970f2e947a78be6cfba162", "width": 800 }, "palette": "forest", @@ -8642,7 +8645,7 @@ "image": { "height": 1024, "path": "images/menu-forest-populated-regular-2x.png", - "sha256": "f01ec0bfa0b3dc1b6c7f850ed1f8bc560e20fe8a0e1b08195b54183469dc864b", + "sha256": "8236833c97a46b921ba6d72844b4dab847f443cb9e40338b6c812142c700ca20", "width": 1600 }, "palette": "forest", @@ -8663,7 +8666,7 @@ "image": { "height": 512, "path": "images/menu-forest-populated-narrow-1x.png", - "sha256": "7bc236bcb5b1011e69e0be839c8736964cb11c02ed12927cc3ef0c5aae989dcc", + "sha256": "b4348423302891951867c72d2e2f9666f9f425c08b6684559a51da71c67a19db", "width": 352 }, "palette": "forest", @@ -8684,7 +8687,7 @@ "image": { "height": 1024, "path": "images/menu-forest-populated-narrow-2x.png", - "sha256": "50dafc7b7f6133456b6818f8467233713975dc5872a33273603dae3f676d1e1d", + "sha256": "2e4bd971223ac7506266c61ce5b367b5632d653958fa937eb546c25980528e01", "width": 704 }, "palette": "forest", @@ -8705,7 +8708,7 @@ "image": { "height": 512, "path": "images/menu-forest-empty-regular-1x.png", - "sha256": "9e1f7f166dfb27746ae7e831f5f62199694de22bf6bb12a93e6a8d3ee82d005c", + "sha256": "86f97cc3a0a5b168600104337f2d56b87cc689252fce11ada38f24955650dd3b", "width": 800 }, "palette": "forest", @@ -8726,7 +8729,7 @@ "image": { "height": 1024, "path": "images/menu-forest-empty-regular-2x.png", - "sha256": "a35b65069cf15b116b2fb440c8104da0ecfda6ecc7cd7a465dccc923fb53593a", + "sha256": "28563d057f26af59c7d01c87947d2f39ede00da559d6ed47c8fa1b10cb99c359", "width": 1600 }, "palette": "forest", @@ -8747,7 +8750,7 @@ "image": { "height": 512, "path": "images/menu-forest-empty-narrow-1x.png", - "sha256": "48f578a874ffb0ef492b7852680350e92b1dcce96400f7499b872a2a385c9daf", + "sha256": "0c79392c9ae35d592365c08d92a5ef22e376b4ac8a3b21310aa37c5f8f7bfaa9", "width": 352 }, "palette": "forest", @@ -8768,7 +8771,7 @@ "image": { "height": 1024, "path": "images/menu-forest-empty-narrow-2x.png", - "sha256": "4646182d94250d3af12f952514067b0a19018549521f38d697a06dde3deab755", + "sha256": "95689ff7515e8d16f0ccf17097c6d3b79dfeb58b11ae1f73cf2b8c32af3d3c57", "width": 704 }, "palette": "forest", @@ -8789,7 +8792,7 @@ "image": { "height": 512, "path": "images/menu-forest-disabled-regular-1x.png", - "sha256": "314d0257646edd9ba6b8b0e079f4a55d7fa2ce5ee044d70e8142237947385943", + "sha256": "f9b8717b73d90b97c6a6cd2564f777cc9e71b7f07ead65e24b7cacfdf0a5db4f", "width": 800 }, "palette": "forest", @@ -8810,7 +8813,7 @@ "image": { "height": 1024, "path": "images/menu-forest-disabled-regular-2x.png", - "sha256": "f6c7a25aa902ee806a36160de2b45c091933ef7c190b3a91912bb4f82daef5ab", + "sha256": "a20efa20cbff96f35fbf48989da2e458768a6b55a5905a09cd72c46992c50fc2", "width": 1600 }, "palette": "forest", @@ -8831,7 +8834,7 @@ "image": { "height": 512, "path": "images/menu-forest-disabled-narrow-1x.png", - "sha256": "7a5f44b978c36b12af9b82354cbeb45e4ac58557705b5d47887fdc100831f5dc", + "sha256": "e851a20ad56d1b5e97833fec343fe24178fd213ffa54a262acb3f3273e22bb5b", "width": 352 }, "palette": "forest", @@ -8852,7 +8855,7 @@ "image": { "height": 1024, "path": "images/menu-forest-disabled-narrow-2x.png", - "sha256": "8f74caab8da471b3f8b62279e414c334e4366a8770033f31fc3c45a1728490fe", + "sha256": "36053c3ba7d2fb517d890e2c2b227d95406ac5a6e5ccc4c7de6debc4e23b97a4", "width": 704 }, "palette": "forest", @@ -8873,7 +8876,7 @@ "image": { "height": 512, "path": "images/menu-ember-populated-regular-1x.png", - "sha256": "bc2e5901c522ad2843c93ff612eef577b2c260f671fc27a3bf225f2c1b4f9f9c", + "sha256": "159faf48c50bdac06363d3f74b6c82de3eee1cd98e55c624f49fb42f7ad2ed10", "width": 800 }, "palette": "ember", @@ -8894,7 +8897,7 @@ "image": { "height": 1024, "path": "images/menu-ember-populated-regular-2x.png", - "sha256": "0d5ea8c9d9667226aba0ad2a3c7f6e445fd46f1abd3b8a5320282962f308c5b1", + "sha256": "d1f57f86cfb64fcf9b57d60d2dad1b68f8cb3834400ebc0cb5c6090bac87bcba", "width": 1600 }, "palette": "ember", @@ -8915,7 +8918,7 @@ "image": { "height": 512, "path": "images/menu-ember-populated-narrow-1x.png", - "sha256": "f8def6cf63e78fc7eeb69b179673ef32a1eb0ef8bcd36c92a6a6baf56d8541d6", + "sha256": "0946fd6afd0cc40fdbd5ee380623592afce4b618ae5996ade098edd35fc0aadb", "width": 352 }, "palette": "ember", @@ -8936,7 +8939,7 @@ "image": { "height": 1024, "path": "images/menu-ember-populated-narrow-2x.png", - "sha256": "02d782a6a04f63ad5f35cb7db6c8c91db915e27c7f403c2efaa531292e0df964", + "sha256": "5605c0a6a8566d574c33aecfd48e63951b0ff5ebb307bb63970b714b8f973837", "width": 704 }, "palette": "ember", @@ -8957,7 +8960,7 @@ "image": { "height": 512, "path": "images/menu-ember-empty-regular-1x.png", - "sha256": "d2b9f22c55bd60c08bbd2e93f46f833c33b80abdc20d76b268a4a5ea3c651c87", + "sha256": "fc844608ab17dcd3bccdf4a1f30924d0c66405626f58ea9ab024c61068fd43d6", "width": 800 }, "palette": "ember", @@ -8978,7 +8981,7 @@ "image": { "height": 1024, "path": "images/menu-ember-empty-regular-2x.png", - "sha256": "60294bae016438cbe9e7e3aa976857c453ae81f99f8907f4e5aa5c3913062c32", + "sha256": "3cd88ecc325055eac71169fbf1d22a2e3564ee0790026cb0e9e194b91c2d2ee0", "width": 1600 }, "palette": "ember", @@ -8999,7 +9002,7 @@ "image": { "height": 512, "path": "images/menu-ember-empty-narrow-1x.png", - "sha256": "0753f955aad9ce4f654ea466ade1b84418cf1a663a7ad6d4faf92576f2e85de8", + "sha256": "2e0124575021284d973410cde374cd4b8fff2e0307caa22350d858f84881d6ab", "width": 352 }, "palette": "ember", @@ -9020,7 +9023,7 @@ "image": { "height": 1024, "path": "images/menu-ember-empty-narrow-2x.png", - "sha256": "cc5b0e8ae281fc939340cccee372ac59e0d7c2a6b901bcf8a9ef880b078c0f2f", + "sha256": "10262a3471135f1687ca8590065cade459433549e492ad9a162446ba58ddd863", "width": 704 }, "palette": "ember", @@ -9041,7 +9044,7 @@ "image": { "height": 512, "path": "images/menu-ember-disabled-regular-1x.png", - "sha256": "1847cde020426b4e1e0d9685815f4b481c8a05630d4fee27169c443dce762c94", + "sha256": "f795c4ac8aad3c65103b308caadf60743cd2685bb95a4f47540d281d76ed41d9", "width": 800 }, "palette": "ember", @@ -9062,7 +9065,7 @@ "image": { "height": 1024, "path": "images/menu-ember-disabled-regular-2x.png", - "sha256": "4302015b2c2ad3ca00f7d1c9ca8097b12dd835722b75c0eb19b69d37f423b846", + "sha256": "ab2bf0aac37443fdd847c1d6924f754f0f096a6755651dd309e3fc44e7db8464", "width": 1600 }, "palette": "ember", @@ -9083,7 +9086,7 @@ "image": { "height": 512, "path": "images/menu-ember-disabled-narrow-1x.png", - "sha256": "bb54d151f592d74185511d5960438e9902f14dd3471b762a9a88be9c51c08654", + "sha256": "bbaa30659ed2f957b8994a22e5dcab7b6d3677e78b32499a7a6f03976df0d02e", "width": 352 }, "palette": "ember", @@ -9104,7 +9107,7 @@ "image": { "height": 1024, "path": "images/menu-ember-disabled-narrow-2x.png", - "sha256": "4546c35822f03159e855b6afea3fbf120efb9268da6709035cf8132e20685a00", + "sha256": "396b03ba675fd60dc5f1a7dffd0a57c4c09b23ff6682271f7cd57c1ed547e143", "width": 704 }, "palette": "ember", @@ -9144,7 +9147,7 @@ "image": { "height": 512, "path": "images/motion-dark-end-regular-1x.png", - "sha256": "01b30eb4c3e42c53bd7281ddc8a12dddb77124bfb0c299bac00d2507d7dbc607", + "sha256": "cb4947fd83c8240e59b03c2ac6abc6e4dd723f9eaf9c6d178e76337eaddec88c", "width": 800 }, "palette": "dark", @@ -9165,7 +9168,7 @@ "image": { "height": 1024, "path": "images/motion-dark-end-regular-2x.png", - "sha256": "28faa555e2ef26fdac246a14abe756782b528f7ae0afb74c7d98b7e2700be935", + "sha256": "c74479c069792e7209f0f107010966b0b1abe66306467e983496bd45e8911c03", "width": 1600 }, "palette": "dark", @@ -9186,7 +9189,7 @@ "image": { "height": 512, "path": "images/motion-dark-end-narrow-1x.png", - "sha256": "5098fa6a652d46f5a5474c2ec676143922428900e53db414272d172ab02da310", + "sha256": "e436baa03f3e6924a29859e31cc3fdc78f40cb5d4d5c8689542d9857fbead8f3", "width": 352 }, "palette": "dark", @@ -9207,7 +9210,7 @@ "image": { "height": 1024, "path": "images/motion-dark-end-narrow-2x.png", - "sha256": "c55e11b07e744e5f161e72197b3fc9e9f937e34ab9834742b7e62c0f0c1ee54b", + "sha256": "919238685334df495b602fe932610911f79c353c0905c6e5d8f88399cd5687f6", "width": 704 }, "palette": "dark", @@ -9228,7 +9231,7 @@ "image": { "height": 512, "path": "images/motion-dark-start-regular-1x.png", - "sha256": "f1f1ca374243673edf2ee1deed74a153c63e82922e0ddf34204a6782dd26a6a3", + "sha256": "9d5a1aaa02c288ea987d453208d9134aa04688f41fa9e693daf5f59b43e83a84", "width": 800 }, "palette": "dark", @@ -9249,7 +9252,7 @@ "image": { "height": 1024, "path": "images/motion-dark-start-regular-2x.png", - "sha256": "b6ede9b4222b424ea5f1523f60bf8c352df2e9df318d607311116100050ba151", + "sha256": "502290ddb4ed17d407e27a2fd4d07313a44c6882baedfcca0815f949740c9ad8", "width": 1600 }, "palette": "dark", @@ -9270,7 +9273,7 @@ "image": { "height": 512, "path": "images/motion-dark-start-narrow-1x.png", - "sha256": "e49501e97b699709690dfb9df634083b79c896993f50f6a44665a95fd3e7191e", + "sha256": "649c56283c83f547eb9b479491047547b0d6ddb6748acf8d0fac900f58b2707a", "width": 352 }, "palette": "dark", @@ -9291,7 +9294,7 @@ "image": { "height": 1024, "path": "images/motion-dark-start-narrow-2x.png", - "sha256": "c44a7ec4e9886758faa937fcf065cfa7b3c78fd407812fa0d79ed24d882fa168", + "sha256": "cfdab200324c95f253e42f7d48dd813a7ee914463e0b4fc677bb12bb6a1aadeb", "width": 704 }, "palette": "dark", @@ -9312,7 +9315,7 @@ "image": { "height": 512, "path": "images/motion-dark-middle-regular-1x.png", - "sha256": "7b9164767ef2231e65b532e278541d66cbd0c4845a8cadd6d0cb3013fe8564c7", + "sha256": "e65103bec2ba3567a96cfe5c8c4c1e549a8af3dd15877f019e33e40b6841dfa8", "width": 800 }, "palette": "dark", @@ -9333,7 +9336,7 @@ "image": { "height": 1024, "path": "images/motion-dark-middle-regular-2x.png", - "sha256": "b92cddd0c9250abcef0e2dcbc7d74924b7528a6d21356d480b5ff0ea6557bd02", + "sha256": "e91ad86b45bac7fb40f4ff855d3f9bff91964debda31b9392f1e85c9ec37d627", "width": 1600 }, "palette": "dark", @@ -9354,7 +9357,7 @@ "image": { "height": 512, "path": "images/motion-dark-middle-narrow-1x.png", - "sha256": "f62fd62f8cc4406afcc59ffcec6d1738303a21dc00f090c9c92d2c188aa56de0", + "sha256": "44eed2ad5b53d11346945b53e7cca30373cb5d0fda9d94cb930ef6f3757ca32a", "width": 352 }, "palette": "dark", @@ -9375,7 +9378,7 @@ "image": { "height": 1024, "path": "images/motion-dark-middle-narrow-2x.png", - "sha256": "96e3ff2c7ca9db0549992d5ddf5d20eb56b08b0036068c49d980481d6b44e4e5", + "sha256": "030b21c332fe084a47672dbfa3126fe7400dd08e1d63350110536fc1f9e10f72", "width": 704 }, "palette": "dark", @@ -9396,7 +9399,7 @@ "image": { "height": 512, "path": "images/motion-light-end-regular-1x.png", - "sha256": "5f6e376f89243e8f738ae0411a70f83f2ebf0afacaf6f2af0e0702b86958baa5", + "sha256": "a9956f62f9e46dd3ba186a2693c0a6620b370503316dbc4c53cdc36fa91f1173", "width": 800 }, "palette": "light", @@ -9417,7 +9420,7 @@ "image": { "height": 1024, "path": "images/motion-light-end-regular-2x.png", - "sha256": "27578c6c4b1587d52d76c78e07feac72072946da81929cacccdeefb1266b0a64", + "sha256": "21072dc5d3944b7e1235d692998d6bead8a68132a342591404a2b81c0feef622", "width": 1600 }, "palette": "light", @@ -9438,7 +9441,7 @@ "image": { "height": 512, "path": "images/motion-light-end-narrow-1x.png", - "sha256": "36043ee51be9bfde3e313e9d083a8a1dc85c029276797da35c8df8a404f80132", + "sha256": "b074b1a6a715146b0c890b7e5f92b809d839c8c1a03ed5cf359e572c2353f760", "width": 352 }, "palette": "light", @@ -9459,7 +9462,7 @@ "image": { "height": 1024, "path": "images/motion-light-end-narrow-2x.png", - "sha256": "af75c0d7f8db77dd4fe0d14af5a4005227a878e944698e62304e6f6e8252ae29", + "sha256": "0d4cfd04810cdefa265efe0779fd18473bdf843ce2f0f48ad6b37e30300b1598", "width": 704 }, "palette": "light", @@ -9480,7 +9483,7 @@ "image": { "height": 512, "path": "images/motion-light-start-regular-1x.png", - "sha256": "61f247e7bcbd40232af487e0af8b546e8e51091aa9cb41aee2ac0682aea4a340", + "sha256": "0499bf49987f0c89571de9d79caf615e2aee73f30ca86d7ed1a948a96e212292", "width": 800 }, "palette": "light", @@ -9501,7 +9504,7 @@ "image": { "height": 1024, "path": "images/motion-light-start-regular-2x.png", - "sha256": "e8092009a894eda42d2bbf9805b21ac645fa8bf23e372da954cb29191d05965d", + "sha256": "7a570e56f3351692a6c08599a92bf10e295d27b936bbbca414475507b68bf268", "width": 1600 }, "palette": "light", @@ -9522,7 +9525,7 @@ "image": { "height": 512, "path": "images/motion-light-start-narrow-1x.png", - "sha256": "cf1a13248364d78d7c82fa5702fd3ce0cff10561a41b436c445804f87d4b05cb", + "sha256": "40344ca915b5190ecfe951b5fa9397d6a2d338347726000fe06dbdc56d61a766", "width": 352 }, "palette": "light", @@ -9543,7 +9546,7 @@ "image": { "height": 1024, "path": "images/motion-light-start-narrow-2x.png", - "sha256": "42aa30076245418290c63544ae8246ca654cbb8cde8caf5f172f349b5ed504ed", + "sha256": "761b8cbe584d5211b88b182fa558fd7121a9466262d6512c8b2fdf6d4744b74d", "width": 704 }, "palette": "light", @@ -9564,7 +9567,7 @@ "image": { "height": 512, "path": "images/motion-light-middle-regular-1x.png", - "sha256": "b761d7a8598c4041b8214e953ad626e7ca91e0aa5b77f8a589b87aa7308c2c80", + "sha256": "daff49085f39a3a63bae9dd29d0c7b28acbb40aafb93de30d091f04878cb095e", "width": 800 }, "palette": "light", @@ -9585,7 +9588,7 @@ "image": { "height": 1024, "path": "images/motion-light-middle-regular-2x.png", - "sha256": "4b0b2b37ee8678beeddcc71f5a8dd0c70c4ec2769149b8ac977eb1d82f3145cb", + "sha256": "272707e6cff7169ec250225de219247ce9df6e9dff968e58c1b36d6eac7267fd", "width": 1600 }, "palette": "light", @@ -9606,7 +9609,7 @@ "image": { "height": 512, "path": "images/motion-light-middle-narrow-1x.png", - "sha256": "1523d6b118269fba6920924cb49a06308772276ce3655027fb7908ee49d3b0b6", + "sha256": "5139192ba4422cf8e2f1f81f777f191a8023ae5526d7a7f0ae246579a943e4d0", "width": 352 }, "palette": "light", @@ -9627,7 +9630,7 @@ "image": { "height": 1024, "path": "images/motion-light-middle-narrow-2x.png", - "sha256": "a74a15fff7c0d5c941583838abdaee20b59f968eec0d189d6b3301b024508ac5", + "sha256": "86a6e848c5c6cef30340f2027398456e67b53c7065a8fc051dbee97640ebfcef", "width": 704 }, "palette": "light", @@ -9648,7 +9651,7 @@ "image": { "height": 512, "path": "images/motion-ocean-end-regular-1x.png", - "sha256": "2c2493e7086a11523d850bac9772de587d9c0ffbb6147c10a8d3d7430a508d7b", + "sha256": "7d82e64b34cdd5af6246750cb25d4693a74000eac3338e974d678845c760e276", "width": 800 }, "palette": "ocean", @@ -9669,7 +9672,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-end-regular-2x.png", - "sha256": "84a1a9efab649d718386b757b00fdd68b560987f0b308f93d065c99a3eafa5c1", + "sha256": "1e96375e193594721de9c400af9d65074b439ed0b4fc38f278442426a3c23a39", "width": 1600 }, "palette": "ocean", @@ -9690,7 +9693,7 @@ "image": { "height": 512, "path": "images/motion-ocean-end-narrow-1x.png", - "sha256": "886059a5566fa6024fa84f4cc23d900a5a429221710388fdbdc56e9f1bbbeb03", + "sha256": "6725683d25a7dcc1f8306613ec2007b67b613492818900e8c3654e640a7eee42", "width": 352 }, "palette": "ocean", @@ -9711,7 +9714,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-end-narrow-2x.png", - "sha256": "54ae4e03b1972dbde91f9cf2fce3b90a8d531faafe56ab358b6edb1b091d2824", + "sha256": "2d28ea814cbcdbe87ba0bfd571d1bea7868e548e8ee1fd402c53609a60da2146", "width": 704 }, "palette": "ocean", @@ -9732,7 +9735,7 @@ "image": { "height": 512, "path": "images/motion-ocean-start-regular-1x.png", - "sha256": "ea42e80a8622ec430ec29bfb3ad20c3f3351a76baf7f31c7476e58931189edf7", + "sha256": "c14cdbafe6e516e6c327708c3e85e9995f14dcbcac859a31222661612f9982f1", "width": 800 }, "palette": "ocean", @@ -9753,7 +9756,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-start-regular-2x.png", - "sha256": "d6820e70ff028ed31f18fff4229726ff29cb9c0cd436fe8f4fbe989bfe2616fe", + "sha256": "1d6a04a05deec4442c514033bf15cfaac588ce3656854a8ada846b6d15eab7ad", "width": 1600 }, "palette": "ocean", @@ -9774,7 +9777,7 @@ "image": { "height": 512, "path": "images/motion-ocean-start-narrow-1x.png", - "sha256": "4a7d2418eb4900aeb40cefbc0c23d0b784d1f1ac9f263484249d85b9ad0a6be4", + "sha256": "9f4a52f338e0858da0ba6a090fcc83ab06d5516180317b1baa1a1dec36af0f1c", "width": 352 }, "palette": "ocean", @@ -9795,7 +9798,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-start-narrow-2x.png", - "sha256": "f175d6f2271450ac5719882edf8d7023980750046c02233116619ad851b5bb1d", + "sha256": "a9d92e738862239bd3c455bb265751b15bb5e4f6c9120859489677e0391eedfe", "width": 704 }, "palette": "ocean", @@ -9816,7 +9819,7 @@ "image": { "height": 512, "path": "images/motion-ocean-middle-regular-1x.png", - "sha256": "64f8e3d87d2d5914ba9faa40e18eaeb0d38d71f0fd7899ba9bb4f0e1f559327b", + "sha256": "ccb222cd3f4396c633fdfb31b9ac97f237c589e14db68dc4e153e2ddd87fa31d", "width": 800 }, "palette": "ocean", @@ -9837,7 +9840,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-middle-regular-2x.png", - "sha256": "047a7e9b6583fb2735192318d8b7c0720d81848a639f88dcaa20fdf15c702a17", + "sha256": "2cb16e0cdfaff24d65adbc5281f4190c247252b4948d0be1810695bc44600c3d", "width": 1600 }, "palette": "ocean", @@ -9858,7 +9861,7 @@ "image": { "height": 512, "path": "images/motion-ocean-middle-narrow-1x.png", - "sha256": "69ff934c3ae1b2981f9667cc99ff459e1f22f2bd5a4dd8099819b0d72cde8577", + "sha256": "03ec7988730ff7b3efcc97c6e1edb4607c50bcad6dfa754d2ce835b55738bd6f", "width": 352 }, "palette": "ocean", @@ -9879,7 +9882,7 @@ "image": { "height": 1024, "path": "images/motion-ocean-middle-narrow-2x.png", - "sha256": "f3bef16eee1fdb0f61779f45fcf8a172a14a1b94d4d5b8d446778e10c18b0bfd", + "sha256": "89e63725dfe3569f04fefb775f1d8690de79c96955eeae85b0dec3782f053c31", "width": 704 }, "palette": "ocean", @@ -9900,7 +9903,7 @@ "image": { "height": 512, "path": "images/motion-forest-end-regular-1x.png", - "sha256": "c492ca582d103093587bba377feecf8a141f86c5b680ff01382dccbca59bdcb0", + "sha256": "742540968f7c3fb2cb8c778b7fa81a8e97a5c794082e384ce4a7c2512020af22", "width": 800 }, "palette": "forest", @@ -9921,7 +9924,7 @@ "image": { "height": 1024, "path": "images/motion-forest-end-regular-2x.png", - "sha256": "00618b93ee632b72520c9c423fcb6a0c0bb36cffe90b9c666605254ca03bd011", + "sha256": "bebbb91b7f3f92843804e7078ae8100cae97d905957beab5ee03ae1cbcb905b1", "width": 1600 }, "palette": "forest", @@ -9942,7 +9945,7 @@ "image": { "height": 512, "path": "images/motion-forest-end-narrow-1x.png", - "sha256": "f391a75afd6090dbd21ea78e36f1457ef5a2e52e70d0c341088156e2139fe607", + "sha256": "6ed91c38d9dc76466f441ad9f55831be5bbbbaa92f012a5fc2d4223a2d062375", "width": 352 }, "palette": "forest", @@ -9963,7 +9966,7 @@ "image": { "height": 1024, "path": "images/motion-forest-end-narrow-2x.png", - "sha256": "51f75b9c117fe0559f978ece86b281658a2bb9612e9f5353d0eeab6a88341a1a", + "sha256": "8307476ad4d95b74127ea03a64babffd5ba62d2baa6f5c93dfe958714201e1fe", "width": 704 }, "palette": "forest", @@ -9984,7 +9987,7 @@ "image": { "height": 512, "path": "images/motion-forest-start-regular-1x.png", - "sha256": "b3f501caef409656980bb412851cf0d5fbf23d4095dfcc5057bfeff480ebb1b2", + "sha256": "63b22d7adae2e0768b0c5adad298201d1f2f5eaae7826f63694e803b9bf28571", "width": 800 }, "palette": "forest", @@ -10005,7 +10008,7 @@ "image": { "height": 1024, "path": "images/motion-forest-start-regular-2x.png", - "sha256": "5fdb4a302e2fc2743b3c3fb79fef6833b458d157be9f2535567092bee275c805", + "sha256": "8b9a35b9ceccd5924181270a7b34554a3292171d71e4eb065e3270662cffb35a", "width": 1600 }, "palette": "forest", @@ -10026,7 +10029,7 @@ "image": { "height": 512, "path": "images/motion-forest-start-narrow-1x.png", - "sha256": "1cb5a3d22a7a99f5232247f53719e396107f38e6cd3c29b1c6f5cff3af1e283b", + "sha256": "8893b86d2c724a5d1a50ea7af395054f4ae1338d00f86444c230bd1c4c4c43e3", "width": 352 }, "palette": "forest", @@ -10047,7 +10050,7 @@ "image": { "height": 1024, "path": "images/motion-forest-start-narrow-2x.png", - "sha256": "8f9be9e7b2578bf0d5edccd6072419eefc7f479475a39690775c78173b76b37c", + "sha256": "4da14e07f8ecc41eaecd5be0866029bc0fe59e6d9e769879b48682e824deebe3", "width": 704 }, "palette": "forest", @@ -10068,7 +10071,7 @@ "image": { "height": 512, "path": "images/motion-forest-middle-regular-1x.png", - "sha256": "57af3310ccdb9a0d11ea65cdb0c1c551044597acb4f63d72a7cc726cf9e89a14", + "sha256": "fd88273a4ba30ba9c2ecc77173a6ec83cd979b1e8eb72c67d9bd00c760ce6bb5", "width": 800 }, "palette": "forest", @@ -10089,7 +10092,7 @@ "image": { "height": 1024, "path": "images/motion-forest-middle-regular-2x.png", - "sha256": "6809d4cd4bd2194fd9ec69326a0c9e7a438e3b8363f569978d3760105f75d6d6", + "sha256": "465c09c4c4d47fc83aa38a01cbf843237d1e3bacff8372300441590645e4b1c3", "width": 1600 }, "palette": "forest", @@ -10110,7 +10113,7 @@ "image": { "height": 512, "path": "images/motion-forest-middle-narrow-1x.png", - "sha256": "0624af0bac6a99c905a03d8f7568d3e5c360026697dd9c792caa42f0e722a835", + "sha256": "4f138d64abed845725d99f993341220d11324e713b7107802388039da2caca72", "width": 352 }, "palette": "forest", @@ -10131,7 +10134,7 @@ "image": { "height": 1024, "path": "images/motion-forest-middle-narrow-2x.png", - "sha256": "7b1e1436cbb69da6299a5a4d574c6c5468ea13e32c7613527c0637077b9f9ca6", + "sha256": "1dc0e88f1fa29093f6e7b3d84bce6c6394d4970af66186a840e366e7d2031fdd", "width": 704 }, "palette": "forest", @@ -10152,7 +10155,7 @@ "image": { "height": 512, "path": "images/motion-ember-end-regular-1x.png", - "sha256": "bcf8b2facee0b93b9dc6808abe72c09489e706bf94c3365138a933cc20eda8a8", + "sha256": "b7a50433a26e60bf70e95dca4d9256be5060796cbaf462282f953d120407f669", "width": 800 }, "palette": "ember", @@ -10173,7 +10176,7 @@ "image": { "height": 1024, "path": "images/motion-ember-end-regular-2x.png", - "sha256": "9747ffe97465ab54eb3dcfa533192deb9310874dd4e3bdb8c5728b93e5557aa8", + "sha256": "119487f1c44babb95bb2015e7ece84ba4e979f91274b8196fe741add3925da2e", "width": 1600 }, "palette": "ember", @@ -10194,7 +10197,7 @@ "image": { "height": 512, "path": "images/motion-ember-end-narrow-1x.png", - "sha256": "78970ccab2d97c0c23c5c146be9063b3ea96de29f1a2a94dcc1b1a0aab9467fe", + "sha256": "b126eac53986347fea2e2db21153e072e9c23b5aa6679914ec61f7f7d2b5925c", "width": 352 }, "palette": "ember", @@ -10215,7 +10218,7 @@ "image": { "height": 1024, "path": "images/motion-ember-end-narrow-2x.png", - "sha256": "34345cf10fa895b9cbeb7dd57f6a0322c8c7d9a1f11cf47ba4a33dd2cadb23a7", + "sha256": "d232bdfc928f80a76c59aacdae39db7a8ef2811acc1e47394d3b5cffabf826a7", "width": 704 }, "palette": "ember", @@ -10236,7 +10239,7 @@ "image": { "height": 512, "path": "images/motion-ember-start-regular-1x.png", - "sha256": "e7667a5f068a503c02b325c914f3c1d929d821f2f903d8c38b59b39741984f1d", + "sha256": "89a7ad8a15459c42c3a90aa78ab89d335f79e6681eca50bdb446e7e14031ae31", "width": 800 }, "palette": "ember", @@ -10257,7 +10260,7 @@ "image": { "height": 1024, "path": "images/motion-ember-start-regular-2x.png", - "sha256": "e5f684e000c4738a80fc8719b9e531269257366ff480f3ddfbb3465a2a25fe79", + "sha256": "d0f640b9d7b7d2abf5795acdd4e543e19e50cdc85dff8d49debde013e4edd1a4", "width": 1600 }, "palette": "ember", @@ -10278,7 +10281,7 @@ "image": { "height": 512, "path": "images/motion-ember-start-narrow-1x.png", - "sha256": "416eb9da552b552d594d6fba8dd950e37b02111dc689b096843582e9609ef0d5", + "sha256": "44b385eba5dd62a5c13084c4c296805fca6e600676b280be6d78369bacc98893", "width": 352 }, "palette": "ember", @@ -10299,7 +10302,7 @@ "image": { "height": 1024, "path": "images/motion-ember-start-narrow-2x.png", - "sha256": "a8696131d75a9a0c762a66035bbe75e49ab39579d9b504c09e85a40b4e8d9a76", + "sha256": "a5f0b5bf70793dba1f773bb8c1adb6e45bf022ae2acd59d53865cd38157d4961", "width": 704 }, "palette": "ember", @@ -10320,7 +10323,7 @@ "image": { "height": 512, "path": "images/motion-ember-middle-regular-1x.png", - "sha256": "6a66a33a53771ae94ae4e2173b674b2df5391c5d6087729a79849bb15fa1ebb2", + "sha256": "008278e9ba27b8ff0b9450cdd543b03eb8f568a74cdefc8f08c25a3aeb07fe81", "width": 800 }, "palette": "ember", @@ -10341,7 +10344,7 @@ "image": { "height": 1024, "path": "images/motion-ember-middle-regular-2x.png", - "sha256": "eb5ff27892eee164fa7643f1a3724109a0e1afe21d78df178f9c6de8acc1b1ce", + "sha256": "055cc4767880e15c06721f61ee8cd9fa54777524d006b7b95b430af2dcb21ac8", "width": 1600 }, "palette": "ember", @@ -10362,7 +10365,7 @@ "image": { "height": 512, "path": "images/motion-ember-middle-narrow-1x.png", - "sha256": "6270f46edad1299e8df9dc007f81379d1956cb31b6015bef5576f70a803ebd2b", + "sha256": "6176567000bdf2e74cb35f6af07d19d81eabfffb1886cfdb5b13720afc48d041", "width": 352 }, "palette": "ember", @@ -10383,7 +10386,7 @@ "image": { "height": 1024, "path": "images/motion-ember-middle-narrow-2x.png", - "sha256": "a42b9c8b9017ec1067e4bf1cf8107b553b2fdcb195b9d1912ec7272bbc35cc6e", + "sha256": "5418fcd36273b3cc28f65cb833883c487e39efddda5b00be48908566dd314bac", "width": 704 }, "palette": "ember", diff --git a/site/src/pages/docs/library.astro b/site/src/pages/docs/library.astro index 4d19ce76..f46f96ae 100644 --- a/site/src/pages/docs/library.astro +++ b/site/src/pages/docs/library.astro @@ -81,6 +81,14 @@ const sections: [string, string][] = [['scope','01 · Library boundary'],['contr
MULTILINE INPUT

The document belongs to the component.

Element::text_area takes a value, selection, placeholder, controlled ScrollSpec and edit/scroll callbacks. Use TextFieldState::multiline() to retain hard lines through the same bounded ordinary history and clipboard model. A shared source-indexed row map drives wrapping, pointer selection, vertical movement and visible-row paint; the engine retains only transient visual affinity and the horizontal navigation goal.

The native runtime refreshes CPU input geometry independently of GPU frame admission. Queued edits and row movement can therefore use current client state while a previous buffer awaits a compositor callback. Textarea painting emits visible rows individually, preserving raster density without creating one tall document texture. The current merged 8e6d074b text path shares script/bidi/fallback shaping and source/caret geometry, with ordinary-client IME opt-in. Its owned native IME suite passes five feature and five restoration checks; third-party/physical/cross-output IME and broader pixel/scroll details remain separate acceptance.

Read the multiline implementation guide for model ownership, wrap affinity, capture, clipboard lifetime, runtime flow and 17 passing native Notes functional checks and nine restoration checks. That historical clipboard run used wl-copy/wl-paste. Later real Chromium textarea ↔ Notes keyboard transfers pass all nine interaction and twelve restoration checks on unchanged 8e with harness 2044e54f, one virtual output. Native pixel/scroll details, other apps, rich content and delayed-transfer/focus races remain separate acceptance.

ASSETS AND FRAME TIMING

Images arrive through effects.

The notification client requests current-version image content through its presentation AssetPort. Its adapter reads local files or converts validated raw pixels on the existing asset worker, prepares immutable ImageData with mip levels and returns typed results. One active batch and latest pending demand bound the queue. Views reference prepared data through Element::image; the framework knows no notification source path or hint policy.

A newly prepared picture receives a client Motion using design tokens. Its opacity is sampled at ViewContext::now, and active motion reaches the runtime through Application::animating. Compositor callbacks pace dirty frames until it settles; Vulkan blends the supplied value. Bounded scroll viewports keep image-card actions reachable. Read the image implementation guide for domain values, adapters, preparation, clips, input, retention and measurements.

+
+ INPUT OWNERSHIP +

Remembering a caret does not mean owning the keyboard.

+

A widget's catalog capability, explicit user demand, logical field selection and native keyboard ownership are separate states. The implemented framework API accepts a focus request only from a genuine prepared focusable press. Its native backend acknowledges actual Enter and verifies focus after releasing its temporary acquisition scope; the client retains member/output intent and rejects stale results. Native caret and focus painting follow actual keyboard activity.

+

The step-by-step keyboard-focus guide follows the request through the client, generic API, prepared UI input and native protocol, with source paths and a sequence diagram. Domain contracts remain ports and supplied OS implementations remain adapters; native objects stay out of the domain.

+

The actual b2 trial still passes pointer opening and fails Tab/Enter, with nine cleanup checks in each case. It observes Clock regaining native focus after history closes. The new one-shot implementation needs fresh native acceptance; this guide does not claim that failure is fixed.

+

The ba5 release report records 17 hosted Arch qualification stages, 880 tests and 94 required regressions, followed by concrete target compatibility review and coherent six-client/root-greeter deployment. Its actual llvmpipe CPU-Vulkan catalogue covers 121 rendering inputs and 480 captures. All 480 file hashes differ from the older RADV catalogue; 18 paired pixel samples peak at about 2/255 error and four visual pairs show no visible layout regression. That sampled comparison establishes neither all-capture pixel parity nor native GPU performance. A first Notes controller attempt stops before typing; its nine restoration checks pass. Immediate input, outside-click behavior, cold URI handoff, lock/login and resource/FPS acceptance remain pending.

+
04 / USE THE CURRENT GEOMETRY

Anchor a label.
Own an explicit popup.

The ordinary tree lays out first. A deferred overlay pass resolves the element ID against that surface’s actual bounds and clips. AnchoredSpec describes the preferred side, alignment, gap and viewport inset. Placement can flip and clamp; it cannot leave the native buffer or invent output-global coordinates. Missing, duplicate, clipped or invalid anchors cannot host the overlay.