
.md-main { max-width: 60em; margin: auto; padding: 2em; }
.md-main h1 { font-size: 20vmin; }
.article-intro { flex: 1 1 100vw; margin-bottom: 2em; }

/* centered page bands (intro / blog) keep the old 60em measure */
.page-band { width: min(60em, 100%); margin-inline: auto; padding: var(--space-4); }

/* Gentle scroll-snap: each full-height section settles into view without
   fighting the reader (proximity only snaps when a section is already near).
   overflow-x: clip keeps the butterfly's off-screen start/flight from widening
   the page (clip doesn't turn html into a scroll container, so snap is safe). */
html { scroll-snap-type: y proximity; overflow-x: clip; }
.hero, .interest-section { scroll-snap-align: start; }
/* The footer gets its own snap point at the very bottom; without it the last
   full-height section's snap-start sits just above max scroll and proximity
   keeps pulling back up, hiding the footer. */
#footer { scroll-snap-align: end; }

/* Small screens: drop scroll-snap (it fights natural phone scrolling) and the
   big full-height section padding. Text/spacing shrink globally via base.css. */
@media (max-width: 44em) {
   html { scroll-snap-type: none; }
   .hero, .interest-section { scroll-snap-align: none; }
}


/* ── Hero ──────────────────────────────────────────────────────────
   Full-viewport landing: portrait + name, an emoji table-of-contents
   of every interest (hover reveals the title), and the latest notes. */
.hero {
   min-height: 100vh;
   width: min(60em, 100%);
   margin-inline: auto;
   padding: var(--space-6) var(--space-4);
   display: flex;
   flex-direction: column;
   justify-content: center;
   gap: var(--space-4);
}

.hero-head { display: flex; align-items: center; gap: var(--space-3); }
.hero-portrait {
   flex: none;
   width: 6rem; height: 6rem;
   border-radius: 50%;
   object-fit: cover;
   border: 3px solid var(--surface-2);
   box-shadow: var(--shadow-2);
}
.hero-title {
   margin: 0;
   font-size: clamp(2.5rem, 8vmin, 5rem);
   line-height: 1.05;
   color: var(--text-1);
}
.hero-tagline { margin: var(--half) 0 0; max-width: 44ch; color: var(--text-2); font-size: 1.25rem; line-height: 1.5; }

/* interest table-of-contents */
.toc-label, .notes-label {
   margin: 0 0 var(--space-1);
   color: var(--text-2);
   text-transform: uppercase;
   letter-spacing: 0.1em;
   font-size: 0.8rem;
}
.notes-label a { color: var(--text-2); font-weight: 600; }

.toc-icons { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: var(--half); }
.toc-icons li { margin: 0; }
.toc-icon {
   position: relative;
   display: flex; align-items: center; justify-content: center;
   width: 2.75rem; height: 2.75rem;
   font-size: 1.5rem;
   border-radius: var(--br);
   background: color-mix(in srgb, var(--surface-2) 80%, transparent);
   transition: transform 0.15s ease, background 0.15s ease;
}
.toc-icon::after { display: none; }               /* kill the base link underline */
@media (hover: hover) {
   .toc-icon:hover { transform: translateY(-3px); background: var(--surface-3); }
}
/* title tooltip on hover / focus */
.toc-icon::before {
   content: attr(data-title);
   position: absolute;
   bottom: calc(100% + 0.4rem);
   left: 50%;
   transform: translateX(-50%) translateY(0.25rem);
   padding: 0.2em 0.6em;
   border-radius: var(--br);
   background: var(--surface-4);
   color: var(--text-1);
   font-size: 0.8rem;
   font-weight: 600;
   white-space: nowrap;
   opacity: 0;
   pointer-events: none;
   box-shadow: var(--shadow-1);
   transition: opacity 0.15s ease, transform 0.15s ease;
   z-index: 5;
}
.toc-icon:hover::before,
.toc-icon:focus-visible::before { opacity: 1; transform: translateX(-50%) translateY(0); }

.hero-notes .blog-posts { max-width: 40em; }

@media (max-width: 44em) {
   .hero-head { flex-direction: column; align-items: flex-start; text-align: left; }
}


/* ── Project banners ───────────────────────────────────────────────
   Each flagship project is just its icon + title (no card, no background),
   sitting under the interest graphic. Hovering grows a solid, rounded
   outline around the whole thing. */
.project-banner {
   position: relative;
   display: inline-flex;
   align-items: center;
   gap: var(--space-1);
   padding: var(--half);
   color: var(--text-1);
}
/* Hover: a solid rounded outline that grows in around the container.
   width/height/background are reset so it's a full box, not the base
   link underline (which only draws a line at the bottom edge). */
.project-banner::after {
   content: "";
   position: absolute;
   inset: 0;
   width: auto;
   height: auto;
   background: none;
   border: 2px solid var(--primary);
   border-radius: 0.9rem;
   opacity: 0;
   transform: scale(0.8);
   transition: opacity 0.25s ease, transform 0.25s ease;
   pointer-events: none;
}
@media (hover: hover) {
   .project-banner:hover::after { opacity: 1; transform: scale(1); }
}

