/* things.css — the index of built things.
   Inherits tokens, fonts and the particles canvas from styles.css.
   Layout here is an index, not a bento grid: a year gutter carries the
   vertical rhythm and every entry is a row in a document. */

.page {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 40px 120px;
    position: relative;
    z-index: 1;
}

/* --- Hero --- */

.hero {
    padding: 112px 0 96px;
    max-width: 820px;
}

.hero h1 {
    font-family: 'Bricolage Grotesque', 'Inter', sans-serif;
    font-size: clamp(40px, 6.4vw, 76px);
    font-weight: 800;
    line-height: 1.02;
    letter-spacing: -0.03em;
    margin-bottom: 28px;
}

.hero-lead {
    font-size: clamp(17px, 2vw, 20px);
    line-height: 1.65;
    color: var(--color-text-secondary);
    max-width: 62ch;
}

.hero-lead + .hero-lead {
    margin-top: 16px;
}

.hero-lead strong {
    color: var(--color-text);
    font-weight: 600;
}

/* --- Sections --- */

.section {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 72px;
    padding-top: 56px;
    border-top: 1px solid var(--color-border);
}

.section + .section {
    margin-top: 88px;
}

.section-aside {
    position: sticky;
    top: 116px;
    align-self: start;
}

.section-aside h2 {
    font-family: 'Bricolage Grotesque', 'Inter', sans-serif;
    font-size: 27px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
    margin-bottom: 14px;
}

.section-aside p {
    font-size: 14px;
    line-height: 1.65;
    color: var(--color-text-secondary);
}

.section-count {
    margin-top: 18px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-accent);
    font-variant-numeric: tabular-nums;
}

/* --- Entries --- */

.entry {
    display: grid;
    grid-template-columns: 66px 1fr;
    gap: 28px;
    padding: 30px 0;
    border-top: 1px solid var(--color-border);
}

.entry:first-child {
    border-top: 0;
    padding-top: 0;
}

.entry-year {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
    padding-top: 5px;
    transition: color 0.2s;
}

.entry:hover .entry-year {
    color: var(--color-accent);
}

.entry h3 {
    font-family: 'Bricolage Grotesque', 'Inter', sans-serif;
    font-size: 25px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
    margin-bottom: 10px;
}

.entry-role {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-accent);
    margin-bottom: 10px;
}

.entry p {
    font-size: 16px;
    line-height: 1.68;
    color: var(--color-text-secondary);
    max-width: 66ch;
}

.entry p + p {
    margin-top: 12px;
}

.entry-note {
    display: inline-block;
    margin-top: 12px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--color-text-secondary);
    border-left: 2px solid var(--color-border);
    padding-left: 12px;
    max-width: 60ch;
}

/* --- Entry links --- */

.entry-links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 18px;
}

.entry-links a {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 13px;
    border-radius: 9px;
    background: rgba(74, 85, 104, 0.08);
    font-size: 13px;
    font-weight: 600;
    color: var(--color-accent);
    text-decoration: none;
    transition: background-color 0.2s;
}

.entry-links a:hover {
    background: rgba(74, 85, 104, 0.16);
}

.entry-links a svg {
    flex: none;
    opacity: 0.75;
}

.entry-links a.is-primary {
    background: var(--color-accent);
    color: #fff;
}

.entry-links a.is-primary:hover {
    background: #2D3748;
}

/* --- Episode list (a real sequence, so it is numbered) --- */

.episodes {
    margin-top: 20px;
    border: 1px solid var(--color-border);
    border-radius: 16px;
    background: var(--color-card);
    overflow: hidden;
    counter-reset: episode;
    list-style: none;
}

.episodes li + li {
    border-top: 1px solid var(--color-border);
}

.episodes a {
    display: grid;
    grid-template-columns: 34px 1fr auto;
    align-items: baseline;
    gap: 14px;
    padding: 13px 18px;
    text-decoration: none;
    color: var(--color-text);
    transition: background-color 0.2s;
}

.episodes a:hover {
    background: rgba(74, 85, 104, 0.05);
}

.episodes a::before {
    counter-increment: episode;
    content: counter(episode, decimal-leading-zero);
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
}

.episode-title {
    font-size: 15px;
    font-weight: 500;
    line-height: 1.45;
}

.episode-title span {
    display: block;
    font-size: 13px;
    font-weight: 400;
    color: var(--color-text-secondary);
    margin-top: 2px;
}

