index.astro (3943B)
1 --- 2 import Base from '../../layouts/Base.astro'; 3 import SectionBanner from '../../components/SectionBanner.astro'; 4 import { allTags, allTools, tagSlug } from '../../lib/sheets'; 5 import { url } from '../../lib/url'; 6 const tags = await allTags(); 7 const tools = await allTools(); 8 --- 9 <Base title="Tags & Tools — DÆMON//SEC" description="Browse every cheatsheet by tag or tool."> 10 <SectionBanner 11 n="04" 12 label="Cross-reference" 13 title="Tags & Tools" 14 blurb="Jump into the vault by topic or by the tool you're reaching for." 15 accent="foam" 16 stats={[ 17 { label: 'Tags', value: String(tags.length).padStart(2, '0'), accent: true }, 18 { label: 'Tools', value: String(tools.length).padStart(2, '0') }, 19 ]} 20 /> 21 22 <div class="wrap"> 23 <nav class="breadcrumb" style="margin-top:1.6rem;"> 24 <a href={url('')}>~</a><span class="sep">/</span><span class="muted">index</span> 25 </nav> 26 27 <section class="section"> 28 <div class="section-head"> 29 <div> 30 <p class="eyebrow" style="--acc: var(--iris);"> 31 <span class="eyebrow__n">01</span> 32 <span class="eyebrow__mark">^:</span> 33 <span>{tags.length} tags</span> 34 <span class="eyebrow__rule" aria-hidden="true"></span> 35 </p> 36 <h2>By tag</h2> 37 </div> 38 </div> 39 <div class="cloud"> 40 {tags.map((t) => ( 41 <a class="tag-pill cloud-item" href={url(`tags/${tagSlug(t.tag)}`)}>{t.tag}<span class="cnt">{t.count}</span></a> 42 ))} 43 </div> 44 </section> 45 46 <section class="section"> 47 <div class="section-head"> 48 <div> 49 <p class="eyebrow" style="--acc: var(--gold);"> 50 <span class="eyebrow__n">02</span> 51 <span class="eyebrow__mark">^:</span> 52 <span>{tools.length} tools</span> 53 <span class="eyebrow__rule" aria-hidden="true"></span> 54 </p> 55 <h2>By tool</h2> 56 </div> 57 </div> 58 <div class="cloud"> 59 {tools.map((t) => ( 60 <span class="tag-pill cloud-item">{t.tool}<span class="cnt">{t.count}</span></span> 61 ))} 62 </div> 63 </section> 64 </div> 65 </Base> 66 67 <style> 68 .cloud { display: flex; flex-wrap: wrap; gap: 0.4rem; } 69 .cloud-item { display: inline-flex; align-items: center; gap: 0.5rem; } 70 /* The count is a second register inside the chip, not a badge on it — 71 square, hairline-separated, same 10px mono. */ 72 .cloud-item .cnt { 73 padding-left: 0.5rem; 74 border-left: 1px solid var(--rule); 75 color: var(--fg-faint); 76 } 77 .cloud-item:hover .cnt { color: inherit; border-left-color: currentColor; } 78 79 /* Corner ticks on hover only: the full .corners object on every pill in a 80 cloud of dozens is bracket noise, so the pills take the record-row 81 convention — the brackets arrive with the pointer. Same geometry as 82 .corners (10px L-ticks, -3px offset), keyed to currentColor so the ticks 83 flip to cream when the pill inverts on hover. */ 84 .cloud-item { position: relative; } 85 .cloud-item:hover::before, 86 .cloud-item:hover::after { 87 content: ""; 88 position: absolute; 89 inset-block: -3px; 90 width: 10px; 91 pointer-events: none; 92 } 93 .cloud-item:hover::before { 94 inset-inline-start: -3px; 95 background: 96 linear-gradient(currentColor 0 0) left top / 10px 1px no-repeat, 97 linear-gradient(currentColor 0 0) left top / 1px 10px no-repeat, 98 linear-gradient(currentColor 0 0) left bottom / 10px 1px no-repeat, 99 linear-gradient(currentColor 0 0) left bottom / 1px 10px no-repeat; 100 } 101 .cloud-item:hover::after { 102 inset-inline-end: -3px; 103 background: 104 linear-gradient(currentColor 0 0) right top / 10px 1px no-repeat, 105 linear-gradient(currentColor 0 0) right top / 1px 10px no-repeat, 106 linear-gradient(currentColor 0 0) right bottom / 10px 1px no-repeat, 107 linear-gradient(currentColor 0 0) right bottom / 1px 10px no-repeat; 108 } 109 </style>