.project-cover {
   position: relative;
   flex: none;
   width: 3.25rem;
   height: 3.25rem;
   display: grid;
   place-items: center;
}
.project-cover img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* Rounded project icons (square is the default). */
.project-cover.rounded img { border-radius: 22%; }

/* Exception: a wide wordmark logo (e.g. schubu) shows 3× the icon size and
   drops the title, so it stands on its own. */
.project-banner.has-big-logo .project-cover {
   width: auto;
   height: auto;
}
.project-banner.has-big-logo .project-cover img {
   width: 9.75rem;          /* 3× the 3.25rem icon slot */
   max-width: none;
   max-height: none;
   height: auto;
   background: var(--surface-2);   /* light in light mode, dark in dark mode */
   padding: var(--half);
   border-radius: var(--br);
}
.project-emoji {
   font-size: clamp(1.75rem, 5vmin, 2.75rem);
   line-height: 1;
   filter: drop-shadow(0 3px 8px hsl(var(--hue) 40% 15% / 0.4));
   user-select: none;
}

/* Baked emoji images (tools/render_emoji.py) sit inside the emoji wrappers and
   scale to their font-size, so they match what the glyphs used to occupy. */
.emoji-img {
   display: block;
   width: 1.15em;
   height: 1.15em;
   object-fit: contain;
   user-select: none;
   -webkit-user-drag: none;
}

.project-name {
   margin: 0;
   font-size: clamp(0.9rem, 2vmin, 1.3rem);
   line-height: 1.1;
   font-weight: 700;
   color: var(--text-1);
}
.project-name .tld { color: var(--text-2); font-weight: 400; }


/* ── Full-height interest sections ─────────────────────────────────
   Each <section> carries color-scheme="<key>", so its whole palette
   (surfaces, text, primary) is the interest's hue. Backgrounds are
   slightly translucent so the baseline dot-grid shows through, and
   alternate tone + graphic side for vertical rhythm. */
.interest-sections { display: block; }

.interest-section {
   min-height: 100vh;
   display: grid;
   place-items: center;
   padding: var(--space-8) var(--space-4);
   /* kept very light so the baseline dot grid reads through the section */
   background-color: color-mix(in srgb, var(--surface-1) 15%, transparent);
   color: var(--text-1);
   transition: background-color 1s ease, color 1s ease;
}
.interest-section:nth-of-type(even) {
   background-color: color-mix(in srgb, var(--surface-2) 24%, transparent);
}
/* Small screens: drop the big full-height section padding. */
@media (max-width: 44em) {
   .interest-section { min-height: auto; padding: var(--space-2) var(--space-1); }
}

.interest-inner {
   width: min(56em, 100%);
   display: flex;
   align-items: center;
   gap: var(--space-6);
}
.interest-section:nth-of-type(even) .interest-inner { flex-direction: row-reverse; }

.interest-body { flex: 1 1 58%; }
/* Right-hand column: the interest graphic with its project banner below. */
.interest-graphic-col {
   flex: 1 1 42%;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
   gap: var(--space-2);
}
.interest-graphic {
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: clamp(4rem, 14vmin, 9rem);
   line-height: 1;
   user-select: none;
   /* placeholder until the pixel-art slice replaces it */
}

.interest-title {
   margin: 0 0 var(--space-1);
   font-size: clamp(2rem, 6vmin, 3.5rem);
   line-height: 1.1;
   color: var(--primary);
}
.interest-blurb {
   margin: 0 0 var(--space-2);
   max-width: 42ch;
   color: var(--text-2);
   font-size: 1.25rem;
}

.interest-posts { list-style: none; padding-left: 0; margin: var(--space-2) 0 0; }
.interest-posts li {
   display: grid;
   grid-template-columns: 6.5em 1fr;
   align-items: baseline;
   gap: 0 1ch;
   padding: 0.15em 0;
}
.interest-posts li small { color: var(--text-2); opacity: 0.6; font-size: 0.85em; }
.interest-posts li a { color: var(--text-1); }
.interest-posts li a::after { background-color: var(--primary); }
.interest-posts .interest-empty {
   display: block;
   color: var(--text-2);
   opacity: 0.55;
   font-style: italic;
}

@media (max-width: 44em) {
   .interest-inner,
   .interest-section:nth-of-type(even) .interest-inner {
      flex-direction: column;
      align-items: center;
      text-align: center;
      gap: var(--space-1);
   }
   /* Flatten the two columns into one flex stack so the pieces can always be
      ordered icon → title → paragraph → blog entries → project banners,
      regardless of the desktop left/right alternation. */
   .interest-body,
   .interest-graphic-col { display: contents; }
   .interest-graphic { order: 1; }
   .interest-title   { order: 2; margin: 0; }
   .interest-blurb   { order: 3; margin: 0 auto; }
   .interest-posts   { order: 4; margin: 0; }
   .interest-graphic-col .project-banner { order: 5; }
}


