@@ -6,91 +6,6 @@ import PageHero from '../components/pagehero.astro'
66import coverSVG from ' ../assets/svg/rosely/undraw_add_notes-light.svg'
77import coverSVGDark from ' ../assets/svg/rosely/undraw_add_notes-dark.svg'
88import socialImage from ' ../assets/social/add_notes.png'
9- import {
10- jupiter ,
11- cutout ,
12- pianoMan ,
13- pieFactory ,
14- graphPaper ,
15- charlieBrown ,
16- autumn ,
17- temple ,
18- deathStar ,
19- churchOnSunday ,
20- overlappingHexagons ,
21- bamboo ,
22- bathroomFloor ,
23- corkScrew ,
24- happyIntersection ,
25- kiwi ,
26- lips ,
27- lisbon ,
28- steelBeams ,
29- tinyCheckers ,
30- fancyRectangles ,
31- heavyRain ,
32- cage ,
33- connections ,
34- flippedDiamonds ,
35- houndstooth ,
36- morphingDiamonds ,
37- zigZag ,
38- aztec ,
39- bankNote ,
40- boxes ,
41- diagonalLines ,
42- endlessClouds ,
43- eyes ,
44- groovy ,
45- melt ,
46- parkayFloor ,
47- pixelDots ,
48- signal ,
49- wallpaper
50- } from ' hero-patterns'
51-
52- const patterns = [
53- steelBeams (' #9c92ac' , 0.5 ),
54- jupiter (' #9c92ac' , 0.5 ),
55- cutout (' #9c92ac' , 0.5 ),
56- pianoMan (' #9c92ac' , 0.5 ),
57- pieFactory (' #9c92ac' , 0.5 ),
58- graphPaper (' #9c92ac' , 0.5 ),
59- charlieBrown (' #9c92ac' , 0.5 ),
60- autumn (' #9c92ac' , 0.5 ),
61- temple (' #9c92ac' , 0.5 ),
62- deathStar (' #9c92ac' , 0.5 ),
63- churchOnSunday (' #9c92ac' , 0.5 ),
64- overlappingHexagons (' #9c92ac' , 0.5 ),
65- bamboo (' #9c92ac' , 0.5 ),
66- bathroomFloor (' #9c92ac' , 0.5 ),
67- corkScrew (' #9c92ac' , 0.5 ),
68- happyIntersection (' #9c92ac' , 0.5 ),
69- kiwi (' #9c92ac' , 0.5 ),
70- lips (' #9c92ac' , 0.5 ),
71- lisbon (' #9c92ac' , 0.5 ),
72- tinyCheckers (' #9c92ac' , 0.5 ),
73- fancyRectangles (' #9c92ac' , 0.5 ),
74- heavyRain (' #9c92ac' , 0.5 ),
75- cage (' #9c92ac' , 0.5 ),
76- connections (' #9c92ac' , 0.5 ),
77- flippedDiamonds (' #9c92ac' , 0.5 ),
78- houndstooth (' #9c92ac' , 0.5 ),
79- morphingDiamonds (' #9c92ac' , 0.5 ),
80- zigZag (' #9c92ac' , 0.5 ),
81- aztec (' #9c92ac' , 0.5 ),
82- bankNote (' #9c92ac' , 0.5 ),
83- boxes (' #9c92ac' , 0.5 ),
84- diagonalLines (' #9c92ac' , 0.5 ),
85- endlessClouds (' #9c92ac' , 0.5 ),
86- eyes (' #9c92ac' , 0.5 ),
87- groovy (' #9c92ac' , 0.5 ),
88- melt (' #9c92ac' , 0.5 ),
89- parkayFloor (' #9c92ac' , 0.5 ),
90- pixelDots (' #9c92ac' , 0.5 ),
91- signal (' #9c92ac' , 0.5 ),
92- wallpaper (' #9c92ac' , 0.5 )
93- ]
949
9510const frontmatter: CollectionEntry <' page' >[' data' ] = {
9611 title: ' Tags' ,
@@ -118,6 +33,35 @@ posts.forEach((post) => {
11833
11934const tags = Array .from (tagmap .values ())
12035
36+ // Frequency is encoded in size and colour; the cloud itself reads
37+ // alphabetically, so a particular tag can still be found by scanning.
38+ const counts = tags .map ((t ) => t .count )
39+ const min = Math .min (... counts )
40+ const max = Math .max (... counts )
41+
42+ // Seven steps, heaviest first — standard type scale, no arbitrary sizes.
43+ const steps = [
44+ { size: ' text-5xl' , tone: ' text-ink dark:text-cream' , weight: ' font-medium' },
45+ { size: ' text-4xl' , tone: ' text-ink dark:text-cream' , weight: ' font-medium' },
46+ { size: ' text-3xl' , tone: ' text-mulberry dark:text-quartz' , weight: ' font-medium' },
47+ { size: ' text-2xl' , tone: ' text-mulberry dark:text-quartz' , weight: ' font-normal' },
48+ { size: ' text-xl' , tone: ' text-slate dark:text-fog' , weight: ' font-normal' },
49+ { size: ' text-lg' , tone: ' text-slate dark:text-fog' , weight: ' font-normal' },
50+ { size: ' text-base' , tone: ' text-slate dark:text-fog' , weight: ' font-normal' }
51+ ]
52+
53+ const stepFor = (count : number ) => {
54+ if (max === min ) return steps [3 ]
55+ // Log scale, so one very frequent tag doesn't flatten all the others.
56+ const t = (Math .log (count ) - Math .log (min )) / (Math .log (max ) - Math .log (min ))
57+ return steps [Math .round ((1 - t ) * (steps .length - 1 ))]
58+ }
59+
60+ const cloud = tags
61+ .slice ()
62+ .sort ((a , b ) => a .tag .toLowerCase ().localeCompare (b .tag .toLowerCase ()))
63+ .map ((t ) => ({ ... t , ... stepFor (t .count ) }))
64+
12165const baseUrl = import .meta .env .BASE_URL
12266---
12367
@@ -131,38 +75,36 @@ const baseUrl = import.meta.env.BASE_URL
13175 socialImage ={ frontmatter .socialImage }
13276 />
13377 </header >
134- <div itemprop =" mainContentOfPage" class =" dark:bg-ink mt-10" >
135- <div
136- itemprop =" mainEntity"
137- itemscope
138- itemtype =" https://schema.org/CollectionPage"
139- class =" mx-4 mt-6 mb-24 grid grid-cols-2 gap-x-4 gap-y-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 xl:gap-x-6 xl:gap-y-6"
140- >
141- {
142- tags
143- .sort ((a , b ) => b .count - a .count )
144- .map ((tag , i ) => (
145- <a href = { ` ${baseUrl }tag/${tag .tag }/ ` } class = " group" >
146- <section
147- class = " group relative h-24 w-full overflow-hidden rounded-lg bg-cover bg-center shadow-lg transition duration-300 ease-in-out hover:shadow-2xl"
148- style = { {
149- backgroundColor: ' #dfdbe5' ,
150- // backgroundImage: `url(${OGImage})`,
151- backgroundImage: patterns [i % patterns .length ]
152- }}
78+
79+ <div itemprop =" mainContentOfPage" class =" dark:bg-ink-deep bg-cream" >
80+ <div class =" mx-auto max-w-5xl px-6 py-14 sm:px-10 lg:py-16" >
81+ <p class =" text-mulberry dark:text-grape mb-10 font-mono text-xs tracking-widest uppercase" >
82+ { tags .length } tags · larger means more articles
83+ </p >
84+
85+ <ul
86+ itemprop =" mainEntity"
87+ itemscope
88+ itemtype =" https://schema.org/CollectionPage"
89+ class =" flex flex-wrap items-baseline justify-center gap-x-6 gap-y-3"
90+ >
91+ {
92+ cloud .map ((tag ) => (
93+ <li class = " leading-tight" >
94+ <a
95+ href = { ` ${baseUrl }tag/${tag .tag }/ ` }
96+ title = { ` ${tag .count } ${tag .count === 1 ? ' article' : ' articles' } ` }
97+ class = { ` hover:text-rose font-serif transition-colors dark:hover:text-white ${tag .size } ${tag .tone } ${tag .weight } ` }
15398 >
154- <div class = " absolute inset-0 bg-black/50 transition duration-300 ease-in-out group-hover:opacity-75" />
155- <div class = " relative flex h-full w-full items-center justify-center px-4 sm:px-6 lg:px-4" >
156- <h3 class = " text-center text-2xl font-bold text-white" >
157- <span class = " absolute inset-0" />
158- { tag .tag }
159- </h3 >
160- <p class = " text-center text-sm font-medium text-gray-200" > ({ tag .count } )</p >
161- </div >
162- </section >
163- </a >
99+ { tag .tag }
100+ <span class = " sr-only" >
101+ , { tag .count } { tag .count === 1 ? ' article' : ' articles' }
102+ </span >
103+ </a >
104+ </li >
164105 ))
165- }
106+ }
107+ </ul >
166108 </div >
167109 </div >
168110</Base >
0 commit comments