.episode-date {
    font-size: 12px;
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --- Footer --- */

.page-footer {
    margin-top: 104px;
    padding-top: 36px;
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    font-size: 14px;
    color: var(--color-text-secondary);
}

.page-footer a {
    color: var(--color-accent);
    font-weight: 600;
    text-decoration: none;
}

.page-footer a:hover {
    text-decoration: underline;
}

/* --- Focus visibility --- */

a:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* --- One orchestrated page-load reveal, hero only --- */

.hero h1,
.hero-lead {
    opacity: 0;
    transform: translateY(14px);
    animation: heroIn 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.hero-lead {
    animation-delay: 0.1s;
}

.hero-lead + .hero-lead {
    animation-delay: 0.16s;
}

@keyframes heroIn {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero h1,
    .hero-lead {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* --- Responsive --- */

@media (max-width: 900px) {
    .page {
        padding: 0 22px 80px;
    }

    .hero {
        padding: 64px 0 64px;
    }

    .section {
        grid-template-columns: 1fr;
        gap: 32px;
        padding-top: 40px;
    }

    .section + .section {
        margin-top: 60px;
    }

    .section-aside {
        position: static;
    }

    .section-count {
        margin-top: 12px;
    }

    .entry {
        grid-template-columns: 1fr;
        gap: 8px;
        padding: 26px 0;
    }

    .entry-year {
        padding-top: 0;
        font-size: 13px;
    }

    .entry h3 {
        font-size: 22px;
    }

    .episodes a {
        grid-template-columns: 26px 1fr;
        gap: 11px;
        padding: 12px 14px;
    }

    .episode-date {
        grid-column: 2;
        margin-top: 3px;
    }
}

/* --- Entry previews ---
   Three frames, because the frame itself says what kind of thing you are
   looking at. A website sits in browser chrome carrying its real domain; a
   video gets a play badge and loads its embed only when clicked; everything
   else — photographs, a rendered banner, a designed tile — gets a plain
   soft frame.

   The chrome is drawn here rather than baked into the capture, so the domain
   stays selectable text and a re-shot screenshot drops straight in. */

.entry-preview {
    margin: 22px 0 0;
}

.preview-frame {
    position: relative;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--color-card);
    box-shadow: 0 10px 30px rgba(45, 55, 72, 0.07);
}

.entry-preview img {
    display: block;
    width: 100%;
    height: auto;
    /* Holds the row's height before the image decodes, so nothing jumps */
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: top center;
    background: rgba(74, 85, 104, 0.05);
}

.entry-preview a {
    display: block;
    text-decoration: none;
}

/* Site frame */

.preview-chrome {
    display: flex;
    align-items: center;
    padding: 9px 13px;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary);
    letter-spacing: 0.01em;
}

/* One element, three dots — no extra markup in every entry */
.preview-dots {
    flex: none;
    width: 9px;
    height: 9px;
    margin-right: 40px;
    border-radius: 50%;
    background: rgba(74, 85, 104, 0.2);
    box-shadow: 15px 0 0 rgba(74, 85, 104, 0.2),
                30px 0 0 rgba(74, 85, 104, 0.2);
}

.entry-preview.is-site a:hover .preview-frame {
    box-shadow: 0 14px 38px rgba(45, 55, 72, 0.13);
}

.entry-preview.is-site img {
    aspect-ratio: 16 / 9.4;
}

/* Video frame — poster until asked for */

.entry-preview.is-video .preview-frame {
    cursor: pointer;
}

.entry-preview.is-video img {
    aspect-ratio: 16 / 9;
    object-position: center;
}

.preview-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    width: 100%;
    padding: 0;
    background: rgba(26, 32, 44, 0.16);
    cursor: pointer;
    transition: background-color 0.2s;
}

.preview-play:hover {
    background: rgba(26, 32, 44, 0.06);
}

.preview-play span {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 62px;
    height: 62px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 6px 20px rgba(26, 32, 44, 0.25);
    transition: transform 0.2s;
}

.preview-play:hover span {
    transform: scale(1.07);
}

.preview-play svg {
    margin-left: 3px;
    color: var(--color-accent);
}

.entry-preview iframe {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
}

/* Photographs and rendered artifacts keep their own proportions — a wide
   panorama of a stage should not be cropped into a website-shaped box. */
.entry-preview.is-flat img {
    aspect-ratio: auto;
    object-fit: contain;
}

.entry-preview figcaption {
    margin-top: 9px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

@media (max-width: 680px) {
    .entry-preview {
        margin-top: 18px;
    }

    .preview-frame {
        border-radius: 10px;
    }

    .preview-dots {
        margin-right: 32px;
    }

    .preview-play span {
        width: 50px;
        height: 50px;
    }
}

/* An extension popup is 360px wide in real life; blowing it up to the width
   of the column would be a lie about its size and blurry besides. */
.entry-preview.is-narrow .preview-frame {
    max-width: 360px;
}

/* A display banner is 728x90 or 300x250 — real ad sizes, not page-shaped.
   Let it keep its own proportions and sit on the card ground. */
/* An explicit ratio, not auto: with auto the box has no height until the
   image decodes, the lazy loader never sees it intersect the viewport, and
   it therefore never decodes. Reserving the height breaks that deadlock. */
.entry-preview.is-banner img {
    aspect-ratio: 1448 / 176;
    object-fit: contain;
}

/* These creatives are mostly white. On a white page they read as nothing,
   so the frame becomes a slot they visibly sit inside. */
.entry-preview.is-banner .preview-frame {
    background: rgba(74, 85, 104, 0.07);
    padding: 20px;
}

.entry-preview.is-banner img {
    box-shadow: 0 1px 4px rgba(45, 55, 72, 0.14);
}
