<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Data Poems | Luke Steuber</title>

    <!-- Open Graph / Social Media -->
    <meta property="og:title" content="Data Poems | Luke Steuber">
    <meta property="og:description" content="Interactive explorations of data, inequality, and hidden patterns.">
    <meta property="og:image" content="https://dr.eamer.dev/datavis/poems/social-cards/forget-me-not.png">
    <meta property="og:url" content="https://datapoems.io">
    <meta property="og:type" content="website">

    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="Data Poems | Luke Steuber">
    <meta name="twitter:description" content="Interactive explorations of data, inequality, and hidden patterns.">
    <meta name="twitter:image" content="https://dr.eamer.dev/datavis/poems/social-cards/forget-me-not.png">

    <meta name="theme-color" content="#07090e">

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400&display=swap" rel="stylesheet">

    <style>
        :root {
            --bg: #07090e;
            --surface: #0a0c12;
            --text: #f1f4f8;
            --text-mid: #aab3c0;
            --text-soft: #79828f;
            --accent: #7aa2ff;
            --line: rgba(255, 255, 255, 0.12);
        }

        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

        body {
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            background: var(--bg);
            color: var(--text);
            font-size: 16px;
            line-height: 1.5;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }

        /* 3px navy rule across the top — matches lukesteuber.com */
        body::before {
            content: '';
            display: block;
            height: 3px;
            background: var(--accent);
        }

        a { color: var(--accent); text-decoration: none; transition: color 0.15s; }

        :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

        .sr-only {
            position: absolute; width: 1px; height: 1px;
            padding: 0; margin: -1px; overflow: hidden;
            clip: rect(0,0,0,0); white-space: nowrap; border: 0;
        }

        .skip-link {
            position: absolute; top: -40px; left: 0;
            background: var(--accent); color: #fff;
            padding: 8px 16px; text-decoration: none; z-index: 100;
        }
        .skip-link:focus { top: 3px; }

        /* Header — compact masthead; the grid is meant to dominate */
        .site-header {
            max-width: 1400px;
            margin: 0 auto;
            padding: 52px 24px 28px;
        }

        .site-header h1 {
            font-family: 'Cormorant Garamond', Georgia, serif;
            font-size: clamp(2.6rem, 5.5vw, 4rem);
            font-weight: 600;
            letter-spacing: -0.01em;
            line-height: 1.0;
            color: var(--text);
        }

        .site-header .tagline {
            font-family: 'Cormorant Garamond', Georgia, serif;
            font-style: italic;
            font-size: clamp(1.15rem, 2.2vw, 1.5rem);
            line-height: 1.4;
            color: var(--text-mid);
            margin-top: 8px;
        }

        .site-header .about {
            margin-top: 16px;
            font-size: 12px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.14em;
        }
        .site-header .about a { color: var(--text-soft); }
        .site-header .about a:hover,
        .site-header .about a:focus-visible { color: var(--accent); }

        /* Main — edge-to-edge grid bands */
        main {
            max-width: 1400px;
            margin: 0 auto;
            padding: 0 24px 8px;
        }

        /* Band label between grids */
        .band {
            display: flex;
            align-items: baseline;
            gap: 14px;
            margin: 40px 0 16px;
        }
        .band:first-of-type { margin-top: 8px; }
        .band h2 {
            font-size: 0.72rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.22em;
            color: var(--accent);
        }
        .band .band-count {
            font-size: 0.7rem;
            letter-spacing: 0.08em;
            color: var(--text-soft);
            font-variant-numeric: tabular-nums;
        }

        /* Collapsed "Parked" band — set-aside pieces, lower visual priority */
        .parked { margin-top: 44px; }
        .parked > summary {
            display: flex;
            align-items: baseline;
            gap: 14px;
            min-height: 44px;
            padding: 12px 0;
            list-style: none;
            cursor: pointer;
            border-top: 1px solid var(--line);
            transition: color 0.2s ease;
        }
        .parked > summary::-webkit-details-marker { display: none; }
        .parked > summary::before {
            content: "\25B8";          /* collapsed: right triangle */
            align-self: center;
            font-size: 0.7rem;
            color: var(--text-soft);
            transition: color 0.2s ease;
        }
        .parked[open] > summary::before { content: "\25BE"; }   /* open: down triangle */
        .parked .summary-label {
            font-size: 0.72rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.22em;
            color: var(--text-soft);
        }
        .parked > summary:hover .summary-label,
        .parked > summary:hover::before { color: var(--text); }
        .parked > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
        .parked .band-count {
            font-size: 0.7rem;
            letter-spacing: 0.08em;
            color: var(--text-soft);
            font-variant-numeric: tabular-nums;
        }
        .parked .grid { margin-top: 16px; }

        /* ---- The chip grid ---- */
        .grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            border-top: 1px solid var(--line);
            border-left: 1px solid var(--line);
        }
        @media (min-width: 720px)  { .grid { grid-template-columns: repeat(3, 1fr); } }
        @media (min-width: 1040px) { .grid { grid-template-columns: repeat(4, 1fr); } }

        .chip {
            position: relative;
            display: block;
            aspect-ratio: 1 / 1;
            border-right: 1px solid var(--line);
            border-bottom: 1px solid var(--line);
            overflow: hidden;
            text-decoration: none;
            color: inherit;
            background: #0a0c12;
            -webkit-tap-highlight-color: transparent;
        }

        /* Poster (img) and the looping clip (video) share the same box. The video
           sits above the poster and fades in once it starts playing, so the tile
           paints instantly and gains motion a beat later. */
        .chip .thumb,
        .chip .loop {
            position: absolute;
            inset: 0;
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
            transition: transform 0.6s ease, opacity 0.5s ease;
        }
        .chip .thumb { z-index: 1; }
        .chip .loop  { z-index: 2; opacity: 0; }
        .chip.is-playing .loop { opacity: 1; }

        /* Persistent caption — name + subtitle, legible over any imagery via a
           bottom scrim. The description fades in on hover/focus/tap. This is the
           "more information" the bare music grid lacks. */
        .chip .cap {
            position: absolute;
            left: 0; right: 0; bottom: 0;
            z-index: 4;
            padding: 30px 14px 12px;
            background: linear-gradient(to top, rgba(6, 8, 15, 0.94) 0%, rgba(6, 8, 15, 0.66) 50%, transparent 100%);
            pointer-events: none;
        }
        .chip .cap-name {
            display: block;
            font-family: 'Cormorant Garamond', Georgia, serif;
            font-size: clamp(17px, 2.2vw, 21px);
            font-weight: 600;
            line-height: 1.08;
            color: #fff;
        }
        .chip .cap-sub {
            display: block;
            margin-top: 3px;
            font-size: 10.5px;
            line-height: 1.35;
            letter-spacing: 0.01em;
            color: rgba(220, 232, 245, 0.82);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .chip .cap-desc {
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            overflow: hidden;
            max-height: 0;
            margin-top: 0;
            font-size: 11px;
            line-height: 1.45;
            color: rgba(220, 232, 245, 0.78);
            opacity: 0;
            transition: opacity 0.3s ease, max-height 0.3s ease, margin-top 0.3s ease;
        }
        .chip:hover .cap-desc,
        .chip:focus-visible .cap-desc,
        .chip.show .cap-desc {
            opacity: 1;
            max-height: 7em;
            margin-top: 7px;
        }

        /* LIVE / popular markers, pinned top-right — persistent */
        .chip .flags {
            position: absolute;
            top: 10px; right: 10px;
            z-index: 5;
            display: flex;
            gap: 6px;
            pointer-events: none;
        }
        .chip .flag {
            font-size: 8.5px;
            font-weight: 700;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            padding: 3px 6px;
            border-radius: 3px;
            background: rgba(6, 8, 15, 0.72);
            color: rgba(220, 232, 245, 0.9);
            backdrop-filter: blur(3px);
        }
        .chip .flag-live { color: #fff; }
        .chip .flag-live::before {
            content: '';
            display: inline-block;
            width: 5px; height: 5px;
            margin-right: 4px;
            border-radius: 50%;
            background: #34d399;
            box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.6);
            animation: live-pulse 2s infinite;
            vertical-align: middle;
        }
        @keyframes live-pulse {
            0%   { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.55); }
            70%  { box-shadow: 0 0 0 6px rgba(52, 211, 153, 0); }
            100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0); }
        }

        .chip .num {
            position: absolute;
            top: 11px; left: 13px;
            z-index: 5;
            font-size: 10px;
            letter-spacing: 2px;
            color: rgba(255, 255, 255, 0.6);
            font-variant-numeric: tabular-nums;
            text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
            opacity: 0;
            transition: opacity 0.3s ease;
        }
        .chip:hover .num,
        .chip:focus-visible .num,
        .chip.show .num { opacity: 1; }

        .chip:hover .thumb,
        .chip:focus-visible .thumb,
        .chip.show .thumb,
        .chip:hover .loop,
        .chip:focus-visible .loop,
        .chip.show .loop { transform: scale(1.04); }

        .chip:focus-visible { outline: none; }
        .chip:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }

        @media (prefers-reduced-motion: reduce) {
            *, *::before, *::after { transition: none !important; animation: none !important; }
            .chip:hover .thumb, .chip.show .thumb, .chip:focus-visible .thumb,
            .chip:hover .loop, .chip.show .loop, .chip:focus-visible .loop { transform: none; }
        }

        @media (forced-colors: active) {
            .chip { border: 1px solid ButtonText; }
            .chip .cap { background: Canvas; }
            .chip .cap-name, .chip .cap-sub, .chip .cap-desc { color: CanvasText; }
        }

        /* Footer */
        .site-footer {
            max-width: 1400px;
            margin: 56px auto 0;
            padding: 32px 24px 48px;
            border-top: 1px solid var(--line);
            font-size: 0.85rem;
            color: var(--text-soft);
        }

        .footer-links {
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
            margin-bottom: 20px;
            list-style: none;
        }

        .footer-links img {
            display: block;
            filter: grayscale(1);
            opacity: 0.7;
            transition: filter 0.15s, opacity 0.15s;
        }
        .footer-links a:hover img,
        .footer-links a:focus-visible img {
            filter: grayscale(0);
            opacity: 1;
        }

        .footer-nav {
            list-style: none;
            display: flex;
            gap: 20px;
            flex-wrap: wrap;
            margin-bottom: 14px;
        }

        .footer-nav a { color: var(--text-mid); font-weight: 500; }
        .footer-nav a:hover { color: var(--accent); }

        .footer-meta { font-size: 0.8rem; color: var(--text-soft); }
        .footer-meta a { color: var(--text-mid); }
        .footer-meta a:hover { color: var(--accent); }

        @media (max-width: 620px) {
            .site-header { padding: 40px 16px 22px; }
            main { padding: 0 16px 8px; }
            .site-footer { padding: 24px 16px 40px; }
        }
    </style>
