Compare commits

..

3 Commits
🎨 ... jxl

Author SHA1 Message Date
rhiannon morris 84f822f73b <picture> elements for jxls 2023-01-17 18:45:12 +01:00
rhiannon morris 0f20753808 generate jxl from png,jpg,gif 2023-01-15 22:40:00 +01:00
rhiannon morris 76ccbe3c7d styles for chatlogs etc 2023-01-15 21:38:43 +01:00
15 changed files with 257 additions and 199 deletions

View File

@ -66,14 +66,9 @@ $(TMPDIR)/%_big.jpg: $(DATADIR)/%.jpg
$(call resize,$(BIG),$(BIG),>)
$(TMPDIR)/%_small.webp: $(DATADIR)/%.webp
$(call resize,$(SMALL),$(SMALL),^,-gravity center -crop 1:1+0)
$(TMPDIR)/%_med.webp: $(DATADIR)/%.webp
$(call resize,$(MEDW),$(MEDH),>)
$(TMPDIR)/%_big.webp: $(DATADIR)/%.webp
$(call resize,$(BIG),$(BIG),>)
%.jxl: %.png ; $(call cjxl,-e 9)
%.jxl: %.jpg ; $(call cjxl,-e 9)
%.jxl: %.gif ; $(call cjxl)
$(MAKEPAGES): make-pages/*.hs make-pages/make-pages.cabal
@ -143,6 +138,14 @@ mkdir -p "$(dir $@)"
convert -resize "$(1)x$(2)$(3)" $(4) "$^" "$@"
endef
# args:
# 1. extra flags
define cjxl
echo "[cjxl] "$@
mkdir -p "$(dir $@)"
cjxl -d 1 "$^" "$@" $(1) 2>/dev/null
endef
# no args
define depend-gallery
echo "[deps] "$@

View File

@ -1,7 +1,7 @@
module Date
(Date (..),
Day (..), dayNum, exact,
formatLong, formatShort, formatRSS, formatSlash, formatTooltip,
formatLong, formatShort, formatRSS, formatSlash,
parseP, parseS, parseA)
where
@ -9,7 +9,7 @@ import Control.Applicative
import qualified Text.ParserCombinators.ReadP as ReadP
import Text.ParserCombinators.ReadP (ReadP, readS_to_P, readP_to_S, (<++))
import Data.Time hiding (Day)
import Data.Char (isSpace, toLower)
import Data.Char (isSpace)
import BuilderQQ
import Data.Function (on)
import Data.Maybe (fromMaybe)
@ -60,15 +60,6 @@ formatShort (Date {month, day}) = [b|$day'$month'|] where
Unknown -> ""
month' = formatTime defaultTimeLocale "%b" $ fromGregorian 1 month 1
formatTooltip :: Date -> Builder
formatTooltip (Date {year, month, day}) = [b|$day'$month' $year|] where
day' = case day of
Exact d -> [b|$d $&|]
Approx d -> [b|$d? $&|]
Unknown -> ""
month' = map toLower $
formatTime defaultTimeLocale "%b" $ fromGregorian 1 month 1
formatRSS :: Date -> Builder
formatRSS = fromString . format . toTime where
format = formatTime defaultTimeLocale "%a, %d %b %_Y %T GMT"

View File

@ -29,17 +29,22 @@ dependSingle' yamlDir indexFile info prefix build nsfw =
where
images = #all if nsfw then #images info else #sfwImages info
paths = map #path images
paths = map #path images
thumb = thumbFile $ thumbnail info
jxls fs = [base <.> "jxl" | f <- fs,
let (base, ext) = splitExtension f,
ext `elem` imgTypes]
imgTypes = words ".png .jpg .gif"
imgFiles0 = thumb : map pageFile paths ++ map bigFile paths
imgFiles = imgFiles0 ++ jxls imgFiles0
dls = mapMaybe #download images
extras = #extras info
dir = build </> prefix </> yamlDir
page = dir </> "index.html"
deps = unwords $ map (dir </>) $
thumbFile (thumbnail info) :
map pageFile paths ++
map bigFile paths ++
dls ++ extras
deps = unwords $ map (dir </>) $ imgFiles ++ dls ++ extras
dependGallery :: GalleryInfo
-> FilePath -- ^ index file

View File

@ -12,10 +12,10 @@ import Data.Function (on, (&))
import qualified Data.HashMap.Strict as HashMap
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
import Data.List (intersperse, groupBy, sortBy, sort)
import Data.List (intersperse, groupBy, sortBy, sortOn)
import Data.Maybe
import qualified Data.Text.Lazy as Lazy
import System.FilePath (takeDirectory, joinPath, splitPath)
import System.FilePath (takeDirectory, joinPath, splitPath, (-<.>))
import GHC.Exts (Down (..), the)
make :: Text -> GalleryInfo -> [(FilePath, Info)] -> Lazy.Text
@ -52,8 +52,9 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
<div class=page>
<header>
<h1>$title</h1>
<a class="right corner" href=rss.xml>rss</a>
<a class="left corner" href=$undir>back</a>
<h2 class="right corner">
<a href=rss.xml>rss</a>
</h2>
</header>
<nav id=filters>
@ -85,6 +86,10 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
$6.items
</ul>
</main>
<footer>
<a href=$undir>all galleries</a>
</footer>
</div>
|]
where
@ -105,7 +110,7 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
allTags = infos
& concatMap (map (,1) . tagsFor nsfw . #second)
& HashMap.fromListWith (+) & HashMap.toList
& sort
& sortOn (\(tag, count) -> (Down count, tag))
requireFilters = map (uncurry $ makeFilter "require" mempty) allTags
excludeFilters = map (uncurry $ makeFilter "exclude" hidden) allTags
@ -148,25 +153,30 @@ makeYearItems nsfw year infos = [b|@0
makeItem :: Bool -> FilePath -> Info -> Builder
makeItem nsfw file info@(Info {bg}) = [b|@0
<li class="item post$nsfw'" data-year=$year' data-updated="$updated'"
<li class="item post$nsfw'" data-date="$date'" data-year=$year'
data-updated="$updated'"
data-tags="$tags'">
<a href="$dir">
<img src="$thumb" loading=lazy$bgStyle
width=200 height=200
title="$tooltip">
</a>
<figure>
<a href="$dir">
<picture>
<source srcset="$thumbJxl" type=image/jxl>
<img src="$thumb" loading=lazy$bgStyle>
</picture>
</a>
<figcaption>
<span class=date>$date'</span>
<span class=title>$title</span>
</figcaption>
</figure>
|]
where
title = fromMaybe (#title info) $ #galleryTitle info
dir = takeDirectory file
thumb = getThumb dir info
thumb = getThumb dir info; thumbJxl = thumb -<.> "jxl"
nsfw' = if nsfw && #anyNsfw info then [b| nsfw|] else ""
tags' = fold $ intersperse ";" $ map fromText $ tagsFor nsfw info
date = #latestDate info nsfw
date' = formatTooltip date
date' = formatShort date
year' = #year date
updated' = if #updated info nsfw then [b|true|] else [b|false|]
bgStyle = case bg of Other col -> [b| style="background: $col"|]; _ -> ""
tooltip =
let upd = if #updated info nsfw then "updated " else "" :: Builder in
[b|$title ($upd$date')|]
bgStyle = ifJust bg \col -> [b| style="background: $col"|]

View File

@ -1,12 +1,9 @@
{-# OPTIONS_GHC -fdefer-typed-holes #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Info
(Info (..),
tagsFor, descFor, imagesFor, linksFor, updatesFor, lastUpdate,
compareFor, sortFor,
tagsFor, descFor, imagesFor, linksFor, updatesFor, compareFor, sortFor,
Artist (..), Images' (..), Images, Image (..), Desc (..), DescField (..),
Link (..), Update (..), Bg (..),
Link (..), Update (..),
GalleryInfo (..), GalleryFilters (..), ArtistFilter (..), NsfwFilter (..),
IndexInfo (..),
readArtistFilter, matchArtist, readNsfwFilter, matchNsfw, matchFilters,
@ -36,7 +33,7 @@ import Data.Text (Text)
import qualified Data.Text as Text
import Data.YAML (FromYAML (..), (.:), (.:?), (.!=))
import qualified Data.YAML as YAML
import System.FilePath ((</>), takeBaseName, takeExtension, splitExtension)
import System.FilePath ((</>), takeBaseName, takeExtension, splitExtensions)
import Data.Bifunctor (second)
@ -60,7 +57,7 @@ data Info =
nsfwTags :: ![Text],
desc :: !Desc,
nsfwDesc :: !Desc,
bg :: !Bg,
bg :: !(Maybe Text),
images :: !Images,
thumb' :: !(Maybe FilePath),
links :: ![Link],
@ -68,9 +65,6 @@ data Info =
}
deriving (Eq, Show)
data Bg = Default | NoBorder | Other !Text
deriving (Eq, Show)
data Desc =
NoDesc
| TextDesc !Text
@ -220,10 +214,6 @@ linksFor nsfw = if nsfw then #links else #sfwLinks
updatesFor :: Bool -> Info -> [(Date, [Update])]
updatesFor nsfw = if nsfw then #updates else #sfwUpdates
lastUpdate :: Bool -> Info -> Maybe Date
lastUpdate nsfw info =
case updatesFor nsfw info of [] -> Nothing; us -> Just $ fst $ last us
compareFor :: Bool -> Info -> Info -> Ordering
compareFor nsfw = comparing \i -> (#latestDate i nsfw, #sortEx i, #title i)
@ -254,7 +244,7 @@ bigFile f
addSuffix :: String -> FilePath -> FilePath
addSuffix suf path =
let (pre, ext) = splitExtension path in
let (pre, ext) = splitExtensions path in
pre ++ suf ++ ext
@ -289,18 +279,12 @@ instance FromYAML Info where
<*> m .:? "nsfw-tags" .!= []
<*> m .:? "desc" .!= NoDesc
<*> m .:? "nsfw-desc" .!= NoDesc
<*> m .:? "bg" .!= Default
<*> m .:? "bg"
<*> m .: "images"
<*> m .:? "thumb"
<*> m .:? "links" .!= []
<*> m .:? "extras" .!= []
instance FromYAML Bg where
parseYAML y =
YAML.withNull "default value" (pure Default) y
<|> YAML.withStr "css <image> or \"noborder\""
(\str -> pure if str == "noborder" then NoBorder else Other str) y
instance FromYAML Artist where
parseYAML y = justName y <|> withUrl y where
justName = YAML.withStr "name" \name -> pure $ Artist {name, url = Nothing}

View File

@ -7,7 +7,7 @@ data What = Single | Gallery
instance CanBuild What where
build Single = "this art"
build Gallery = "some of the art in this gallery"
build Gallery = "the art in this gallery"
script :: Maybe What -> Builder
@ -34,9 +34,7 @@ dialog (Just what) = [b|@0
<div class=dialog-buttons>
<button id=nsfw-yes class=yes>i am an adult</button>
<a href=//crouton.net referrerpolicy=no-referrer>
<button id=nsfw-no class=no>i am not</button>
</a>
<button id=nsfw-no class=no>i am not</button>
</div>
</div>
</div>

View File

@ -12,7 +12,7 @@ import Data.List (sort, intersperse)
import Data.Maybe (fromMaybe, isNothing, isJust)
import qualified Data.Text as Strict
import qualified Data.Text.Lazy as Lazy
import System.FilePath (joinPath, splitPath)
import System.FilePath (joinPath, splitPath, (-<.>))
import qualified Data.HashSet as Set
import Data.Traversable
@ -57,6 +57,7 @@ make' root siteName prefix nsfw _dataDir dir
let download0 = fromMaybe (bigFile path0) download0'
let path0' = pageFile path0
let path0'Jxl = path0' -<.> "jxl"
let descSection = makeDesc $ descFor nsfw info
let tagsList = makeTags undir $ tagsFor nsfw info
@ -84,20 +85,9 @@ make' root siteName prefix nsfw _dataDir dir
| otherwise = mempty
let warningT = makeWarning [b|.|]
let bgStyle = case bg of
Default -> ""
NoBorder -> [b|@0
<style>
#mainfig {
background: transparent;
border: none;
box-shadow: none;
}
</style>
|]
Other col -> [b|@0
<style> #mainfig { background: $col; } </style>
|]
let bgStyle = ifJust bg \col -> [b|@0
<style> #mainfig { background: $col; } </style>
|]
let url = [b|$root/$prefix/$dir|]
let desc = case artist of
@ -154,13 +144,10 @@ make' root siteName prefix nsfw _dataDir dir
<div class=page>
<header>
<h1>$title</h1>
$artistTag
<h2 id=date class="right corner">
$formattedDate $updateDate
</h2>
<h2 class="left corner">
$artistTag
<a href=$undir>back to gallery</a>
</h2>
</header>
$2.buttonBar
@ -169,7 +156,10 @@ make' root siteName prefix nsfw _dataDir dir
<figure id=mainfig>
$warning'
<a id=mainlink href="$download0" title="download full version">
<img id=mainimg src="$path0'" alt="">
<picture id=mainimg>
<source srcset="$path0'Jxl" type=image/jxl>
<img src="$path0'" alt="">
</picture>
</a>
</figure>
@ -183,6 +173,10 @@ make' root siteName prefix nsfw _dataDir dir
$6.tagsList
</div>
</main>
<footer>
<a href=$undir>back to gallery</a>
</footer>
</div>
<template id=cw-template>
@ -195,7 +189,7 @@ last' xs = if null xs then Nothing else Just $ last xs
makeArtist :: Artist -> Builder
makeArtist (Artist {name, url}) =
[b|by $artistLink <br>|]
[b|<h2 id=artist class="left corner">by $artistLink</h2>|]
where
artistLink = case url of
Just u -> [b|<a href="$u">$name</a>|]
@ -313,7 +307,7 @@ extLinks links =
if null links then "" else [b|@0
<nav id=links class=info-section>
<h2>links</h2>
<ul>
<ul class="buttonbar bb-links">
$4.linkList
</ul>
</nav>

View File

@ -35,14 +35,6 @@ function updateItems() {
document.getElementById(`marker-${year}`).hidden = hide;
}
function disp(pfx, tags) {
return Array(...tags).map(x => pfx + x).join('\u2003'); // em space
}
let plus = disp('+\u2009', reqTags); // thin space
let minus = disp('-\u2009', excTags);
document.getElementById('filters-details').dataset.filters =
`${plus}\u2003${minus}`.trim();
}
function update() {
@ -138,7 +130,7 @@ function sortFilters(cmp) {
sort1('exclude');
}
function sortFiltersAlpha(e) {
function sortFiltersAlpha() {
function getName(x) {
if (x.nodeType == Node.ELEMENT_NODE) {
return x.getElementsByTagName('input')[0].value;
@ -147,10 +139,9 @@ function sortFiltersAlpha(e) {
}
}
sortFilters((a, b) => getName(a).localeCompare(getName(b)));
e.preventDefault();
}
function sortFiltersUses(e) {
function sortFiltersUses() {
function getUses(x) {
if (x.nodeType == Node.ELEMENT_NODE) {
return parseInt(x.getElementsByTagName('label')[0].dataset.count);
@ -159,7 +150,6 @@ function sortFiltersUses(e) {
}
}
sortFilters((a, b) => getUses(b) - getUses(a));
e.preventDefault();
}
@ -170,8 +160,8 @@ function setup() {
}
let items = Array.from(document.getElementsByClassName('post'));
itemsByYear = new Map;
for (let item of items) {
let year = item.dataset.year;
if (!itemsByYear.has(year)) itemsByYear.set(year, new Set);

View File

@ -17,19 +17,16 @@ function yes() {
dismiss();
}
// now just a normal link
/*
function no() {
document.location = '//crouton.net';
history.go(-1);
}
*/
function setup() {
if (alreadyYes()) {
dismiss();
} else {
document.getElementById('nsfw-yes').onclick = yes;
// document.getElementById('nsfw-no').onclick = no;
document.getElementById('nsfw-no').onclick = no;
}
}

