From 645d161cbdca1ec4b63a237323d78b3581cf93d4 Mon Sep 17 00:00:00 2001 From: gentpan Date: Mon, 21 Sep 2026 03:38:08 +0500 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=E6=AD=BB=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=81=E6=AD=BB=E8=AF=91=E6=96=87=E4=B8=8E=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删掉没人调用的函数、属性与解码字段:网络弹窗的两个标签函数、supportsStyleOverride、probedAddress、countryEn、辅助工具客户端的单风扇恢复自动封装(协议与辅助工具端保留,不动 XPC 接口) - 译文表删掉 19 条不再使用的条目,补上测速窗口“开始”按钮漏掉的英文 - 网络弹窗与出口窗口各自一份的归属地格式化和 IP 类型徽章合并为 GeoText;两个折线图里重复的参考线绘制提成 ChartGrid - 官网样式删掉没人用的 .mb-drop__ext - server/sync/sync 是误提交的 Go 编译产物,从仓库移除并忽略 --- .gitignore | 2 + CHANGELOG.md | 1 + .../Sources/Localization/Translations.swift | 20 +-------- .../Sources/Metrics/PublicAddressLookup.swift | 1 - .../Sources/OpenStatsUI/Design/Charts.swift | 30 +++++++------ .../Sources/OpenStatsUI/Design/GeoText.swift | 25 +++++++++++ .../OpenStatsUI/Panel/EgressWindowView.swift | 19 ++------- .../OpenStatsUI/Popover/NetworkPopover.swift | 42 ++++--------------- .../OpenStatsUI/State/AppSettings.swift | 3 -- .../OpenStatsUI/State/HelperClient.swift | 4 -- .../OpenStatsUI/State/NetworkController.swift | 1 - web/replica.css | 1 - 12 files changed, 53 insertions(+), 96 deletions(-) create mode 100644 Packages/OpenStatsKit/Sources/OpenStatsUI/Design/GeoText.swift diff --git a/.gitignore b/.gitignore index ead4d6a..23ccb48 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ xcuserdata/ Packages/OpenStatsKit/Package.resolved dist/ __pycache__/ +# go build 在同步服务目录下生成的本地二进制 +server/sync/sync diff --git a/CHANGELOG.md b/CHANGELOG.md index 9271677..1635189 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ #### 修复 - 账号登录后应用直接退出:在登录窗口里选完 GitHub、Google 或 Apple 账号,应用立即闪退,重新打开也没有登录状态。原因是系统在后台队列回调登录结果,而回调闭包带着主线程隔离,被运行时当场中止,令牌还没来得及换取和保存。现在回调改为不带隔离、收到后再回到主线程处理,并补了回归测试。 +- 英文界面下测速窗口的“开始”按钮没有翻译,仍显示中文。 ## 0.6.1 · 2026-09-18 diff --git a/Packages/OpenStatsKit/Sources/Localization/Translations.swift b/Packages/OpenStatsKit/Sources/Localization/Translations.swift index 70eb343..f27d0e6 100644 --- a/Packages/OpenStatsKit/Sources/Localization/Translations.swift +++ b/Packages/OpenStatsKit/Sources/Localization/Translations.swift @@ -60,7 +60,6 @@ GPU 占用 GPU Usage Globalping 返回了错误(HTTP {}) Globalping returned an error (HTTP {}) Google(8.8.8.8) Google (8.8.8.8) IP 地址 IP Addresses -IP 类型 IP type IP 纯净度 IP cleanliness IPv6 没有经过代理:只走 IPv6 的连接会直接暴露本机地址 {}。 IPv6 isn't going through the proxy: IPv6-only connections expose your address {}. IPv6 连接也经过代理。 IPv6 connections also go through the proxy. @@ -104,7 +103,6 @@ npm 缓存 npm Cache {} 个应用,系统自带的不列出 {} apps; built-in apps are not listed {} 个网站 {} sites {} 个进程 {} processes -{} 中位延迟 {} median {} 分钟 {} min {} 可用 {} · 共 {} {} {} free · {} total {} 天 {} d @@ -117,7 +115,6 @@ npm 缓存 npm Cache {} 正在运行,卸载前需要先退出。 {} is running. Quit it before uninstalling. {} 测 at {} {} 秒 {}s -{} 秒 / {} MB {}s / {} MB {} 秒·{} MB {}s · {} MB {} 组 {} groups {} 缓存 {} Cache @@ -127,7 +124,6 @@ npm 缓存 npm Cache {} 项 · 需要管理员权限,只读 {} items · needs admin, read-only {} 项失败 {} failed {}%(阈值 {}%) {}% (threshold {}%) -{}/{} 个节点连得上 {}/{} nodes reachable {}{}只剩 {}%,记得充电。 {}{} is down to {}%. Time to charge. {}{}({}) {}{} ({}) {}。系统会自动分配任务,不用你操心 {}. macOS assigns work between them automatically. @@ -205,7 +201,6 @@ npm 缓存 npm Cache 以后再说 Later 以系统权限运行的后台服务,只接受本应用的请求 A background service with system privileges that only accepts requests from this app 仪表盘 Dashboard -企业 Business 企业 IP Business IP 企业网络 Business network 会一并找出它留在资源库里的缓存、偏好设置、容器与登录启动项,全部移到废纸篓,可以放回 Also finds its caches, preferences, containers and launch agents in your Library and moves them all to the Trash, where you can restore them @@ -217,8 +212,6 @@ npm 缓存 npm Cache 低风险 Low risk 住宅 IP Residential IP 住宅代理 Residential proxy -住宅宽带 Residential -住宅概率 Residential probability 余量 {} Headroom {} 使用 {} 登录 Sign in with {} 使用云端设置 Use cloud settings @@ -311,14 +304,12 @@ npm 缓存 npm Cache 剪切 Cut 功耗 Power 包名是 {} Bundle ID is {} -包含城市数据 Include City Data 协议版本 Protocol version 单个节点一次测速最多花的时间与流量,先到哪个停哪个 Time and data cap for one node's speed test, whichever comes first 单行 Inline 单行文字 Inline Text 占整机 CPU 的比例:{} 个核心全部跑满为 100% Share of total CPU: all {} cores fully busy is 100% 占用 Usage -占用超过 85% 时数值与图形显示为红色 Show values and graphs in red above 85% 占用超过 85%(电池电量低于 20%)时数值与图形显示为红色 Values and graphics turn red above 85% usage (below 20% battery) 占用高于 Usage above 卷 Volume @@ -339,14 +330,12 @@ npm 缓存 npm Cache 压缩包里应当只有一个 .app The archive should contain exactly one .app 压缩比 Compression ratio 原因 Reason -原生 / 广播 Native / broadcast 原生 IP Native IP 去批准 Approve 去授权 Grant Access 双行圆点 Dots 双行文字 Stacked Text 双行箭头 Arrows -反向解析 Reverse DNS 反馈问题 Report a Problem 发现新版本 {} Version {} available 发现问题 Problems found @@ -378,7 +367,6 @@ npm 缓存 npm Cache 可用 {} {} available 可用 {} / 共 {} {1} free of {2} 可用内存只剩 {},系统正在压缩和交换内存。关闭不用的应用可以缓解。 Only {} of memory is available and the system is compressing and swapping. Quitting unused apps will help. -可用空间包含系统可以随时清除的缓存,与访达显示一致 Available space includes purgeable caches, matching Finder 可访问 Reachable 右侧风扇 Right Fan 右耳 Right @@ -536,6 +524,7 @@ npm 缓存 npm Cache 开启 On 开启 / 关闭“合盖不睡眠”(等同 pmset disablesleep) Turn lid-closed sleep prevention on or off (same as pmset disablesleep) 开启后图标出现在菜单栏;按住 ⌘ 键拖动图标可以调整位置 Adds the icon to the menu bar; hold ⌘ and drag the icon to move it +开始 Start 开始分析 Analyze 开始探测 Run 开机以来 Since boot @@ -582,7 +571,6 @@ npm 缓存 npm Cache 打包版本、系统与辅助工具状态、主要设置、最近 3 天的运行日志和崩溃报告,反馈问题时附上;会去掉序列号、IP 与硬件地址 Bundles version, system and helper status, main settings, and the last 3 days of logs and crash reports to attach to a bug report. Serial numbers, IP and hardware addresses are removed. 打包生成的 .xcarchive,删除后无法重新符号化旧版本崩溃日志 .xcarchive bundles; without them old crash logs can't be symbolicated 打开 OpenStats Open OpenStats -打开 OpenStats 主窗口 Open the OpenStats Window 打开 SMC 失败 ({}) Failed to open SMC ({}) 打开登录项设置 Open Login Items Settings 打开网络详情时向 Cloudflare(1.1.1.1)或 ipify 查询一次公网地址,10 分钟内不重复请求;归属地、ASN、网络类型与纯净度由这台 Mac 直接向 cleanip.io 查询,只发送公网地址 When network details open, asks Cloudflare (1.1.1.1) or ipify for your public address, at most once every 10 minutes; location, ASN, network type and cleanliness are looked up by this Mac directly at cleanip.io, sending only the public address @@ -632,7 +620,6 @@ npm 缓存 npm Cache 教育网 Education 散热模式 Cooling 数据 Data -数据来源 Source 整体风格 Overall style 整体风格套用到所有项目。想让某个项目不一样,在下面“显示项目”里给它单独选一种,比如 CPU 用圆环、风扇用数字。 The overall style applies to every item. To make one item different, pick a style for it under Items below, say a ring for CPU and plain numbers for the fan. 整机 System @@ -908,7 +895,6 @@ npm 缓存 npm Cache 社交 Social 移到废纸篓 Move to Trash 移到废纸篓? Move to the Trash? -移动网络 Mobile 移动网络 IP Mobile IP 移动运营商 Mobile carrier 空 empty @@ -972,7 +958,6 @@ npm 缓存 npm Cache 网络断开 Network Down 网络测速 Network Speed Test 网络环境变了,下面是之前的结果,正在重新检测。 The network changed. These are the previous results; checking again. -网络类型 Network type 网络详情打开时每秒 ping 一次,通了是绿格、不通是红格,显示最近 60 次 Pings once a second while network details are open: green when reachable, red when not, showing the last 60 网络运营方 Network operator 网络连接中断超过 20 秒,恢复后再提示一次 Network has been down for over 20 seconds; notifies again when it's back @@ -1046,7 +1031,6 @@ npm 缓存 npm Cache 超时 Timed out 超级核 Super 超过 1 天未更新的 .crdownload / .part / .download .crdownload / .part / .download files untouched for over a day -跟随整体 Follow global 跟随整体({}) Follow overall ({}) 跟随系统 System 路径不可读 Path not readable @@ -1113,7 +1097,6 @@ npm 缓存 npm Cache 重新分析 Analyze again 重新安装 Reinstall 重新扫描 Rescan -重新查询公网 IP Look Up Public IP Again 重新检测 Check Again 重新生成 Regenerate 重新读取蓝牙设备电量 Read Bluetooth device batteries again @@ -1143,7 +1126,6 @@ npm 缓存 npm Cache 风扇模式 Fan mode 风扇设置 Fan Settings 风扇转速 Fan Speed -风格 Style 风险标记 Risk flags 风险评分 Risk score 饼图 Pie diff --git a/Packages/OpenStatsKit/Sources/Metrics/PublicAddressLookup.swift b/Packages/OpenStatsKit/Sources/Metrics/PublicAddressLookup.swift index 0dcf80e..0632637 100644 --- a/Packages/OpenStatsKit/Sources/Metrics/PublicAddressLookup.swift +++ b/Packages/OpenStatsKit/Sources/Metrics/PublicAddressLookup.swift @@ -159,7 +159,6 @@ public enum PublicAddressLookup { struct Geo: Decodable { let countryCode: String? let country: String? - let countryEn: String? let region: String? let city: String? } diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Charts.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Charts.swift index 61c0f22..68038ab 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Charts.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/Charts.swift @@ -42,6 +42,18 @@ struct BarHistoryChart: View { } } +/// 图表里 25% / 50% / 75% 三条淡淡的参考线 +enum ChartGrid { + static func draw(in context: GraphicsContext, size: CGSize) { + let usable = size.height - DS.Size.chartLine * 2 + for fraction in [0.25, 0.5, 0.75] { + let y = (DS.Size.chartLine + usable * CGFloat(1 - fraction)).rounded() + context.fill(Path(CGRect(x: 0, y: y, width: size.width, height: DS.Size.stroke)), + with: .color(DS.Palette.border)) + } + } +} + /// 历史折线(可带实色半透明填充) struct LineHistoryChart: View { let values: [Double] @@ -55,14 +67,7 @@ struct LineHistoryChart: View { var body: some View { Canvas { context, size in - if grid { - let usable = size.height - DS.Size.chartLine * 2 - for fraction in [0.25, 0.5, 0.75] { - let y = (DS.Size.chartLine + usable * CGFloat(1 - fraction)).rounded() - context.fill(Path(CGRect(x: 0, y: y, width: size.width, height: DS.Size.stroke)), - with: .color(DS.Palette.border)) - } - } + if grid { ChartGrid.draw(in: context, size: size) } let line = LineHistoryChart.path(values: values, capacity: capacity, maxValue: maxValue, in: size) guard let line else { return } if filled { @@ -112,14 +117,7 @@ struct TimedLineChart: View { var body: some View { Canvas { context, size in - if grid { - let usable = size.height - DS.Size.chartLine * 2 - for fraction in [0.25, 0.5, 0.75] { - let y = (DS.Size.chartLine + usable * CGFloat(1 - fraction)).rounded() - context.fill(Path(CGRect(x: 0, y: y, width: size.width, height: DS.Size.stroke)), - with: .color(DS.Palette.border)) - } - } + if grid { ChartGrid.draw(in: context, size: size) } for segment in Self.segments(points, duration: duration, end: end, in: size) { guard let first = segment.first, let last = segment.last else { continue } var line = Path() diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/GeoText.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/GeoText.swift new file mode 100644 index 0000000..430c1ea --- /dev/null +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Design/GeoText.swift @@ -0,0 +1,25 @@ +import Foundation +import Localization + +/// 归属地与 IP 类型的文字:网络弹窗与出口窗口共用 +enum GeoText { + /// 国家 · 省 / 州 · 城市;英文界面优先用英文地名,重复的相邻项只留一个 + static func location(countryCode: String, region: String?, regionEnglish: String?, city: String?, cityEnglish: String?) -> String { + let country = Locale(identifier: L10n.isEnglish ? "en" : "zh-Hans").localizedString(forRegionCode: countryCode) ?? countryCode + let region = L10n.isEnglish ? (regionEnglish ?? region) : region + let city = L10n.isEnglish ? (cityEnglish ?? city) : city + var parts = [country] + for part in [region, city].compactMap({ $0 }) where part != parts.last { parts.append(part) } + return parts.joined(separator: " · ") + } + + /// 数据源给的 IP 类型(residential ip、datacenter ip……)对应的徽章;不认识的返回 nil + static func ipTypeBadge(_ raw: String) -> (icon: String, text: String, tone: TagBadge.Tone)? { + let type = raw.lowercased() + if type.contains("residential") { return ("house.fill", tr("住宅 IP"), .success) } + if type.contains("mobile") { return ("iphone.radiowaves.left.and.right", tr("移动网络 IP"), .success) } + if type.contains("business") { return ("building.2.fill", tr("企业 IP"), .success) } + if type.contains("idc") || type.contains("datacenter") || type.contains("hosting") { return ("server.rack", tr("机房 IP"), .warning) } + return nil + } +} diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/EgressWindowView.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/EgressWindowView.swift index 96040f3..7ba6ee8 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/EgressWindowView.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Panel/EgressWindowView.swift @@ -306,7 +306,7 @@ private struct ExitNode: View { .lineLimit(1) .truncationMode(.tail) } - if let type = geo?.ipType.flatMap(EgressText.ipTypeBadge) { + if let type = geo?.ipType.flatMap(GeoText.ipTypeBadge) { TagBadge(text: type.text, tone: type.tone, compact: true) } } @@ -744,24 +744,11 @@ private enum EgressText { } } - static func ipTypeBadge(_ raw: String) -> (text: String, tone: TagBadge.Tone)? { - let type = raw.lowercased() - if type.contains("residential") { return (tr("住宅 IP"), .success) } - if type.contains("mobile") { return (tr("移动网络 IP"), .success) } - if type.contains("business") { return (tr("企业 IP"), .success) } - if type.contains("idc") || type.contains("datacenter") || type.contains("hosting") { return (tr("机房 IP"), .warning) } - return nil - } - /// 国家 · 省 / 州 · 城市;英文界面优先用英文地名,重复的相邻项只留一个 static func location(_ geo: EgressGeo?, fallback country: String?) -> String { guard let code = geo?.countryCode ?? country else { return "" } - let name = Locale(identifier: L10n.isEnglish ? "en" : "zh-Hans").localizedString(forRegionCode: code) ?? code - let region = L10n.isEnglish ? (geo?.regionEnglish ?? geo?.region) : geo?.region - let city = L10n.isEnglish ? (geo?.cityEnglish ?? geo?.city) : geo?.city - var parts = [name] - for part in [region, city].compactMap({ $0 }) where part != parts.last { parts.append(part) } - return parts.joined(separator: " · ") + return GeoText.location(countryCode: code, region: geo?.region, regionEnglish: geo?.regionEnglish, + city: geo?.city, cityEnglish: geo?.cityEnglish) } static func checkedAt(_ date: Date, now: Date) -> String { diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift index 287fa9e..3fae346 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift @@ -244,12 +244,8 @@ private struct AddressSection: View { /// 国家 · 省 / 州 · 城市;英文界面优先用英文地名,重复的相邻项只留一个 private func location(_ addresses: PublicAddresses, code: String) -> String { - let country = Locale(identifier: L10n.isEnglish ? "en" : "zh-Hans").localizedString(forRegionCode: code) ?? code - let region = L10n.isEnglish ? (addresses.regionEnglish ?? addresses.region) : addresses.region - let city = L10n.isEnglish ? (addresses.cityEnglish ?? addresses.city) : addresses.city - var parts: [String] = [country] - for part in [region, city].compactMap({ $0 }) where part != parts.last { parts.append(part) } - return parts.joined(separator: " · ") + GeoText.location(countryCode: code, region: addresses.region, regionEnglish: addresses.regionEnglish, + city: addresses.city, cityEnglish: addresses.cityEnglish) } /// 标题行:IP 地址 ……… [IPv4 | IPv6] ⟳;数据来源的字标只放在下面的纯净度区块里 @@ -292,13 +288,11 @@ private struct AddressSection: View { badges.append(isNative ? Badge(icon: "checkmark.shield.fill", text: tr("原生 IP"), tone: .success) : Badge(icon: "antenna.radiowaves.left.and.right", text: tr("广播 IP"), tone: .warning)) } - if let ipType = addresses.ipType?.lowercased() { - switch ipType { - case "residential ip": badges.append(Badge(icon: "house.fill", text: tr("住宅 IP"), tone: .success)) - case "datacenter ip", "hosting ip": badges.append(Badge(icon: "server.rack", text: tr("机房 IP"), tone: .warning)) - case "mobile ip": badges.append(Badge(icon: "iphone.radiowaves.left.and.right", text: tr("移动网络 IP"), tone: .success)) - case "business ip": badges.append(Badge(icon: "building.2.fill", text: tr("企业 IP"), tone: .success)) - default: badges.append(Badge(icon: "questionmark.circle", text: addresses.ipType ?? "", tone: .neutral)) + if let ipType = addresses.ipType { + if let known = GeoText.ipTypeBadge(ipType) { + badges.append(Badge(icon: known.icon, text: known.text, tone: known.tone)) + } else { + badges.append(Badge(icon: "questionmark.circle", text: ipType, tone: .neutral)) } } if let asnType = addresses.asnType { @@ -314,28 +308,6 @@ private struct AddressSection: View { } return badges } - - static func networkTypeLabel(_ raw: String) -> String { - switch raw.lowercased() { - case "residential", "isp": tr("住宅宽带") - case "business": tr("企业") - case "hosting", "datacenter", "data center": tr("机房") - case "mobile", "cellular": tr("移动网络") - case "education": tr("教育网") - case "government": tr("政府") - default: raw - } - } - - static func ipTypeLabel(_ raw: String) -> String { - switch raw.lowercased() { - case "residential ip": tr("住宅 IP") - case "datacenter ip", "hosting ip": tr("机房 IP") - case "mobile ip": tr("移动网络 IP") - case "business ip": tr("企业 IP") - default: raw - } - } } // MARK: - IP 纯净度 diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/AppSettings.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/AppSettings.swift index cdbdd10..47cca0a 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/AppSettings.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/AppSettings.swift @@ -76,9 +76,6 @@ public enum MenuBarItem: String, CaseIterable, Identifiable, Sendable { } } - /// 可以单独指定风格的指标(网速有自己的样式) - var supportsStyleOverride: Bool { self != .network } - var symbol: String { switch self { case .cpu: "cpu" diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/HelperClient.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/HelperClient.swift index 7bd17ff..2cd94d9 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/HelperClient.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/HelperClient.swift @@ -140,10 +140,6 @@ public final class HelperClient { await call { proxy, reply in proxy.setFanTarget(fan: fan, rpm: rpm, reply: reply) } } - func setFanAutomatic(fan: Int) async -> String? { - await call { proxy, reply in proxy.setFanAutomatic(fan: fan, reply: reply) } - } - func resetAllFans() async -> String? { await call { proxy, reply in proxy.resetAllFans(reply: reply) } } diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/NetworkController.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/NetworkController.swift index 3aa16d3..463bb69 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/State/NetworkController.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/State/NetworkController.swift @@ -42,7 +42,6 @@ public final class NetworkController { @ObservationIgnored private let settings: AppSettings @ObservationIgnored private var probeTask: Task? @ObservationIgnored private var detailTask: Task? - @ObservationIgnored private var probedAddress: String? @ObservationIgnored private var lastPublicLookup: (date: Date, localIPv4: [String])? @ObservationIgnored private var isPaused = false @ObservationIgnored private var wantsDetail = false diff --git a/web/replica.css b/web/replica.css index ebcba62..3c503eb 100644 --- a/web/replica.css +++ b/web/replica.css @@ -155,7 +155,6 @@ } .mb-drop a:hover { background: var(--color-primary); color: #fff; } .mb-drop hr { border: 0; border-top: 1px solid var(--drop-border); margin: var(--space-1) var(--space-2); } -.mb-drop__ext { opacity: 0.6; } .menubar__right { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); } .menubar__clock { font-variant-numeric: tabular-nums; }