Improved readability and accessibility for CSS-less mode

This commit is contained in:
Bad Manners 2024-08-10 01:17:33 -03:00
parent 6dd8a92318
commit d529b043c6
14 changed files with 166 additions and 94 deletions

View file

@ -3,6 +3,7 @@ import { getImage } from "astro:assets";
import BaseLayout from "./BaseLayout.astro";
import Navigation from "../components/Navigation.astro";
import logoBM from "../assets/images/logo_bm.png";
import { t } from "../i18n";
type Props = {
pageTitle?: string;
@ -45,31 +46,34 @@ const copyrightYear = currentYear > FIRST_YEAR ? `${FIRST_YEAR}${currentYear}
<a class="hover:underline focus:underline" href="/licenses.txt" target="_blank">Licenses</a>
</div>
<div class="mt-2 flex items-center gap-x-1 pb-10">
<a class="text-link p-1" href="https://badmanners.xyz/" target="_blank" aria-label="Main website">
<svg viewBox="0 0 576 512" class="h-6 w-6 fill-current" aria-hidden="true">
<a class="text-link p-1" href="https://badmanners.xyz/" target="_blank" aria-labelled-by="label-main-website">
<svg width="1.5rem" height="1.5rem" viewBox="0 0 576 512" class="fill-current" aria-hidden>
<path
d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"
></path>
</svg>
<span id="label-main-website" class="hidden">Main website</span>
</a>
<a class="text-link p-1" href="/feed.xml" target="_blank" aria-label="RSS feed">
<svg viewBox="0 0 448 512" class="h-6 w-6 fill-current" aria-hidden="true">
<a class="text-link p-1" href="/feed.xml" target="_blank" aria-labelledby="label-rss-feed">
<svg width="1.5rem" height="1.5rem" viewBox="0 0 448 512" class="fill-current" aria-hidden>
<path
d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM96 136c0-13.3 10.7-24 24-24c137 0 248 111 248 248c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-110.5-89.5-200-200-200c-13.3 0-24-10.7-24-24zm0 96c0-13.3 10.7-24 24-24c83.9 0 152 68.1 152 152c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-57.4-46.6-104-104-104c-13.3 0-24-10.7-24-24zm0 120a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"
></path>
</svg>
<span id="label-rss-feed" class="hidden">RSS feed</span>
</a>
<button data-dark-mode class="text-link p-1" aria-label="Toggle dark mode">
<svg viewBox="0 0 512 512" class="hidden h-6 w-6 fill-current dark:block" aria-hidden="true">
<button data-dark-mode class="text-link hidden p-1" aria-labelledby="label-toggle-dark-mode" aria-hidden>
<svg width="1.5rem" height="1.5rem" viewBox="0 0 512 512" class="hidden fill-current dark:block" aria-hidden>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"
></path>
</svg>
<svg viewBox="0 0 512 512" class="block h-6 w-6 fill-current dark:hidden" aria-hidden="true">
<svg width="1.5rem" height="1.5rem" viewBox="0 0 512 512" class="block fill-current dark:hidden" aria-hidden>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
></path>
</svg>
<span id="label-toggle-dark-mode" class="hidden">{t("en", "published_content/toggle_dark_mode")}</span>
</button>
</div>
</div>

View file

@ -10,14 +10,12 @@ import CopyrightedCharacters from "../components/CopyrightedCharacters.astro";
import Prose from "../components/Prose.astro";
import MastodonComments from "../components/MastodonComments.astro";
import UserComponent from "../components/UserComponent.astro";
import { formatCopyrightedCharacters } from "../utils/format_copyrighted_characters";
type Props = CollectionEntry<"games">["data"];
const { props } = Astro;
const series = props.series && (await getEntry(props.series));
const authorsList = await getEntries(props.authors);
const copyrightedCharacters = await formatCopyrightedCharacters(props.copyrightedCharacters);
const relatedStories = (await getEntries(props.relatedStories)).filter((story) => !story.data.isDraft);
const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft);
const categorizedTags = Object.fromEntries(
@ -75,45 +73,62 @@ const thumbnail =
<div
class="pointer-events-auto sticky top-6 flex rounded-full bg-white px-1 py-1 shadow-md dark:bg-black print:hidden"
>
<a
href={series ? series.data.url : "/games"}
class="text-link my-1 h-9 w-9 p-2"
aria-label={series
? t(props.lang, "published_content/return_to_series", series.data.name)
: t(props.lang, "game/return_to_games")}
>
<svg viewBox="0 0 512 512" class="fill-current" aria-hidden="true">
<a href={series ? series.data.url : "/games"} class="text-link my-1 p-2" aria-labelled-by="label-return-to">
<svg width="1.25rem" height="1.25rem" viewBox="0 0 512 512" class="fill-current" aria-hidden>
<path
d="M48.5 224H40c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H48.5z"
></path>
</svg>
<span class="hidden" id="label-return-to">
{
series
? t(props.lang, "published_content/return_to_series", series.data.name)
: t(props.lang, "game/return_to_games")
}
</span>
</a>
<a
href="#description"
class="text-link my-1 h-9 w-9 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/go_to_description")}
class="text-link my-1 border-l border-stone-300 p-2 dark:border-stone-700"
aria-labelled-by="label-go-to-description"
>
<svg viewBox="0 0 512 512" class="fill-current" aria-hidden="true">
<svg width="1.25rem" height="1.25rem" viewBox="0 0 512 512" class="fill-current" aria-hidden>
<path
d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"
></path>
</svg>
<span class="hidden" id="label-go-to-description">{t(props.lang, "published_content/go_to_description")}</span
>
</a>
<button
data-dark-mode
class="text-link my-1 h-9 w-9 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/toggle_dark_mode")}
class="text-link my-1 hidden border-l border-stone-300 p-2 dark:border-stone-700"
aria-labelled-by="label-toggle-dark-mode"
aria-hidden
>
<svg viewBox="0 0 512 512" class="hidden fill-current dark:block" aria-hidden="true">
<svg
width="1.25rem"
height="1.25rem"
viewBox="0 0 512 512"
class="hidden fill-current dark:block"
aria-hidden
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"
></path>
</svg>
<svg viewBox="0 0 512 512" class="block fill-current dark:hidden" aria-hidden="true">
<svg
width="1.25rem"
height="1.25rem"
viewBox="0 0 512 512"
class="block fill-current dark:hidden"
aria-hidden
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
></path>
</svg>
<span class="hidden" id="label-toggle-dark-mode">{t(props.lang, "published_content/toggle_dark_mode")}</span>
</button>
</div>
</div>
@ -132,6 +147,7 @@ const thumbnail =
<section
id="game-information"
class="mt-1 space-y-2 px-2 font-serif font-light italic text-stone-600 dark:text-stone-200"
aria-label={t(props.lang, "game/information_aria_label")}
>
<Authors lang={props.lang}>
{authorsList.map((author) => <UserComponent user={author} lang={props.lang} />)}
@ -206,12 +222,12 @@ const thumbnail =
</h2>
<Prose>
<Markdown of={props.description} />
<CopyrightedCharacters copyrightedCharacters={copyrightedCharacters} lang={props.lang} />
<CopyrightedCharacters copyrightedCharacters={props.copyrightedCharacters} lang={props.lang} />
</Prose>
</section>
<div class="pr-3 text-right print:hidden">
<a href="#top" class="text-link inline-flex items-center underline"
><svg class="mr-1 h-6 w-6 fill-current" viewBox="0 0 384 512" aria-hidden="true"
><svg width="1.25rem" height="1.25rem" class="mr-1 fill-current" viewBox="0 0 384 512" aria-hidden
><path
d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"
></path></svg
@ -274,7 +290,10 @@ const thumbnail =
}
{props.posts.mastodon ? <MastodonComments lang={props.lang} {...props.posts.mastodon} /> : null}
</main>
<div class="pt-6 text-center text-xs text-black dark:text-white">
<div
class="pt-6 text-center text-xs text-black dark:text-white"
aria-label={t(props.lang, "published_content/copyright_aria_label")}
>
<span>{t(props.lang, "published_content/copyright_year", (props.pubDate || new Date()).getFullYear())} | </span>
<a class="hover:underline focus:underline" href="/licenses.txt" target="_blank"
>{t(props.lang, "published_content/licenses")}</a

View file

@ -12,7 +12,6 @@ import UserComponent from "../components/UserComponent.astro";
import CopyrightedCharacters from "../components/CopyrightedCharacters.astro";
import Prose from "../components/Prose.astro";
import MastodonComments from "../components/MastodonComments.astro";
import { formatCopyrightedCharacters } from "../utils/format_copyrighted_characters";
type Props = CollectionEntry<"stories">["data"];
@ -23,7 +22,6 @@ const series = props.series && (await getEntry(props.series));
const authorsList = await getEntries(props.authors);
const commissionersList = props.commissioner && (await getEntries(props.commissioner));
const requestersList = props.requester && (await getEntries(props.requester));
const copyrightedCharacters = await formatCopyrightedCharacters(props.copyrightedCharacters);
const relatedStories = (await getEntries(props.relatedStories)).filter((story) => !story.data.isDraft);
const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft);
const categorizedTags = Object.fromEntries(
@ -82,45 +80,62 @@ const wordCount = props.wordCount?.toString();
<div
class="pointer-events-auto sticky top-6 flex rounded-full bg-white px-1 py-1 shadow-md dark:bg-black print:hidden"
>
<a
href={series ? series.data.url : "/stories/1"}
class="text-link my-1 h-9 w-9 p-2"
aria-label={series
? t(props.lang, "published_content/return_to_series", series.data.name)
: t(props.lang, "story/return_to_stories")}
>
<svg viewBox="0 0 512 512" class="fill-current" aria-hidden="true">
<a href={series ? series.data.url : "/stories/1"} class="text-link my-1 p-2" aria-labelled-by="label-return-to">
<svg width="1.25rem" height="1.25rem" viewBox="0 0 512 512" class="fill-current" aria-hidden>
<path
d="M48.5 224H40c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H48.5z"
></path>
</svg>
<span class="hidden" id="label-return-to"
>{
series
? t(props.lang, "published_content/return_to_series", series.data.name)
: t(props.lang, "story/return_to_stories")
}</span
>
</a>
<a
href="#description"
class="text-link my-1 h-9 w-9 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/go_to_description")}
class="text-link my-1 border-l border-stone-300 p-2 dark:border-stone-700"
aria-labelled-by="label-go-to-description"
>
<svg viewBox="0 0 512 512" class="fill-current" aria-hidden="true">
<svg width="1.25rem" height="1.25rem" viewBox="0 0 512 512" class="fill-current" aria-hidden>
<path
d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"
></path>
</svg>
<span class="hidden" id="label-go-to-description">{t(props.lang, "published_content/go_to_description")}</span
>
</a>
<button
data-dark-mode
class="text-link my-1 h-9 w-9 border-l border-stone-300 p-2 dark:border-stone-700"
aria-label={t(props.lang, "published_content/toggle_dark_mode")}
class="text-link my-1 hidden border-l border-stone-300 p-2 dark:border-stone-700"
aria-labelled-by="label-toggle-dark-mode"
aria-hidden
>
<svg viewBox="0 0 512 512" class="hidden fill-current dark:block" aria-hidden="true">
<svg
width="1.25rem"
height="1.25rem"
viewBox="0 0 512 512"
class="hidden fill-current dark:block"
aria-hidden
>
<path
d="M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"
></path>
</svg>
<svg viewBox="0 0 512 512" class="block fill-current dark:hidden" aria-hidden="true">
<svg
width="1.25rem"
height="1.25rem"
viewBox="0 0 512 512"
class="block fill-current dark:hidden"
aria-hidden
>
<path
d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"
></path>
</svg>
<span class="hidden" id="label-toggle-dark-mode">{t(props.lang, "published_content/toggle_dark_mode")}</span>
</button>
</div>
</div>
@ -133,31 +148,33 @@ const wordCount = props.wordCount?.toString();
(prev && !prev.data.isDraft) || (next && !next.data.isDraft) ? (
<div class="print:hidden">
<div id="story-nav-top" class="my-4 grid grid-cols-2 justify-items-stretch gap-2">
{prev ? (
{prev && !prev.data.isDraft ? (
<a
href={`/stories/${prev.slug}`}
class="text-link flex items-center justify-center border-r border-stone-400 px-1 py-3 font-light underline dark:border-stone-600"
aria-label={t(props.lang, "story/previous_story_aria_label")}
>
<svg class="mr-1 h-5 w-5 fill-current" viewBox="0 0 320 512">
<svg width="1.25rem" height="1.25rem" class="mr-1 fill-current" viewBox="0 0 320 512" aria-hidden>
<path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z" />
</svg>
<span>Previous: {prev.data.shortTitle || prev.data.title}</span>
<span>{t(props.lang, "story/previous_story", prev.data.shortTitle || prev.data.title)}</span>
</a>
) : (
<div class="h-full border-r border-stone-400 dark:border-stone-600" />
<div class="h-full border-r border-stone-400 dark:border-stone-600" aria-hidden />
)}
{next ? (
{next && !next.data.isDraft ? (
<a
href={`/stories/${next.slug}`}
class="text-link flex items-center justify-center px-1 py-3 font-light underline"
aria-label={t(props.lang, "story/next_story_aria_label")}
>
<span>Next: {next.data.shortTitle || next.data.title}</span>
<svg class="ml-1 h-5 w-5 fill-current" viewBox="0 0 320 512">
<span>{t(props.lang, "story/next_story", next.data.shortTitle || next.data.title)}</span>
<svg width="1.25rem" height="1.25rem" class="ml-1 fill-current" viewBox="0 0 320 512" aria-hidden>
<path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" />
</svg>
</a>
) : (
<div />
<div aria-hidden />
)}
</div>
<hr class="mx-auto mb-5 w-full max-w-2xl border-stone-400 dark:border-stone-600" />
@ -174,6 +191,7 @@ const wordCount = props.wordCount?.toString();
<section
id="story-information"
class="mt-1 space-y-2 px-2 font-serif font-light italic text-stone-600 dark:text-stone-200"
aria-label={t(props.lang, "story/information_aria_label")}
>
<Authors lang={props.lang}>
{authorsList.map((author) => <UserComponent user={author} lang={props.lang} />)}
@ -260,7 +278,7 @@ const wordCount = props.wordCount?.toString();
</h2>
<Prose>
<Markdown of={props.description} />
<CopyrightedCharacters copyrightedCharacters={copyrightedCharacters} lang={props.lang} />
<CopyrightedCharacters copyrightedCharacters={props.copyrightedCharacters} lang={props.lang} />
</Prose>
</section>
{
@ -283,12 +301,12 @@ const wordCount = props.wordCount?.toString();
) : null
}
<div class="pr-3 text-right print:hidden">
<a href="#top" class="text-link inline-flex items-center underline"
><svg class="mr-1 h-6 w-6 fill-current" viewBox="0 0 384 512" aria-hidden="true"
<a href="#top" class="text-link inline-flex items-center underline" aria-labelledby="label-to-top"
><svg width="1.25rem" height="1.25rem" class="mr-1 fill-current" viewBox="0 0 384 512" aria-hidden
><path
d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"
></path></svg
><span>{t(props.lang, "published_content/to_top")}</span></a
><span id="label-to-top">{t(props.lang, "published_content/to_top")}</span></a
>
</div>
{
@ -300,11 +318,12 @@ const wordCount = props.wordCount?.toString();
<a
href={`/stories/${prev.slug}`}
class="text-link flex items-center justify-center border-r border-stone-400 px-1 py-3 font-light underline dark:border-stone-600"
aria-label={t(props.lang, "story/previous_story_aria_label")}
>
<svg class="mr-1 h-5 w-5 fill-current" viewBox="0 0 320 512">
<svg width="1.25rem" height="1.25rem" class="mr-1 fill-current" viewBox="0 0 320 512" aria-hidden>
<path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z" />
</svg>
<span>Previous: {prev.data.shortTitle || prev.data.title}</span>
<span>{t(props.lang, "story/previous_story", prev.data.shortTitle || prev.data.title)}</span>
</a>
) : (
<div class="h-full border-r border-stone-400 dark:border-stone-600" />
@ -313,9 +332,10 @@ const wordCount = props.wordCount?.toString();
<a
href={`/stories/${next.slug}`}
class="text-link flex items-center justify-center px-1 py-3 font-light underline"
aria-label={t(props.lang, "story/next_story_aria_label")}
>
<span>Next: {next.data.shortTitle || next.data.title}</span>
<svg class="ml-1 h-5 w-5 fill-current" viewBox="0 0 320 512">
<span>{t(props.lang, "story/next_story", next.data.shortTitle || next.data.title)}</span>
<svg width="1.25rem" height="1.25rem" class="ml-1 fill-current" viewBox="0 0 320 512" aria-hidden>
<path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" />
</svg>
</a>
@ -383,7 +403,10 @@ const wordCount = props.wordCount?.toString();
}
{props.posts.mastodon ? <MastodonComments lang={props.lang} {...props.posts.mastodon} /> : null}
</main>
<div class="pt-6 text-center text-xs text-black dark:text-white">
<div
class="pt-6 text-center text-xs text-black dark:text-white"
aria-label={t(props.lang, "published_content/copyright_aria_label")}
>
<span>{t(props.lang, "published_content/copyright_year", (props.pubDate || new Date()).getFullYear())} | </span>
<a class="hover:underline focus:underline" href="/licenses.txt" target="_blank"
>{t(props.lang, "published_content/licenses")}</a