Compare commits

...

13 Commits
jxl ... 🎨

Author SHA1 Message Date
rhiannon morris 11f5029412 simplify a selector 2023-08-06 06:50:07 +02:00
rhiannon morris 37cfafbcd3 vertically center single pages 2023-08-06 06:12:29 +02:00
rhiannon morris f40850cf38 simplify grid css syntax 2023-08-06 06:12:10 +02:00
rhiannon morris a79310c4ec display links field as normal text not buttons 2023-08-06 06:11:54 +02:00
rhiannon morris 7d20b2a761 make current filters more obvious
- inside the list, give selected filters a background
- when the list is collapsed, display the current selection next to it
2023-08-06 06:10:56 +02:00
rhiannon morris fd216ae3dd no button on the nsfw warning goes to crouton.net 2023-07-19 23:07:18 +02:00
rhiannon morris f16c2f549a fix overlapping text and other layout weirdness 2023-07-10 10:59:07 +02:00
rhiannon morris db83137243 remove some unused cruft 2023-06-21 22:38:49 +02:00
rhiannon morris 8dcc603ade explicit height/width in gallery to placate chromium 2023-06-21 22:38:34 +02:00
rhiannon morris 485b90fb46 style & layout updates 2023-06-21 19:58:01 +02:00
rhiannon morris ebd08fb2e5 style for <del> 2023-03-11 15:55:25 +01:00
rhiannon morris 474276e6a1 support for no background at all 2023-03-07 16:14:42 +01:00
Rhiannon Morris 57627e2af6 webp resizing rules 2023-02-09 18:45:22 +01:00
14 changed files with 188 additions and 200 deletions

View File

