From b2c648c3e6ec7404d545a6c6a8a0381a7623cbb1 Mon Sep 17 00:00:00 2001 From: Megghy Date: Thu, 25 Sep 2025 17:15:57 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0=20Ant=20Design=20?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=20DNS=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将项目从 Fluent UI 迁移到 Ant Design Blazor: - 替换 UI 组件,更新样式和脚本。 - 移除 Fluent UI 相关依赖,添加 Ant Design 依赖。 优化 DNS 解析接口: - 将解析接口从 POST 改为 GET,简化参数结构。 - 更新 `DnsResponse` 和配置文件结构。 数据库模型优化: - 为 JSON 数据存储添加 `JArray` 映射支持。 初始化逻辑重构: - 简化 `AutoInit` 初始化逻辑,提升代码可读性。 其他改动: - 升级依赖包版本。 - 移除无用命名空间和属性。 --- Components/App.razor | 12 +- Components/Layout/MainLayout.razor | 55 ++++--- Components/Layout/NavMenu.razor | 92 ++++++++++-- Components/Pages/Counter.razor | 21 --- Components/Pages/Pixiv.razor | 15 +- Components/Pages/Weather.razor | 43 ------ Components/_Imports.razor | 5 +- Controllers/PublicController.cs | 20 +-- DB.cs | 1 - Data/Config.json | 10 +- MegghysAPI.csproj | 13 +- Modules/PixivFavoriteDownloader.cs | 8 +- Program.cs | 58 +++++--- wwwroot/app.css | 227 +++++++++-------------------- 14 files changed, 256 insertions(+), 324 deletions(-) delete mode 100644 Components/Pages/Counter.razor delete mode 100644 Components/Pages/Weather.razor diff --git a/Components/App.razor b/Components/App.razor index 346ac69..f4133f5 100644 --- a/Components/App.razor +++ b/Components/App.razor @@ -1,4 +1,4 @@ - + @@ -7,17 +7,17 @@ + - - - - - + + + + diff --git a/Components/Layout/MainLayout.razor b/Components/Layout/MainLayout.razor index 302772b..f74a54b 100644 --- a/Components/Layout/MainLayout.razor +++ b/Components/Layout/MainLayout.razor @@ -1,26 +1,43 @@ -@inherits LayoutComponentBase +@inherits LayoutComponentBase - - - MegghysAPI - - - - -
- @Body -
-
-
- - Documentation and demos - - About Blazor - -
+ +
+
MegghysAPI
+
+ + + + + + +
+ @Body +
+
+ +
+
+
An unhandled error has occurred. Reload 🗙
+ +@code { + private bool collapsed; + + private void HandleCollapse(bool isCollapsed) + { + collapsed = isCollapsed; + } +} diff --git a/Components/Layout/NavMenu.razor b/Components/Layout/NavMenu.razor index fd44fea..6f1c99d 100644 --- a/Components/Layout/NavMenu.razor +++ b/Components/Layout/NavMenu.razor @@ -1,20 +1,80 @@ -@rendermode InteractiveServer +@rendermode InteractiveServer +@implements IDisposable - + + + + Home + + + + Pixiv + + + + Weather + + @code { - private bool expanded = true; - public DesignThemeModes Mode { get; set; } - public OfficeColor? OfficeColor { get; set; } + [Parameter] + public bool InlineCollapsed { get; set; } + + private string[] selectedKeys = ["/"]; + + [Inject] + private NavigationManager NavigationManager { get; set; } = default!; + + protected override void OnParametersSet() + { + UpdateSelectedKeys(NavigationManager.Uri); + } + + protected override void OnInitialized() + { + UpdateSelectedKeys(NavigationManager.Uri); + NavigationManager.LocationChanged += HandleLocationChanged; + } + + private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) + { + UpdateSelectedKeys(e.Location); + StateHasChanged(); + } + + private void UpdateSelectedKeys(string uri) + { + var relative = NavigationManager.ToBaseRelativePath(uri); + if (string.IsNullOrEmpty(relative)) + { + selectedKeys = ["/"]; + } + else + { + var key = relative.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? string.Empty; + selectedKeys = [key]; + } + } + + private void HandleMenuClick(MenuItem menuItem) + { + if (menuItem.Key is null) + { + return; + } + + selectedKeys = [menuItem.Key]; + var target = menuItem.Key == "/" ? "/" : $"/{menuItem.Key}"; + NavigationManager.NavigateTo(target); + } + + public void Dispose() + { + NavigationManager.LocationChanged -= HandleLocationChanged; + } } diff --git a/Components/Pages/Counter.razor b/Components/Pages/Counter.razor deleted file mode 100644 index bc892df..0000000 --- a/Components/Pages/Counter.razor +++ /dev/null @@ -1,21 +0,0 @@ -@page "/counter" -@rendermode InteractiveServer - -Counter - -