View File

@ -24,7 +24,7 @@ function addCWListeners(id, caption) {
}
}
function setImage(id, src, href, cw) {
function setImage(id, src, width, height, href, cw, firstLoad) {
let caption = document.getElementById('cw');
let newCaption;
@ -45,13 +45,20 @@ function setImage(id, src, href, cw) {
mainlink.tabIndex = -1;
}
mainimg.src = src;
mainlink.href = href;
let jxl = src.replace(/\..*?$/, ".jxl");
mainimg.querySelector('img').src = src;
mainimg.querySelector('source').srcset = jxl;
mainfig.dataset.width = width;
mainfig.dataset.height = height;
mainlink.href = href;
}
function activateButton(button, doPush = true) {
function activateButton(button, doPush = true, firstLoad = false) {
setImage(button.id, button.value,
button.dataset.link, button.dataset.warning);
button.dataset.width, button.dataset.height,
button.dataset.link, button.dataset.warning,
firstLoad);
if (doPush) history.pushState(null, '', '#' + button.id);
}
@ -70,7 +77,7 @@ function useFragment(firstLoad = false) {
if (button) {
id = button.id;
button.checked = true;
activateButton(button, false);
activateButton(button, false, firstLoad);
}
if (firstLoad) addCWListeners(id, document.getElementById('cw'));
@ -101,7 +108,7 @@ function setup() {
} };
}
window.addEventListener('popstate', e => useFragment());
window.addEventListener('popstate', useFragment);
useFragment(true);
}

