146146 margin-top : 3rem ;
147147 }
148148
149+ details {
150+ border : 1px solid var (--border );
151+ border-radius : 6px ;
152+ padding : 0.75rem 1rem ;
153+ margin : 0.75rem 0 ;
154+ background : var (--code-bg );
155+ }
156+
157+ details [open ] {
158+ padding-bottom : 1rem ;
159+ }
160+
161+ summary {
162+ cursor : pointer;
163+ font-weight : 600 ;
164+ font-size : 1.1rem ;
165+ user-select : none;
166+ list-style : none;
167+ display : flex;
168+ align-items : center;
169+ gap : 0.5rem ;
170+ }
171+
172+ summary ::-webkit-details-marker {
173+ display : none;
174+ }
175+
176+ summary ::before {
177+ content : '▶' ;
178+ display : inline-block;
179+ transition : transform 0.2s ;
180+ font-size : 0.8em ;
181+ }
182+
183+ details [open ] summary ::before {
184+ transform : rotate (90deg );
185+ }
186+
187+ summary : hover {
188+ color : var (--link );
189+ }
190+
191+ details .content {
192+ margin-top : 1rem ;
193+ padding-left : 1.3rem ;
194+ }
195+
149196 footer {
150197 margin-top : 3rem ;
151198 padding-top : 2rem ;
@@ -170,7 +217,9 @@ <h1>Ricardo Decal's Tools</h1>
170217< p > This is an experiment in low-stakes vibe coding. The code lives in < a href ="https://github.com/crypdick/tools "> < code > crypdick/tools</ code > </ a > .</ p >
171218< p > Inspired by < a href ="https://github.com/simonw/tools "> Simon Willison's tools collection</ a > .</ p >
172219< h2 > Available Tools</ h2 >
173- < h3 > < a href ="python/convert_arrow_to_parquet_streaming.py "> convert_arrow_to_parquet_streaming.py</ a > </ h3 >
220+ < details >
221+ < summary > convert_arrow_to_parquet_streaming.py</ summary >
222+ < div class ="content ">
174223< p > Output of < code > uv run https://tools.ricardodecal.com/python/convert_arrow_to_parquet_streaming.py --help</ code > :</ p >
175224< pre > < code class ="language-text "> Usage: convert_arrow_to_parquet_streaming.py [OPTIONS]
176225
@@ -202,7 +251,11 @@ <h3><a href="python/convert_arrow_to_parquet_streaming.py">convert_arrow_to_parq
202251 dir
203252 --help Show this message and exit.
204253</ code > </ pre >
205- < h3 > < a href ="python/count_parquet_rows.py "> count_parquet_rows.py</ a > </ h3 >
254+ </ div >
255+ </ details >
256+ < details >
257+ < summary > count_parquet_rows.py</ summary >
258+ < div class ="content ">
206259< p > Output of < code > uv run https://tools.ricardodecal.com/python/count_parquet_rows.py --help</ code > :</ p >
207260< pre > < code class ="language-text "> Usage: count_parquet_rows.py [OPTIONS] DATASET_PATH
208261
@@ -232,7 +285,11 @@ <h3><a href="python/count_parquet_rows.py">count_parquet_rows.py</a></h3>
232285Options:
233286 --help Show this message and exit.
234287</ code > </ pre >
235- < h3 > < a href ="python/download_video.py "> download_video.py</ a > </ h3 >
288+ </ div >
289+ </ details >
290+ < details >
291+ < summary > download_video.py</ summary >
292+ < div class ="content ">
236293< p > Output of < code > uv run https://tools.ricardodecal.com/python/download_video.py --help</ code > :</ p >
237294< pre > < code class ="language-text "> Usage: download_video.py [OPTIONS] URL
238295
@@ -259,7 +316,11 @@ <h3><a href="python/download_video.py">download_video.py</a></h3>
259316 directory.
260317 --help Show this message and exit.
261318</ code > </ pre >
262- < h3 > < a href ="python/ipynb_to_py_sphinx.py "> ipynb_to_py_sphinx.py</ a > </ h3 >
319+ </ div >
320+ </ details >
321+ < details >
322+ < summary > ipynb_to_py_sphinx.py</ summary >
323+ < div class ="content ">
263324< p > Output of < code > uv run https://tools.ricardodecal.com/python/ipynb_to_py_sphinx.py --help</ code > :</ p >
264325< pre > < code class ="language-text "> Usage: ipynb_to_py_sphinx.py [OPTIONS] NOTEBOOK
265326
@@ -287,7 +348,11 @@ <h3><a href="python/ipynb_to_py_sphinx.py">ipynb_to_py_sphinx.py</a></h3>
287348 .py extension.
288349 --help Show this message and exit.
289350</ code > </ pre >
290- < h3 > < a href ="python/strip_pdf_metadata.py "> strip_pdf_metadata.py</ a > </ h3 >
351+ </ div >
352+ </ details >
353+ < details >
354+ < summary > strip_pdf_metadata.py</ summary >
355+ < div class ="content ">
291356< p > Output of < code > uv run https://tools.ricardodecal.com/python/strip_pdf_metadata.py --help</ code > :</ p >
292357< pre > < code class ="language-text "> Usage: strip_pdf_metadata.py [OPTIONS] INPUT_FILE [OUTPUT_FILE]
293358
@@ -298,7 +363,11 @@ <h3><a href="python/strip_pdf_metadata.py">strip_pdf_metadata.py</a></h3>
298363Options:
299364 --help Show this message and exit.
300365</ code > </ pre >
301- < h3 > < a href ="python/yt_transcript.py "> yt_transcript.py</ a > </ h3 >
366+ </ div >
367+ </ details >
368+ < details >
369+ < summary > yt_transcript.py</ summary >
370+ < div class ="content ">
302371< p > Output of < code > uv run https://tools.ricardodecal.com/python/yt_transcript.py --help</ code > :</ p >
303372< pre > < code class ="language-text "> Usage: yt_transcript.py [OPTIONS] URL [OUTPUT_FILE]
304373
@@ -318,6 +387,8 @@ <h3><a href="python/yt_transcript.py">yt_transcript.py</a></h3>
318387 -l, --lang TEXT Language codes to prefer (e.g. -l en -l fr)
319388 --help Show this message and exit.
320389</ code > </ pre >
390+ </ div >
391+ </ details >
321392< h2 > License</ h2 >
322393< p > < a href ="LICENSE "> Apache 2.0</ a > </ p >
323394
0 commit comments