@ -66,6 +66,16 @@ $(TMPDIR)/%_big.jpg: $(DATADIR)/%.jpg
$(call resize,$(BIG),$(BIG),>) $(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),>)
$(MAKEPAGES): make-pages/*.hs make-pages/make-pages.cabal $(MAKEPAGES): make-pages/*.hs make-pages/make-pages.cabal
echo "[make-pages]" echo "[make-pages]"
mkdir -p $(dir $@) mkdir -p $(dir $@)

View File

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

View File

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

View File

@ -1,9 +1,12 @@
{-# OPTIONS_GHC -fdefer-typed-holes #-}
{-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-orphans #-}
module Info module Info
(Info (..), (Info (..),
tagsFor, descFor, imagesFor, linksFor, updatesFor, compareFor, sortFor, tagsFor, descFor, imagesFor, linksFor, updatesFor, lastUpdate,
compareFor, sortFor,
Artist (..), Images' (..), Images, Image (..), Desc (..), DescField (..), Artist (..), Images' (..), Images, Image (..), Desc (..), DescField (..),
Link (..), Update (..), Link (..), Update (..), Bg (..),
GalleryInfo (..), GalleryFilters (..), ArtistFilter (..), NsfwFilter (..), GalleryInfo (..), GalleryFilters (..), ArtistFilter (..), NsfwFilter (..),
IndexInfo (..), IndexInfo (..),
readArtistFilter, matchArtist, readNsfwFilter, matchNsfw, matchFilters, readArtistFilter, matchArtist, readNsfwFilter, matchNsfw, matchFilters,
@ -57,7 +60,7 @@ data Info =
nsfwTags :: ![Text], nsfwTags :: ![Text],
desc :: !Desc, desc :: !Desc,
nsfwDesc :: !Desc, nsfwDesc :: !Desc,
bg :: !(Maybe Text), bg :: !Bg,
images :: !Images, images :: !Images,
thumb' :: !(Maybe FilePath), thumb' :: !(Maybe FilePath),
links :: ![Link], links :: ![Link],
@ -65,6 +68,9 @@ data Info =
} }
deriving (Eq, Show) deriving (Eq, Show)
data Bg = Default | NoBorder | Other !Text
deriving (Eq, Show)
data Desc = data Desc =
NoDesc NoDesc
| TextDesc !Text | TextDesc !Text
@ -214,6 +220,10 @@ linksFor nsfw = if nsfw then #links else #sfwLinks
updatesFor :: Bool -> Info -> [(Date, [Update])] updatesFor :: Bool -> Info -> [(Date, [Update])]
updatesFor nsfw = if nsfw then #updates else #sfwUpdates 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 :: Bool -> Info -> Info -> Ordering
compareFor nsfw = comparing \i -> (#latestDate i nsfw, #sortEx i, #title i) compareFor nsfw = comparing \i -> (#latestDate i nsfw, #sortEx i, #title i)
@ -279,12 +289,18 @@ instance FromYAML Info where
<*> m .:? "nsfw-tags" .!= [] <*> m .:? "nsfw-tags" .!= []
<*> m .:? "desc" .!= NoDesc <*> m .:? "desc" .!= NoDesc
<*> m .:? "nsfw-desc" .!= NoDesc <*> m .:? "nsfw-desc" .!= NoDesc
<*> m .:? "bg" <*> m .:? "bg" .!= Default
<*> m .: "images" <*> m .: "images"
<*> m .:? "thumb" <*> m .:? "thumb"
<*> m .:? "links" .!= [] <*> m .:? "links" .!= []
<*> m .:? "extras" .!= [] <*> 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 instance FromYAML Artist where
parseYAML y = justName y <|> withUrl y where parseYAML y = justName y <|> withUrl y where
justName = YAML.withStr "name" \name -> pure $ Artist {name, url = Nothing} justName = YAML.withStr "name" \name -> pure $ Artist {name, url = Nothing}

View File

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

View File

@ -84,9 +84,20 @@ make' root siteName prefix nsfw _dataDir dir
| otherwise = mempty | otherwise = mempty
let warningT = makeWarning [b|.|] let warningT = makeWarning [b|.|]
let bgStyle = ifJust bg \col -> [b|@0 let bgStyle = case bg of
<style> #mainfig { background: $col; } </style> Default -> ""
|] NoBorder -> [b|@0
<style>
#mainfig {
background: transparent;
border: none;
box-shadow: none;
}
</style>
|]
Other col -> [b|@0
<style> #mainfig { background: $col; } </style>
|]
let url = [b|$root/$prefix/$dir|] let url = [b|$root/$prefix/$dir|]
let desc = case artist of let desc = case artist of
@ -143,10 +154,13 @@ make' root siteName prefix nsfw _dataDir dir
<div class=page> <div class=page>
<header> <header>
<h1>$title</h1> <h1>$title</h1>
$artistTag
<h2 id=date class="right corner"> <h2 id=date class="right corner">
$formattedDate $updateDate $formattedDate $updateDate
</h2> </h2>
<h2 class="left corner">
$artistTag
<a href=$undir>back to gallery</a>
</h2>
</header> </header>
$2.buttonBar $2.buttonBar
@ -169,10 +183,6 @@ make' root siteName prefix nsfw _dataDir dir
$6.tagsList $6.tagsList
</div> </div>
</main> </main>
<footer>
<a href=$undir>back to gallery</a>
</footer>
</div> </div>
<template id=cw-template> <template id=cw-template>
@ -185,7 +195,7 @@ last' xs = if null xs then Nothing else Just $ last xs
makeArtist :: Artist -> Builder makeArtist :: Artist -> Builder
makeArtist (Artist {name, url}) = makeArtist (Artist {name, url}) =
[b|<h2 id=artist class="left corner">by $artistLink</h2>|] [b|by $artistLink <br>|]
where where
artistLink = case url of artistLink = case url of
Just u -> [b|<a href="$u">$name</a>|] Just u -> [b|<a href="$u">$name</a>|]
@ -303,7 +313,7 @@ extLinks links =
if null links then "" else [b|@0 if null links then "" else [b|@0
<nav id=links class=info-section> <nav id=links class=info-section>
<h2>links</h2> <h2>links</h2>
<ul class="buttonbar bb-links"> <ul>
$4.linkList $4.linkList
</ul> </ul>
</nav> </nav>

View File

@ -35,6 +35,14 @@ function updateItems() {
document.getElementById(`marker-${year}`).hidden = hide; 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() { function update() {
@ -130,7 +138,7 @@ function sortFilters(cmp) {
sort1('exclude'); sort1('exclude');
} }
function sortFiltersAlpha() { function sortFiltersAlpha(e) {
function getName(x) { function getName(x) {
if (x.nodeType == Node.ELEMENT_NODE) { if (x.nodeType == Node.ELEMENT_NODE) {
return x.getElementsByTagName('input')[0].value; return x.getElementsByTagName('input')[0].value;
@ -139,9 +147,10 @@ function sortFiltersAlpha() {
} }
} }
sortFilters((a, b) => getName(a).localeCompare(getName(b))); sortFilters((a, b) => getName(a).localeCompare(getName(b)));
e.preventDefault();
} }
function sortFiltersUses() { function sortFiltersUses(e) {
function getUses(x) { function getUses(x) {
if (x.nodeType == Node.ELEMENT_NODE) { if (x.nodeType == Node.ELEMENT_NODE) {
return parseInt(x.getElementsByTagName('label')[0].dataset.count); return parseInt(x.getElementsByTagName('label')[0].dataset.count);
@ -150,6 +159,7 @@ function sortFiltersUses() {
} }
} }
sortFilters((a, b) => getUses(b) - getUses(a)); sortFilters((a, b) => getUses(b) - getUses(a));
e.preventDefault();
} }
@ -160,8 +170,8 @@ function setup() {
} }
let items = Array.from(document.getElementsByClassName('post')); let items = Array.from(document.getElementsByClassName('post'));
itemsByYear = new Map;
itemsByYear = new Map;
for (let item of items) { for (let item of items) {
let year = item.dataset.year; let year = item.dataset.year;
if (!itemsByYear.has(year)) itemsByYear.set(year, new Set); if (!itemsByYear.has(year)) itemsByYear.set(year, new Set);

View File

@ -17,16 +17,19 @@ function yes() {
dismiss(); dismiss();
} }
// now just a normal link
/*
function no() { function no() {
history.go(-1); document.location = '//crouton.net';
} }
*/
function setup() { function setup() {
if (alreadyYes()) { if (alreadyYes()) {
dismiss(); dismiss();
} else { } else {
document.getElementById('nsfw-yes').onclick = yes; 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, width, height, href, cw, firstLoad) { function setImage(id, src, href, cw) {
let caption = document.getElementById('cw'); let caption = document.getElementById('cw');
let newCaption; let newCaption;
@ -45,17 +45,13 @@ function setImage(id, src, width, height, href, cw, firstLoad) {
mainlink.tabIndex = -1; mainlink.tabIndex = -1;
} }
mainimg.src = src; mainimg.src = src;
mainfig.dataset.width = width; mainlink.href = href;
mainfig.dataset.height = height;
mainlink.href = href;
} }
function activateButton(button, doPush = true, firstLoad = false) { function activateButton(button, doPush = true) {
setImage(button.id, button.value, setImage(button.id, button.value,
button.dataset.width, button.dataset.height, button.dataset.link, button.dataset.warning);
button.dataset.link, button.dataset.warning,
firstLoad);
if (doPush) history.pushState(null, '', '#' + button.id); if (doPush) history.pushState(null, '', '#' + button.id);
} }
@ -74,7 +70,7 @@ function useFragment(firstLoad = false) {
if (button) { if (button) {
id = button.id; id = button.id;
button.checked = true; button.checked = true;
activateButton(button, false, firstLoad); activateButton(button, false);
} }
if (firstLoad) addCWListeners(id, document.getElementById('cw')); if (firstLoad) addCWListeners(id, document.getElementById('cw'));
@ -105,7 +101,7 @@ function setup() {
} }; } };
} }
window.addEventListener('popstate', useFragment); window.addEventListener('popstate', e => useFragment());
useFragment(true); useFragment(true);
} }

View File

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

View File

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

View File

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

View File

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

View File

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