View File

@ -28,6 +28,7 @@
--text-col: white;
--text-shadow-col: hsl(0, 0%, 0%, 75%);
--text-shadow: 2px 2px 3px var(--text-shadow-col);
--nsfw-sticker-rotate: 15deg;
--focus-box: 0 0 5px hsl(55deg, 60%, 90%, 80%);
--focus-text: hsl(334deg, 87%, 90%);
@ -52,8 +53,6 @@
margin: 0;
}
body { margin: 0; }
header {
text-align: center;
}
@ -66,10 +65,12 @@ h3 { font-size: 110%; }
.page {
background: var(--background);
border: var(--border);
position: relative;
padding: 2em 4em;
margin: 0 auto;
margin: 3em auto 3.5em;
border-radius: var(--border-radius);
color: var(--text-col);
text-shadow: var(--text-shadow);
@ -111,7 +112,7 @@ figure > img {
margin: 0;
padding: 0;
position: absolute;
top: 1em;
top: 0.5em;
font-size: 100%;
font-weight: 500;
@ -233,11 +234,6 @@ p {
hyphens: auto;
}
del {
text-decoration: line-through wavy;
text-decoration-thickness: 2px;
}
.threecol {
columns: 3;

View File

@ -3,18 +3,13 @@
:root {
--image-size: 200px;
--badge-size: calc(1/4 * var(--image-size));
--gap: 0em;
--gap: 1em;
}
@media (min-width: 1000px) {
.page { max-width: 80%; }
}
.page {
padding: 2em calc(1/4 * var(--image-size));
}
#filters {
margin: 1em 0 2em 0;
}
@ -23,7 +18,7 @@
display: grid;
grid-template-columns: 15% auto;
align-items: baseline;
gap: 0.75em;
grid-gap: 0.75em;
}
#filters h3 {
@ -38,11 +33,12 @@
.filterlist {
display: flex;
flex-flow: row wrap;
/* justify-content: space-between; */
padding: 0;
font-weight: 500;
font-size: 90%;
gap: 0.5em;
grid-gap: 0.5em 1em;
}
.filterlist input {
@ -58,10 +54,10 @@
}
.filterlist label {
cursor: pointer;
padding: 0.15em 0.4em;
border-radius: 1000px;
border: 1px solid transparent;
border-radius: var(--button-radius);
background: var(--button-bg);
border: var(--button-border);
}
.filterlist label::before {
@ -74,10 +70,6 @@
text-shadow: none;
}
.filterlist :checked + label::before { content: url('/style/checked.svg'); }
.filterlist :checked + label {
background: var(--button-bg);
border: var(--button-border);
}
.filterlist label:not([data-count="1"])::after {
content: attr(data-count);
@ -101,7 +93,7 @@
display: flex;
justify-content: center;
margin-top: 0;
gap: 2em;
grid-gap: 2em;
}
#filterstuff li {
@ -118,12 +110,6 @@
text-decoration: none;
}
#filters-details:not([open])::after {
content: attr(data-filters);
margin-left: 2em;
font-size: 90%;
}
@media (max-width: 80rem) {
#filters div {
@ -138,7 +124,7 @@
#filterstuff {
grid-area: unset;
flex-flow: column;
gap: 0.2em;
grid-gap: 0.2em;
}
#filterstuff li {
@ -150,8 +136,8 @@
.grid {
padding: 0;
display: grid;
grid: auto-flow / repeat(auto-fit, var(--image-size));
gap: var(--gap);
grid-template-columns: repeat(auto-fill, var(--image-size));
grid-gap: var(--gap);
justify-content: center;
}
@ -168,18 +154,35 @@
.item:not(.year-marker) {
box-shadow: var(--text-shadow);
outline: var(--border-thickness) solid var(--border-col);
background: hsl(0, 0%, 0%, 50%);
clip-path: polygon(5% 0, 95% 10%, 95% 100%, 5% 90%);
}
.item img {
clip-path: polygon(7% 2%, 93% 12%, 93% 98%, 7% 88%);
border: var(--border-thickness) solid var(--border-col);
border-radius: 0.5em;
background: hsl(340, 45%, 65%);
}
.item:focus-within {
box-shadow: var(--focus-box);
}
figure {
margin: 0;
padding: 0;
}
figcaption .date, figcaption .title {
position: absolute;
width: 100%;
border: 1px solid var(--border-col);
display: block;
text-align: center;
background: hsl(0, 0%, 0%, 75%);
text-shadow: none;
}
figcaption .date { top: -1px; left: -1px; }
figcaption .title { bottom: -1px; left: -1px; }
.date { text-transform: lowercase; }
.year-marker {
/* uncomment to reenable line breaks before year markers */
/* grid-area: auto / 1; */
@ -190,7 +193,7 @@
--gap: 0.2em;
display: grid;
grid-template-columns: repeat(2, calc(50% - 3 * var(--gap)));
gap: var(--gap);
grid-gap: var(--gap);
align-items: center;
justify-content: center;
height: 100%;
@ -207,8 +210,9 @@
}
.item.nsfw::before, .item[data-updated="true"]::after {
height: var(--badge-size);
width: var(--badge-size);
height: var(--size);
width: var(--size);
transform: var(--base-transform);
display: inline-block;
position: absolute;
@ -217,18 +221,19 @@
}
.item.nsfw::before {
transform: rotate(15deg);
--size: calc(1/4 * var(--image-size));
--base-transform: rotate(var(--nsfw-sticker-rotate));
content: url(../18_plus_white.svg);
top: 11%;
right: 7%;
z-index: 100;
top: calc(1em + 3px);
right: 3px;
}
.item[data-updated="true"]::after {
transform: rotate(-8deg);
--size: calc(1/4 * var(--image-size));
--base-transform: rotate(-8deg);
content: url(../sparkles.svg);
bottom: 4%;
right: 7%;
bottom: calc(1em + 3px);
right: 3px;
}
footer {
@ -237,6 +242,68 @@ footer {
margin-top: 1em;
}
@media (hover) and (pointer: fine) {
.item:hover .date, .item:hover .title,
.item:hover::before, .item:hover::after {
filter: opacity(20%);
}
@media (prefers-reduced-motion: no-preference) {
figcaption .date, figcaption .title, .item::before, .item::after {
transition-property: filter, transform;
transition-duration: 0.15s;
transition-timing-function: ease-in-out;
}
.item:hover .title {
transform: translate(-20%, 80%) rotateZ(7deg);
}
.item:hover .date {
transform: translate(20%, -80%) rotateZ(7deg);
}
.item:hover::before {
transform: translate(1.5em, -1.5em) var(--base-transform);
}
.item:hover::after {
transform: translate(1.5em, 1.5em) var(--base-transform);
}
}
}
@media (not hover), (pointer: coarse) {
.item:not(.year-marker) {
height: min-content;
}
figcaption .date, figcaption .title {
position: initial;
}
figcaption .date {
border-bottom: none;
}
figcaption .title {
border-top: none;
}
figcaption .date::after {
content: ':';
}
.item a {
display: block;
height: var(--image-size);
}
.item img {
margin-bottom: 0;
}
}
@media (pointer: coarse) {
#filters label {
font-size: 150%;

View File

@ -9,7 +9,6 @@
.page {
width: 37.5em;
border-radius: var(--border-radius);
}
#title::before, #title::after {
@ -31,11 +30,12 @@
}
@media not speech {
@media screen {
.nsfw::after {
content: url(../18_plus_white.svg);
height: 1em;
width: 1em;
transform: rotate(var(--nsfw-sticker-rotate));
mix-blend-mode: hard-light;
margin-left: 0.3em;
}
@ -43,7 +43,7 @@
@media speech {
.nsfw::after {
content: ' (contains adult content)';
content: ' (some nsfw)';
}
}
@ -67,7 +67,7 @@
align-items: center;
justify-content: space-evenly;
padding: 0;
gap: 1.5em;
grid-gap: 1.5em;
font-size: 175%;
}
@ -93,7 +93,7 @@ main {
.list {
font-size: 300%;
grid-template-columns: 100%;
gap: 1em;
grid-gap: 1em;
}
}

View File

@ -20,7 +20,7 @@
"icon text"
"buttons buttons"
/ 1fr 3fr;
gap: 0.5em;
grid-gap: 0.5em;
align-items: center;
min-height: 20vh;
@ -61,8 +61,8 @@
margin-top: 1em;
}
.dialog-buttons > * {
margin: 0 1em;
.dialog button + button {
margin-left: 1em;
}
.dialog button {
@ -74,16 +74,6 @@
font-weight: 600;
font-size: inherit;
color: black;
position: relative;
cursor: pointer;
}
.dialog button a {
inset: 0;
width: max-content;
text-decoration: none;
}
.dialog .yes {

View File

@ -6,14 +6,8 @@
--image-width: 1000px;
}
body {
display: grid;
min-height: 100vh;
}
.page {
max-width: var(--image-width);
align-self: center;
}
#mainfig {
@ -24,6 +18,7 @@ body {
position: relative;
overflow: hidden;
border: var(--border-thickness) solid var(--border-col);
border-radius: 1em;
box-shadow: var(--text-shadow);
background: hsl(340, 45%, 65%);
}
@ -32,7 +27,7 @@ body {
box-shadow: var(--focus-box);
}
#mainimg {
#mainimg, #mainimg img {
display: block;
}
@ -81,6 +76,20 @@ body {
}
}
/*
.nsfw-label::after {
content: url(../18_plus_white.svg);
display: inline-block;
height: 0.9em; width: 0.9em;
vertical-align: -0.07em;
padding-left: 0.25em;
}
:checked ~ .nsfw-label::after {
content: url(../18_plus.svg);
}
*/
#date { text-transform: lowercase; }
#info {
@ -95,6 +104,9 @@ body {
align-items: baseline;
}
/* 'display: contents' removes things from the accessibility tree
* which is probably only a problem for screen readers?
*/
@media not speech {
.info-section {
display: contents;
@ -102,13 +114,10 @@ body {
}
#info figure {
width: min-content;
margin: 0.25em auto;
}
#info figure img {
max-width: 100%;
}
#info .light-bg {
background: hsl(0deg, 0%, 100%, 75%);
padding: 5px;
@ -118,7 +127,6 @@ body {
#info .floating {
float: right;
margin-left: 0.8em;
max-width: 40%;
}
#info .floating.left {
@ -144,7 +152,7 @@ body {
#updates dl {
display: grid;
grid-template-columns: min-content auto;
gap: 0.5em;
grid-gap: 0.5em;
align-items: baseline;
}
@ -183,7 +191,7 @@ footer {
margin: 1.5em 0;
text-align: center;
display: grid;
gap: 0.5em;
grid-gap: 0.5em;
grid-template-columns: minmax(auto, 10em) auto minmax(auto, 10em);
}
@ -214,11 +222,29 @@ footer {
grid-area: 1 / 3 / auto / auto;
}
:is(#tags, #links) ul {
#tags ul {
padding: 0;
}
:is(#tags, #links) li {
#tags li {
display: inline;
margin-right: 0.75em;
}
.conversation {
display: grid;
grid-template-columns: min-content auto;
grid-gap: 0.15em 1em;
margin: 0;
}
.conversation > b {
grid-area: auto / 1 / auto / auto;
display: block;
text-align: right;
}
.conversation > q {
grid-area: auto / 2 / auto / auto;
font-style: initial;
quotes: none;
display: block;
}