Counter

- -
- Current count: @currentCount -
- -Click me - -@code { - private int currentCount = 0; - - private void IncrementCount() - { - currentCount++; - } -} diff --git a/Components/Pages/Pixiv.razor b/Components/Pages/Pixiv.razor index f0775ef..238a9fc 100644 --- a/Components/Pages/Pixiv.razor +++ b/Components/Pages/Pixiv.razor @@ -1,14 +1,13 @@ -@page "/pixiv" +@page "/pixiv" @rendermode InteractiveServer

Pixiv

- - 随机获取 - - -
- + + + + + @foreach (var (index, img) in CurrentImgs.S3URL.Index()) { @if(index == 0) @@ -20,7 +19,7 @@ } } - + @code { public Modules.PixivFavoriteDownloader.Pixiv.PixivImgInfo CurrentImgs; diff --git a/Components/Pages/Weather.razor b/Components/Pages/Weather.razor deleted file mode 100644 index 0506bba..0000000 --- a/Components/Pages/Weather.razor +++ /dev/null @@ -1,43 +0,0 @@ -@page "/weather" -@attribute [StreamRendering] - -Weather - -

Weather

- -

This component demonstrates showing data.

- - - - - - - - - -@code { - private IQueryable? forecasts; - - protected override async Task OnInitializedAsync() - { - // Simulate asynchronous loading to demonstrate streaming rendering - await Task.Delay(500); - - var startDate = DateOnly.FromDateTime(DateTime.Now); - var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; - forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = startDate.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = summaries[Random.Shared.Next(summaries.Length)] - }).AsQueryable(); - } - - private class WeatherForecast - { - public DateOnly Date { get; set; } - public int TemperatureC { get; set; } - public string? Summary { get; set; } - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } -} diff --git a/Components/_Imports.razor b/Components/_Imports.razor index 8c17df0..1d13022 100644 --- a/Components/_Imports.razor +++ b/Components/_Imports.razor @@ -1,12 +1,11 @@ -@using System.Net.Http +@using System.Net.Http @using System.Net.Http.Json @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization -@using Microsoft.FluentUI.AspNetCore.Components -@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons +@using AntDesign @using Microsoft.JSInterop @using MegghysAPI @using MegghysAPI.Components diff --git a/Controllers/PublicController.cs b/Controllers/PublicController.cs index 9a82fc8..47a490d 100644 --- a/Controllers/PublicController.cs +++ b/Controllers/PublicController.cs @@ -23,6 +23,11 @@ namespace MegghysAPI.Controllers public class DnsResponse { + public class DnsQuestion + { + public string Name { get; set; } + public int type { get; set; } + } [JsonPropertyName("Status")] public int Status { get; set; } @@ -42,17 +47,12 @@ namespace MegghysAPI.Controllers public bool Cd { get; set; } [JsonPropertyName("Question")] - public List> Question { get; set; } = new(); + public DnsQuestion Question { get; set; } [JsonPropertyName("Answer")] public List? Answer { get; set; } } - public class DnsRequest - { - public string Domain { get; set; } = string.Empty; - public string RecordType { get; set; } = "A"; - } [Route("api/public")] [ApiController] public class PublicController : MControllerBase @@ -67,8 +67,8 @@ namespace MegghysAPI.Controllers return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); } - [HttpPost("resolve-dns")] - public static async Task ResolveDns([FromBody] DnsRequest request) + [HttpGet("resolve-dns")] + public async Task ResolveDns([FromQuery] string domain, [FromQuery] string recordType = "A") { try { @@ -84,9 +84,9 @@ namespace MegghysAPI.Controllers } var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - var key = CalculateKey(accountId, akSecret, timestamp, request.Domain, akId); + var key = CalculateKey(accountId, akSecret, timestamp, domain, akId); - var url = $"{endpoint}?name={Uri.EscapeDataString(request.Domain)}&type={request.RecordType}&uid={accountId}&ak={akId}&key={key}&ts={timestamp}"; + var url = $"{endpoint}?name={Uri.EscapeDataString(domain)}&type={recordType}&uid={accountId}&ak={akId}&key={key}&ts={timestamp}"; Logs.Info($"正在向 {url} 发起DNS请求"); diff --git a/DB.cs b/DB.cs index cc1a95c..a0918e5 100644 --- a/DB.cs +++ b/DB.cs @@ -6,7 +6,6 @@ namespace MegghysAPI public static class DB { public static IFreeSql SQL { get; private set; } - [AutoInit(Order = 0)] internal static void InitDB() { SQL = new FreeSqlBuilder() diff --git a/Data/Config.json b/Data/Config.json index ebf1cad..0a31b95 100644 --- a/Data/Config.json +++ b/Data/Config.json @@ -8,10 +8,8 @@ "MinIOSecretKey": "Nko5azOSUiYgOUeLsj8hLxGz4cKC8XOcH0VS7lWq", "MinIORegion": "cn-main", "MinIOBucket": "general", - "DnsResolver": { - "AccountId": "720341", - "AkId": "720341_30798028364391424", - "AkSecret": "0739b7584ab54c1b9585f10594af0cd0", - "Endpoint": "https://223.5.5.5/resolve" - } + "DnsResolverAccountId": "720341", + "DnsResolverAkId": "720341_30798028364391424", + "DnsResolverAkSecret": "0739b7584ab54c1b9585f10594af0cd0", + "DnsResolverEndpoint": "https://223.5.5.5/resolve" } \ No newline at end of file diff --git a/MegghysAPI.csproj b/MegghysAPI.csproj index 6babec2..c2ddea6 100644 --- a/MegghysAPI.csproj +++ b/MegghysAPI.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -7,12 +7,11 @@ - - - - - - + + + + + diff --git a/Modules/PixivFavoriteDownloader.cs b/Modules/PixivFavoriteDownloader.cs index 7aaa069..41f765a 100644 --- a/Modules/PixivFavoriteDownloader.cs +++ b/Modules/PixivFavoriteDownloader.cs @@ -2,6 +2,7 @@ using System.Web; using FreeSql.DataAnnotations; using MegghysAPI.Attributes; +using Newtonsoft.Json.Linq; using static MegghysAPI.Modules.PixivFavoriteDownloader.Pixiv; namespace MegghysAPI.Modules @@ -184,19 +185,18 @@ namespace MegghysAPI.Modules public long Id { get; set; } public PixivImgType Type { get; set; } public string Title { get; set; } - [JsonMap] public PixivRestrictInfo Restrict { get; set; } [Column(DbType = "text")] public string Description { get; set; } [JsonMap] public PixivAuthorInfo Author { get; set; } public bool R18 => Restrict != PixivRestrictInfo.Normal; - [JsonMap] + [JsonMap, Column(MapType = typeof(JArray))] public List Tags { get; set; } = []; - [JsonMap] + [JsonMap, Column(MapType = typeof(JArray))] public List URL { get; set; } = []; - [JsonMap] + [JsonMap, Column(MapType = typeof(JArray))] public List S3URL { get; set; } = []; public int Width { get; set; } public int Height { get; set; } diff --git a/Program.cs b/Program.cs index 532fbac..e0db13c 100644 --- a/Program.cs +++ b/Program.cs @@ -2,14 +2,14 @@ using System.Diagnostics; using System.Reflection; using MegghysAPI.Attributes; using MegghysAPI.Components; -using Microsoft.FluentUI.AspNetCore.Components; +using AntDesign; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); -builder.Services.AddFluentUIComponents(); +builder.Services.AddAntDesign(); builder.Services.AddControllers(); var app = builder.Build(); @@ -36,36 +36,48 @@ app.UseAntiforgery(); app.MapControllers(); -// AutoInitAttribute -// ȡǰAssembly +// 加载所有有 AutoInitAttribute 的类 +// 获取当前Assembly var inits = new List(); -Assembly.GetExecutingAssembly() - .GetTypes() - .ForEach(t => t.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) - .Where(m => m.GetCustomAttribute() is { }).ForEach(m => inits.Add(m))); -inits = [.. inits.OrderBy(m => m.GetCustomAttribute().Order)]; -inits.ForEach(m => +foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { - var sw = new Stopwatch(); - sw.Start(); - var attr = m.GetCustomAttribute(); - if (attr.LogMessage is not null) - Logs.Info(attr.LogMessage); - if (attr.Async) + foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) + .Where(m => m.GetCustomAttribute() is not null)) { - Task.Run(() => + inits.Add(method); + } +} + +DB.InitDB(); + +inits = inits + .OrderBy(m => m.GetCustomAttribute()?.Order ?? 0) + .ToList(); + +foreach (var method in inits) +{ + var sw = Stopwatch.StartNew(); + var attr = method.GetCustomAttribute(); + if (attr?.LogMessage is { } message) + { + Logs.Info(message); + } + + if (attr?.Async is true) + { + _ = Task.Run(() => { - m.Invoke(null, null); + method.Invoke(null, null); attr.PostInit?.Invoke(); - Logs.Info($"[{sw.ElapsedMilliseconds} ms] Async <{m.DeclaringType.Name}.{m.Name}> => Inited."); + Logs.Info($"[{sw.ElapsedMilliseconds} ms] Async <{method.DeclaringType?.Name}.{method.Name}> => Inited."); }); } else { - m.Invoke(null, null); - attr.PostInit?.Invoke(); - Logs.Info($"[{sw.ElapsedMilliseconds} ms] <{m.DeclaringType.Name}.{m.Name}> => Inited."); + method.Invoke(null, null); + attr?.PostInit?.Invoke(); + Logs.Info($"[{sw.ElapsedMilliseconds} ms] <{method.DeclaringType?.Name}.{method.Name}> => Inited."); } -}); +} app.Run(); diff --git a/wwwroot/app.css b/wwwroot/app.css index 469e373..aca5cff 100644 --- a/wwwroot/app.css +++ b/wwwroot/app.css @@ -1,80 +1,71 @@ -@import '/_content/Microsoft.FluentUI.AspNetCore.Components/css/reboot.css'; - -body { - --body-font: "Segoe UI Variable", "Segoe UI", sans-serif; - font-family: var(--body-font); - font-size: var(--type-ramp-base-font-size); - line-height: var(--type-ramp-base-line-height); - margin: 0; -} - body { margin: 0; padding: 0; - height: 100vh; - font-family: var(--body-font); - font-size: var(--type-ramp-base-font-size); - line-height: var(--type-ramp-base-line-height); - font-weight: var(--font-weight); - color: var(--neutral-foreground-rest); - background: var(--neutral-fill-layer-rest); + min-height: 100vh; + font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif; + background: #f0f2f5; + color: rgba(0, 0, 0, 0.85); } -.navmenu-icon { - display: none; +.app-layout { + min-height: 100vh; } -.main { - min-height: calc(100dvh - 86px); - color: var(--neutral-foreground-rest); - align-items: stretch !important; -} - -.body-content { - align-self: stretch; - height: calc(100dvh - 86px) !important; +.app-header { + background: #001529; display: flex; + align-items: center; + padding: 0 24px; + height: 64px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); +} + +.app-header-title { + color: #fff; + font-size: 20px; + font-weight: 600; +} + +.app-sider { + background: #001529; + min-height: calc(100vh - 64px); +} + +.app-menu { + height: 100%; + border-inline-end: none !important; +} + +.app-content { + padding: 24px; + background: #fff; + min-height: calc(100vh - 64px - 70px); } .content { - padding: 0.5rem 1.5rem; - align-self: stretch !important; - width: 100%; + min-height: 100%; } -.manage { - width: 100dvw; -} - -footer { - background: var(--neutral-layer-4); - color: var(--neutral-foreground-rest); +.app-footer { + display: flex; align-items: center; - padding: 10px 10px; + padding: 16px 24px; + background: #fff; + border-top: 1px solid #f0f0f0; + gap: 12px; } - footer a { - color: var(--neutral-foreground-rest); - text-decoration: none; - } - - footer a:focus { - outline: 1px dashed; - outline-offset: 3px; - } - - footer a:hover { - text-decoration: underline; - } - -.alert { - border: 1px dashed var(--accent-fill-rest); - padding: 5px; +.footer-spacer { + flex: 1; } +.weather-table { + background: #fff; +} #blazor-error-ui { - background: lightyellow; + background: #fffbe6; + border: 1px solid #ffe58f; bottom: 0; box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); display: none; @@ -83,121 +74,43 @@ footer { position: fixed; width: 100%; z-index: 1000; - margin: 20px 0; } - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} .blazor-error-boundary { - background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; - padding: 1rem 1rem 1rem 3.7rem; - color: white; + border: 1px solid #ff4d4f; + padding: 16px 24px; + border-radius: 4px; + background: #fff2f0; + color: #a8071a; } - .blazor-error-boundary::before { - content: "An error has occurred. " - } - -.loading-progress { - position: relative; - display: block; - width: 8rem; - height: 8rem; - margin: 20vh auto 1rem auto; +.blazor-error-boundary::before { + content: "An error has occurred. "; + font-weight: 600; } - .loading-progress circle { - fill: none; - stroke: #e0e0e0; - stroke-width: 0.6rem; - transform-origin: 50% 50%; - transform: rotate(-90deg); - } - - .loading-progress circle:last-child { - stroke: #1b6ec2; - stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; - transition: stroke-dasharray 0.05s ease-in-out; - } - -.loading-progress-text { - position: absolute; - text-align: center; - font-weight: bold; - inset: calc(20vh + 3.25rem) 0 auto 0.2rem; -} - - .loading-progress-text:after { - content: var(--blazor-load-percentage-text, "Loading"); - } - code { color: #c02d76; } -@media (max-width: 600px) { - .header-gutters { - margin: 0.5rem 3rem 0.5rem 1.5rem !important; +@media (max-width: 768px) { + .app-content { + padding: 16px; } - [dir="rtl"] .header-gutters { - margin: 0.5rem 1.5rem 0.5rem 3rem !important; + .app-footer { + flex-direction: column; + align-items: flex-start; } - .main { - flex-direction: column !important; - row-gap: 0 !important; - } - - nav.sitenav { - width: 100%; - height: 100%; - } - - #main-menu { - width: 100% !important; - } - - #main-menu > div:first-child:is(.expander) { - display: none; - } - - .navmenu { - width: 100%; - } - - #navmenu-toggle { - appearance: none; - } - - #navmenu-toggle ~ nav { - display: none; - } - - #navmenu-toggle:checked ~ nav { - display: block; - } - - .navmenu-icon { - cursor: pointer; - z-index: 10; - display: block; - position: absolute; - top: 15px; - left: unset; - right: 20px; - width: 20px; - height: 20px; - border: none; - } - - [dir="rtl"] .navmenu-icon { - left: 20px; - right: unset; + .footer-spacer { + display: none; } }