/* ── Smaller collection cards (books / links / movies / butterflies) ── */
.minor-interests {
   width: min(56em, 100%);
   margin: var(--space-8) auto;
   padding-inline: var(--space-4);
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(13em, 1fr));
   gap: var(--space-2);
}
.minor-card {
   color: var(--text-1);
   background-color: color-mix(in srgb, var(--surface-2) 90%, transparent);
   border: 1px solid var(--surface-3);
   border-radius: var(--br);
   padding: var(--space-3);
}
.minor-card h3 { margin: 0 0 var(--space-1); color: var(--primary); font-size: 1.4rem; }
.minor-card p { margin: 0; font-size: 1rem; color: var(--text-2); }
.minor-card .minor-emoji { font-size: 2.2rem; line-height: 1; display: block; margin-bottom: var(--space-1); }
.minor-card h3 a { color: inherit; }
.minor-cta { display: inline-block; margin-top: var(--space-1); font-weight: 700; color: var(--primary); }


.projects-list {
   display: flex; justify-content: flex-start; align-items: center; flex-wrap: wrap;

   li { list-style: none; margin: 0.5em; }
   img { height: 5em; width: 5em; padding: 0.5em; object-fit: contain; }
}

.project-link { 
   text-decoration: none; transition: color 0.3s;

   &:hover { color: #0056b3; }
   &:hover::after { display: none; }
}


/* Butterfly styles now live site-wide in base.css. */

/* Homepage has its own hero, so the site-wide back-arrow header is hidden. */
header { display: none; }



.article-blog { flex: 1 1 60em; }

.articles-list { padding-left: 0; }

.blog-article-link { padding: 0.1em 0.3em; text-decoration: none; color: var(--text-1); transition: background 0.3s ease-in-out; }
.blog-article-link { display: grid; grid-template-columns: 3.5em 1fr auto; }
.blog-article-link a::after { display: none; }
.blog-article-link:hover { background-color: var(--surface-2); }
.blog-article-link span { display: block; }
.blog-article-link date { font-size: 0.5em; }
.blog-article-link small { opacity: 0.5; }
.blog-article-link img { height: 1em; width: auto; }











footer {
   display: flex;
   justify-content: center;
   column-gap: 1em;
   padding: 1em 0;
}


/* ── Interest scrubber ──────────────────────────────────────────────
   Fixed vertical white pill of interest emojis. Hover reveals the
   label; pressing and dragging along it scrubs straight to sections. */
.scrubber {
   position: fixed;
   right: var(--space-2);
   top: 50%;
   transform: translateY(-50%);
   z-index: 9000;               /* under the butterfly (9999) */
   pointer-events: none;        /* only the track is interactive */
}
.scrubber-track {
   position: relative;
   pointer-events: auto;
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 1px;
   padding: 7px 5px;
   background: var(--surface-2); /* white-ish in light, dark surface in dark */
   border-radius: 999px;        /* very tall pill */
   box-shadow: 0 8px 28px rgba(0, 0, 0, 0.16), 0 1px 4px rgba(0, 0, 0, 0.10);
   touch-action: none;          /* we drive the jump ourselves */
}
.scrubber-item {
   position: relative;
   display: flex;
   align-items: center;
   justify-content: center;
   width: 28px; height: 28px;
   border-radius: 50%;
   font-size: 1rem;
   line-height: 1;
   text-decoration: none;
   transition: transform 0.12s ease, background-color 0.12s ease;
}
.scrubber-item::after { content: none; }   /* no global link underline */
.scrubber-emoji { pointer-events: none; }
/* selected item: just a slight background tint, no label */
.scrubber-item.is-active { background-color: var(--surface-3); }
/* hover: stronger highlight, enlarge, and reveal the label */
.scrubber-item:hover {
   background-color: var(--surface-4);
   transform: scale(1.35);
}
.scrubber-label {
   position: absolute;
   right: calc(100% + 12px);
   top: 50%;
   transform: translateY(-50%);
   white-space: nowrap;
   padding: 4px 11px;
   background: var(--surface-2);
   color: var(--text-1);
   font-size: 0.85rem;
   border-radius: 999px;
   box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
   opacity: 0;
   pointer-events: none;
   transition: opacity 0.12s ease;
}
.scrubber-item:hover .scrubber-label { opacity: 1; }

/* "My interests" annotation: centered above the bar, arrow pointing down onto it */
.scrubber-annotation {
   position: absolute;
   bottom: calc(100% + 4px);
   left: 50%;
   transform: translateX(-50%);
   display: flex;
   flex-direction: column;
   align-items: center;
   color: var(--text-2);
   pointer-events: none;
}
.scrubber-annotation-text {
   font-size: 0.95rem;
   font-weight: 600;
   white-space: nowrap;
   transform: translateX(-30%);   /* nudge the hint left; arrow stays put */
}
.scrubber-arrow { display: block; width: 40px; height: 44px; transform: translateX(-10px); }

@media (max-width: 720px) { .scrubber { display: none; } }

/* roomier spacing between items when the viewport is tall enough */
@media (min-height: 800px)  { .scrubber-track { gap: 5px; } }
@media (min-height: 1000px) { .scrubber-track { gap: 10px; } }