/* Swarm crests: decorative point-cloud emblems beside headings (see js/swarm-crests.js).
   Large crests are measured into clear space in the heading block; small ones follow
   section titles inline. Neither takes part in layout (both are out of flow or fixed-size). */
.swarm-crest { display: block; }
.swarm-crest canvas { display: block; width: 100%; height: 100%; }

/* Large: placed by js/swarm-crests.js in the largest clear square of the heading block,
   nearest the page's preferred spot (fractions of the block), capped by --crest-max.
   Hidden until measured, so it never appears in the wrong place first. Small phones allow
   a smaller emblem rather than none. */
:has(> .swarm-crest--lg) { position: relative; isolation: isolate; }
.swarm-crest.swarm-crest--lg {
  position: absolute;
  /* Above the heading's block boxes so hover reaches it; placement keeps it clear of text. */
  z-index: 1;
  left: 0;
  top: 0;
  width: 8rem;
  height: 8rem;
  opacity: .92;
  visibility: hidden;
}
.swarm-crest.swarm-crest--lg[data-placed="true"] { visibility: visible; }
/* Home: right of the headline's first lines, beside the availability pill. */
[data-crest="home"] { --crest-ax: .9; --crest-ay: .22; --crest-max: 230px; }
/* Portfolio: right of "My work,", above the actions. */
[data-crest="portfolio"] { --crest-ax: .88; --crest-ay: .3; --crest-max: 240px; }
/* AI Lab: between the headline and the laptop, level with the headline. */
[data-crest="ai-lab"] { --crest-ax: .52; --crest-ay: .45; --crest-max: 250px; }
/* Blog: the open corner of the hero card beside the introduction. */
[data-crest="blog"] { --crest-ax: .9; --crest-ay: .8; --crest-max: 220px; --crest-bleed: 16px; }
/* Phones stack AI Lab's hero centrally with no side space: a band above the badge holds
   the flask, centred like the rest of the column. */
@media (max-width: 600px) {
  [data-crest="ai-lab"] { --crest-ax: .5; --crest-ay: 0; --crest-max: 92px; }
  .hero:has(> [data-crest="ai-lab"]) .hero-badge { margin-top: 5.25rem; }
}
/* The laptop drawing leaves a clear margin inside its square canvas. */
.hero:has(> [data-crest="ai-lab"]) .hero-illustration { --crest-inset: .1; }
/* The blog introduction keeps a reading measure that leaves the crest its corner on
   tablets, where the paragraph would otherwise run the full card width. */
@media (min-width: 600px) {
  .hero-card:has(> [data-crest="blog"]) p { max-width: min(64ch, 100% - 12rem); }
}
/* Koda: beside the "Visit Koda's site" row. */
[data-crest="koda"] { --crest-ax: .9; --crest-ay: .85; --crest-max: 200px; --crest-bleed: 48px; }
/* Home's crest takes over from the older orbit ornament in the same corner. */
.hero:has([data-crest="home"]) .float-shape-1 { display: none; }

/* Small: inline after the section title, sized to the heading's cap height. */
.swarm-crest--sm {
  display: inline-block;
  width: 1.45em;
  height: 1.45em;
  margin-inline-start: .4em;
  vertical-align: -.28em;
}

@media (max-width: 600px) {
  .swarm-crest.swarm-crest--lg { --crest-min: 56px; }
  @media (max-width: 400px) { .swarm-crest.swarm-crest--lg { --crest-min: 44px; } }
  /* The book is wide and short: on phones it fits the strip beside the eyebrow. */
  .swarm-crest[data-crest="blog"] { --crest-min: 34px; }
}

/* Crests react to attention (js/swarm-crests.js animates the particles), but they are
   decoration, not controls: the default cursor, no focus, no pressed or link styling.
   The brightness lift is the only cue under reduced motion. */
.swarm-crest { pointer-events: auto; cursor: default; -webkit-tap-highlight-color: transparent; user-select: none; }
.swarm-crest canvas { transition: filter .35s ease; }
.swarm-crest:hover canvas { filter: saturate(1.2) brightness(1.08); }
@media (forced-colors: active), print {
  .swarm-crest { display: none; }
}
