Improve accessibility and polish page styling
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 11m31s

This commit is contained in:
2026-10-24 14:11:17 +05:00
parent 060e8f27ef
commit 927923dc95
34 changed files with 99 additions and 48 deletions

View File

@@ -6,7 +6,7 @@ export default async function About() {
return (
<>
<Header />
<main className="section page-content prose">
<main className="section page-content prose" id="main-content" tabIndex={-1}>
<span className="eyebrow">{t("THE EXPLORER’S FIELD GUIDE")}</span>
<h1>
{t("You know this place.")}

View File

@@ -9,7 +9,7 @@ export default async function AdminPage() {
return (
<>
<Header />
<main className="section page-content moderation-page">
<main className="section page-content moderation-page" id="main-content" tabIndex={-1}>
<span className="eyebrow">MINEGEO ADMIN</span>
<h1>{t("Admin Tools.")}</h1>
<p className="lead">

View File

@@ -30,7 +30,7 @@ export default async function ResetPassword() {
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<section className="auth-card reset-card">
<span className="eyebrow">{t("ACCOUNT RECOVERY")}</span>
<h1>{t("A fresh start.")}</h1>

View File

@@ -12,7 +12,7 @@ export default async function AppealPage() {
return (
<>
<Header />
<main className={`section page-content ${styles.page}`}>
<main className={`section page-content ${styles.page}`} id="main-content" tabIndex={-1}>
<span className="eyebrow">MINEGEO</span>
<h1>{ru ? "Доступ и апелляции." : "Account access & appeals."}</h1>
{account ? (

View File

@@ -28,7 +28,7 @@ export default async function ChangelogsPage({
return (
<>
<Header />
<main className="section page-content changelog-page">
<main className="section page-content changelog-page" id="main-content" tabIndex={-1}>
{!before && <ChangelogRefresh />}
<span className="eyebrow">{t("WHAT'S NEW")}</span>
<h1>{t("Changelogs")}</h1>

View File

@@ -18,7 +18,7 @@ export default async function Draft({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<span className="eyebrow">{t("YOUR WORLD · YOUR LOCATIONS")}</span>
<h1>{t("Map workshop")}</h1>
<DraftEditor id={id} hostName={profile.display_name} />

View File

@@ -28,7 +28,7 @@ export default async function DashboardPage() {
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
{account ? (
<>
<span className="eyebrow">{t("THE CARTOGRAPHER’S DESK")}</span>

View File

@@ -14,7 +14,7 @@ export default async function DeveloperApiPage() {
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<DeveloperPanel signedIn={Boolean(account)} />
</main>
<Footer />

View File

@@ -93,7 +93,7 @@ export default async function Docs({
return (
<>
<Header />
<main className={`section page-content ${styles.layout}`}>
<main className={`section page-content ${styles.layout}`} id="main-content" tabIndex={-1}>
<aside>
<h2>Player docs</h2>
<nav aria-label="Documentation pages" className={styles.menu}>

View File

@@ -14,8 +14,8 @@ export default async function Downloads() {
return (
<>
<Header />
<main className="section page-content">
<article className="tool-card" style={{ marginBottom: 40 }}>
<main className="section page-content" id="main-content" tabIndex={-1}>
<article className="tool-card desktop-download-card">
<span className="eyebrow">{t("MINEGEO DESKTOP")}</span>
<h2>{t("Your next expedition, on your desktop.")}</h2>
<p className="muted">
@@ -26,7 +26,7 @@ export default async function Downloads() {
<a className="button primary" href={desktopRelease.file} download>
<Download size={16} /> {t("Download for Windows")}
</a>
<p className="muted" style={{ marginTop: 16 }}>
<p className="muted desktop-download-version">
{t(
"Windows 10/11 · 64-bit · Version {version} · Internet required",
{ version: desktopRelease.version },
@@ -87,10 +87,9 @@ export default async function Downloads() {
) ? (
<a
key={version}
className="button primary"
className="button primary download-build-link"
href={`/tools/mod/minegeo-fabric-${version}-${release}.jar`}
download
style={{ marginRight: 8, marginBottom: 8 }}
>
<Download size={16} /> {t("Download Fabric mod")} · {version}
</a>
@@ -100,7 +99,7 @@ export default async function Downloads() {
</p>
),
)}
<p className="muted" style={{ fontSize: 11, marginTop: 20 }}>
<p className="muted tool-card-note tool-card-note-spaced">
{t(
"Install the JAR in your Minecraft mods folder alongside Fabric API.",
)}
@@ -156,7 +155,7 @@ export default async function Downloads() {
". The manifest appears when export finishes. Upload sends the latest completed export; it does not capture the world.",
)}
</p>
<p className="muted" style={{ fontSize: 11 }}>
<p className="muted tool-card-note">
{t(
"Put the JAR in plugins/ and restart. Set server-name and server-address in plugins/MineGeo/config.yml, then run /minegeo reload. Permission: minegeo.admin. The same plugin JAR supports all three versions.",
)}

View File

@@ -4,7 +4,7 @@ import { useI18n } from "@/components/I18nProvider";
export default function ErrorPage({ retry }: { retry: () => void }) {
const { t } = useI18n();
return (
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<h1>{t("Lost connection.")}</h1>
<p>
{t(

View File

@@ -26,7 +26,12 @@ body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: Arial, Helvetica, sans-serif;
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
font-size: 14px;
line-height: 1.6;
}
@@ -50,7 +55,7 @@ button {
cursor: pointer;
}
button:disabled {
cursor: wait;
cursor: not-allowed;
opacity: 0.6;
}
::selection {

View File

@@ -44,16 +44,17 @@ export default async function RootLayout({
}: {
children: React.ReactNode;
}) {
const [{ locale, preference, detectedLocale }, settings] = await Promise.all([
getI18n(),
initialSiteSettings(),
]);
const [{ locale, preference, detectedLocale, t }, settings] =
await Promise.all([getI18n(), initialSiteSettings()]);
return (
<html lang={locale} data-theme="dark" suppressHydrationWarning>
<head>
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
</head>
<body>
<a className="skip-link" href="#main-content">
{t("Skip to content")}
</a>
<I18nProvider
locale={locale}
preference={preference}

View File

@@ -6,6 +6,8 @@ export default async function LoadingLeaderboard() {
className="section page-content leaderboard-page"
aria-busy="true"
aria-label={t("Loading leaderboard")}
id="main-content"
tabIndex={-1}
>
<span className="eyebrow">{t("THE EXPLORERS’ BOARD")}</span>
<h1>{t("Every block counts.")}</h1>

View File

@@ -42,7 +42,7 @@ export default async function LeaderboardPage({
return (
<>
<Header />
<main className="section page-content leaderboard-page" id="main-content">
<main className="section page-content leaderboard-page" id="main-content" tabIndex={-1}>
<Link href="/" className="text-link leaderboard-back">
<ArrowLeft size={14} /> {t("Back to home")}
</Link>

View File

@@ -22,7 +22,7 @@ export default async function LogIn({
return (
<>
<Header />
<main className="section page-content auth-page">
<main className="section page-content auth-page" id="main-content" tabIndex={-1}>
<SignIn
next={next}
initialError={

View File

@@ -10,7 +10,7 @@ export default async function Review() {
return (
<>
<Header />
<main className="section page-content moderation-page">
<main className="section page-content moderation-page" id="main-content" tabIndex={-1}>
<span className="eyebrow">{t("THE COMMUNITY’S COMPASS")}</span>
<h1>{t("Moderation Tools.")}</h1>
<p className="lead">

View File

@@ -3,7 +3,7 @@ import Link from "next/link";
export default async function NotFound() {
const { t } = await getI18n();
return (
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<span className="eyebrow">{t("UNKNOWN COORDINATES")}</span>
<h1>{t("Uncharted territory.")}</h1>
<p>{t("This map or page isn’t available.")}</p>

View File

@@ -30,10 +30,10 @@ export default async function Home() {
<>
<FirstVisitIntro />
<Header />
<main className="home-page" id="main-content">
<main className="home-page" id="main-content" tabIndex={-1}>
<section className="hero">
<div className="hero-copy">
<div className="status-label">{t("A MINECRAFT GUESSING GAME")}</div>
<div className="status-label">{t("A Minecraft guessing game")}</div>
<h1>
{t("Guess where you are")}
<br />
@@ -131,8 +131,8 @@ export default async function Home() {
<section className="section catalog-section">
<div className="section-heading">
<div>
<span className="eyebrow">{t("COMMUNITY MAPS")}</span>
<h2>{t("Where will you go today?")}</h2>
<span className="eyebrow">{t("Community maps")}</span>
<h2>{t("Explore community worlds.")}</h2>
</div>
<Link className="text-link" href="/servers">
{t("All maps ({count})", { count: maps.length })}{" "}
@@ -196,7 +196,7 @@ export default async function Home() {
</Suspense>
<section className="section home-panels">
<article className="home-panel">
<span className="eyebrow">{t("HOW TO PLAY")}</span>
<span className="eyebrow">{t("How to play")}</span>
<h2>{t("Know your blocks?")}</h2>
<ol className="play-steps">
<li>
@@ -234,8 +234,8 @@ export default async function Home() {
</Link>
</article>
<article className="home-panel">
<span className="eyebrow">{t("CHOOSE YOUR CHALLENGE")}</span>
<h2>{t("Find your challenge.")}</h2>
<span className="eyebrow">{t("Choose a difficulty")}</span>
<h2>{t("Pick a difficulty.")}</h2>
<div className="mode-list">
{[
{
@@ -287,8 +287,8 @@ export default async function Home() {
<section className="section contribute-banner">
<Blocks size={38} />
<div>
<span className="eyebrow">{t("BUILT BY THE COMMUNITY")}</span>
<h2>{t("Your world deserves to be explored.")}</h2>
<span className="eyebrow">{t("Made by MineGeo players")}</span>
<h2>{t("Put your world on the map.")}</h2>
<p>
{t("Share your builds and your favorite corners of Minecraft.")}
</p>

View File

@@ -14,7 +14,7 @@ export default async function Pair({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
{!account ? (
<>
<p className="muted">

View File

@@ -1,4 +1,21 @@
/* Responsive corrections shared by both languages. */
.skip-link {
position: fixed;
inset-block-start: 12px;
inset-inline-start: 12px;
z-index: 1000;
padding: 10px 14px;
transform: translateY(calc(-100% - 16px));
border: 1px solid var(--line);
border-radius: var(--radius-control);
color: var(--text);
background: var(--panel);
box-shadow: 0 4px 14px #03060a55;
white-space: nowrap;
}
.skip-link:focus-visible {
transform: translateY(0);
}
.language-switcher {
display: inline-flex;
align-items: center;
@@ -107,6 +124,22 @@ html[lang="ru"] .mode-row h3 span {
display: flex;
flex-direction: column;
}
.desktop-download-card {
margin-bottom: 40px;
}
.desktop-download-version {
margin-top: 16px;
}
.download-build-link {
margin-inline-end: 8px;
margin-block-end: 8px;
}
.tool-card-note {
font-size: 11px;
}
.tool-card-note-spaced {
margin-top: 20px;
}
.tool-card pre,
.token-box code {
max-width: 100%;

View File

@@ -8,7 +8,7 @@ export default async function ResultPage({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<Results id={(await params).id} />
</main>
<Footer />

View File

@@ -9,7 +9,7 @@
--text: #eef1f4;
--board-stone: #1a222c;
--board-edge: #35404c;
--radius-panel: 16px;
--radius-panel: 12px;
--radius-control: 9px;
}
body {

View File

@@ -33,7 +33,7 @@ export default async function ServerPage({
return (
<>
<Header />
<main className="section page-content map-detail-page">
<main className="section page-content map-detail-page" id="main-content" tabIndex={-1}>
<Link className="map-back-link" href="/servers">
<ArrowLeft size={16} aria-hidden="true" />
{t("All worlds")}

View File

@@ -10,7 +10,7 @@ export default async function Servers() {
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<span className="eyebrow">
{t("THE COMMUNITY AT YOUR COORDINATES")}
</span>

View File

@@ -35,7 +35,7 @@ export default async function Settings({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<Link
className="text-link"
href={active ? "/dashboard" : "/ban/appeal"}

View File

@@ -13,7 +13,7 @@ export default async function Report({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<SupportConversation key={id} id={id} />
</main>
<Footer />

View File

@@ -18,7 +18,7 @@ export default async function Support({
return (
<>
<Header />
<main className="section page-content">
<main className="section page-content" id="main-content" tabIndex={-1}>
<SupportInbox pagePath={pagePath} />
</main>
<Footer />

View File

@@ -15,7 +15,7 @@ export default async function TournamentPage({
return (
<>
<Header />
<main id="main-content">
<main id="main-content" tabIndex={-1}>
<TournamentLobby id={id} signedIn={!!account} />
</main>
<Footer />

View File

@@ -14,7 +14,7 @@ export default async function TournamentsPage({
return (
<>
<Header />
<main id="main-content">
<main id="main-content" tabIndex={-1}>
<TournamentIndex signedIn={!!account} initialMapId={initialMapId} />
</main>
<Footer />