</head>

<body>

    <a href="#main-content" class="skip-link">Skip to main content</a>

    <header class="site-header">
        <h1>Data Poems</h1>
        <p class="tagline">Stories I like to tell with numbers.</p>
        <p class="about"><a href="https://lukesteuber.com">about me &rarr;</a></p>
    </header>

    <main id="main-content">
        <div id="strips-container"></div>

        <noscript>
            <p style="color:var(--text-mid);margin:24px 0;">
                JavaScript is required to display visualizations.
                Browse all visualizations at <a href="/datavis/gallery/">the gallery</a>.
            </p>
        </noscript>
    </main>

    <footer class="site-footer">
        <ul class="footer-links" aria-label="Profiles">
            <li><a href="https://github.com/lukeslp" target="_blank" rel="noopener noreferrer" aria-label="GitHub"><img src="https://img.shields.io/badge/GitHub-lukeslp-181717?style=flat-square&logo=github" alt="GitHub" loading="lazy" height="20"></a></li>
            <li><a href="https://huggingface.co/lukeslp" target="_blank" rel="noopener noreferrer" aria-label="Hugging Face"><img src="https://img.shields.io/badge/HuggingFace-lukeslp-ffd21e?style=flat-square&logo=huggingface&logoColor=000" alt="Hugging Face" loading="lazy" height="20"></a></li>
            <li><a href="https://www.kaggle.com/lucassteuber" target="_blank" rel="noopener noreferrer" aria-label="Kaggle"><img src="https://img.shields.io/badge/Kaggle-lucassteuber-20beff?style=flat-square&logo=kaggle&logoColor=white" alt="Kaggle" loading="lazy" height="20"></a></li>
            <li><a href="https://codepen.io/lukeslp" target="_blank" rel="noopener noreferrer" aria-label="CodePen"><img src="https://img.shields.io/badge/CodePen-lukeslp-1e1f26?style=flat-square&logo=codepen" alt="CodePen" loading="lazy" height="20"></a></li>
        </ul>
        <ul class="footer-nav">
            <li><a href="https://lukesteuber.com" target="_blank" rel="noopener noreferrer">about me</a></li>
            <li><a href="https://dr.eamer.dev">other projects</a></li>
            <li><a href="/portfolio/">portfolio</a></li>
            <li><a href="/code/">code &amp; open source</a></li>
            <li><a href="/datavis/data_trove/">data trove</a></li>
        </ul>
        <p class="footer-meta">
            <a href="mailto:luke@lukesteuber.com">luke@lukesteuber.com</a>
        </p>
    </footer>

    <script src="/datavis/cards.js?v=8" defer></script>
    <!-- GoatCounter Analytics -->
    <script data-goatcounter="https://stats.dr.eamer.dev/count"
            async src="https://stats.dr.eamer.dev/count.js"></script>
</body>

</html>
