/* Ledger page styles: home. Owned by the home page; shared component rules
   belong in assets/css/base.css under "Architectural Ledger blocks".

   The page is a stack of full-bleed bands that alternate on the surface
   ladder (background -> panel-contrast). Depth is tonal: no shadows, no
   radii, no hex literals — a hardcoded colour would break one of the two
   themes. */

/* ── Bands ── */
.home-ledger {
  display: block;
  width: 100%;
}

.home-band {
  position: relative;
  width: 100%;
  padding-block: var(--space-2xl);
  background-color: transparent;
  border-bottom: 1px solid var(--border-gentle);
}

.home-band--hero {
  background-color: var(--color-background);
}

.home-band--contrast {
  background-color: var(--color-panel-contrast);
  background-image: none;
}

.home-band:last-child {
  border-bottom: 0;
}

.home-band-inner {
  max-width: 80rem;
  margin-inline: auto;
  padding-inline: var(--gutter-mobile);
}

@media (min-width: 768px) {
  .home-band {
    padding-block: var(--space-3xl);
  }

  .home-band-inner {
    padding-inline: var(--gutter);
  }
}

/* ── Hero ── */
/* The band was 3rem above the name and 4.5rem below, which read as the block
   sitting low in its own space. Equal above and below, at 60% of the larger
   of the two, so the masthead is centred in the air around it. On desktop the
   photograph matches the copy column height at 3:4; on a phone it is 4:3
   full-bleed. */
.home-band--hero {
  padding-block: 2.7rem;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

/* The first band title is the LCP text. On a phone the hero padding and the
   gap under the copy were pushing that title just past the first viewport,
   so the paint waited on a later frame. */
@media (max-width: 767px) {
  .home-band--hero {
    padding-block: 1.75rem 1.25rem;
  }

  .home-hero {
    gap: var(--space-md);
  }
}

.home-band--hero .home-band-inner {
  position: relative;
  z-index: 1;
}

/* ── Hero art slot (site supplies art via pandorga.home.hero_art) ── */
.home-hero-art,
.home-hero-pandorga {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  opacity: 0.42;
}

.home-hero-art-svg {
  width: 100%;
  height: 100%;
  display: block;
}

@media (max-width: 639px) {
  .home-hero-art,
  .home-hero-pandorga {
    opacity: 0.28;
  }
}

/* Ambient pool behind the hero.
 *
 * Same weight as the earlier primary-container bloom, but keyed to neutral
 * ink/outline so it stays grey paper depth instead of a blue spotlight. */
.home-band--hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -18%;
  right: 8%;
  width: min(38rem, 60%);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle,
      color-mix(in srgb, var(--color-outline) 22%, transparent) 0%,
      color-mix(in srgb, var(--color-on-surface) 8%, transparent) 42%,
      transparent 72%);
  filter: blur(52px);
  pointer-events: none;
}

[data-theme="dark"] .home-band--hero::before {
  background: radial-gradient(circle,
      color-mix(in srgb, var(--color-on-surface) 10%, transparent) 0%,
      color-mix(in srgb, var(--color-outline) 8%, transparent) 50%,
      transparent 70%);
  filter: blur(60px);
}

@media (prefers-reduced-motion: no-preference) {
  .home-band--hero::before {
    transition: opacity var(--motion-duration-slow, 400ms) var(--motion-ease-default);
  }
}

.home-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}

@media (min-width: 1024px) {
  .home-hero {
    /* Copy content height sets the flex line. Portrait stretches to that
       height; aspect-ratio then sets W = 3/4 × H. Children are taken out of
       flow so the photo's intrinsic box cannot inflate the line or collapse
       the copy. */
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: var(--space-2xl);
  }

  .home-hero-copy {
    flex: 1 1 auto;
    min-width: min(100%, 20rem);
  }

  .home-hero-portrait {
    position: relative;
    flex: 0 0 auto;
    align-self: stretch;
    width: auto;
    height: auto;
    aspect-ratio: 3 / 4;
    overflow: hidden;
    min-width: 0;
    min-height: 0;
    max-width: none;
    justify-self: unset;
  }

  .home-hero-plate-wrap {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    flex: none;
  }

  .home-hero-plate {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    flex: none;
  }

  .home-hero-plate img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
  }
}

.home-hero-copy {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  min-width: 0;
  container-type: inline-size;
}

.home-hero-tagline {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 0 var(--space-sm);
  color: var(--color-on-surface);
  font-family: var(--font-label);
  /* Same size as the summary under the name, which inherits --type-body. */
  font-size: var(--type-body);
  font-weight: var(--weight-label);
  letter-spacing: 0.03em;
  line-height: 1.35;
  max-width: 100%;
}

.home-hero-tagline::after {
  content: "";
  flex: 1 1 auto;
  height: 0;
  border-top: 1px dashed color-mix(in srgb, var(--color-outline) 45%, transparent);
  min-width: 1.5rem;
}

.home-hero-tagline p {
  margin: 0;
}

.home-hero-tagline:empty {
  min-height: calc(var(--type-body) * 1.35);
}

/* Name spans the copy column (container query on .home-hero-copy). The floor
   is the band-title step — Articles, Rascunhos, Projects — so a phone does
   not drop the name to the card size to keep it on one line. From 640px the
   floor follows `.section-title` up to `--type-section-lg`. Wider columns
   still grow toward `--type-page-lg`. */
.home-hero-title {
  font-family: var(--font-title);
  font-weight: 400;
  font-size: clamp(var(--type-section), calc(100cqi * 0.92 / 14.5), var(--type-page-lg));
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--color-on-surface);
  font-synthesis: none;
  font-optical-sizing: auto;
  margin: 0 0 var(--space-xl);
  max-width: 100%;
}

.home-hero-given,
.home-hero-family {
  display: inline;
}

.home-hero-family {
  color: var(--color-primary);
}

@media (min-width: 640px) {
  .home-hero-title {
    font-size: clamp(var(--type-section-lg), calc(100cqi * 0.92 / 14.5), var(--type-page-lg));
  }
}

/* Below 768px the name is 3pt larger than the clamp above, and the only
   wrap point is the gap between the given name and the family name. */
@media (max-width: 639px) {
  .home-hero-title {
    white-space: normal;
    font-size: calc(clamp(var(--type-section), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt);
  }
}

@media (min-width: 640px) and (max-width: 767px) {
  .home-hero-title {
    white-space: normal;
    font-size: calc(clamp(var(--type-section-lg), calc(100cqi * 0.92 / 14.5), var(--type-page-lg)) + 3pt);
  }
}

@media (max-width: 767px) {
  .home-hero-given,
  .home-hero-family {
    display: inline-block;
    white-space: nowrap;
  }
}

@media (min-width: 768px) {
  .home-hero-title {
    white-space: nowrap;
  }
}

.home-hero-summary {
  max-width: var(--reading-measure, 45rem);
  color: var(--color-on-surface);
  line-height: var(--leading-body);
}

/* No empty min-height. A guessed line count shifts the call to action
   when the summary is shorter or taller than the reserve. The paragraph
   is in the HTML when content/pages/cv/summary.md exists. */

.home-hero-summary p {
  margin: 0 0 var(--space-md);
}

.home-hero-summary p:last-child {
  margin-bottom: 0;
}

.home-hero-portrait {
  position: relative;
  width: 100%;
  max-width: 16rem;
  justify-self: end;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.home-hero-plate-wrap {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.home-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
  position: relative;
}

/* Primary hero CTA: a small lift on hover — tactile without box-shadow. */
.home-hero-cta {
  transition: color var(--motion-duration-fast) var(--motion-ease-default),
    border-color var(--motion-duration-fast) var(--motion-ease-default),
    background-color var(--motion-duration-fast) var(--motion-ease-default),
    transform var(--motion-duration-fast) var(--motion-ease-default);
}

.home-hero-cta:hover {
  transform: translateY(-2px);
}

.home-hero-cta:active {
  transform: translateY(0);
}

/* ── Portrait plate ──
   Beside the copy on a wide page the plate is portrait (3:4): its height
   matches the left column and the width is W = 3/4 × H. On a phone it stays
   3:4. A wider box would cover-crop that portrait a second time. When
   hero_landscape is set, or a portrait entry has its own landscape, the
   phone plate is 16:9 and the chosen 16:9 file is shown whole. */
.home-hero-plate {
  position: relative;
  z-index: 1;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  /* Black in both themes: the photograph fades in over this, so a theme
     canvas here would read as the wrong picture arriving late. */
  background: black;
  border: 1.5px solid var(--border-ink);
  border-radius: var(--radius-card);
  width: 100%;
  flex: 0 0 auto;
  min-height: 0;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-on-surface) 10%, transparent);
}

:root:not([data-theme="dark"]) .home-hero-plate,
html[data-theme="light"] .home-hero-plate {
  border-width: 1px;
  border-color: var(--border-ink);
}

[data-theme="dark"] .home-hero-plate {
  box-shadow: none;
}

/* Silk facet behind the portrait — restored; the Borders pass had hidden it. */
.home-hero-shard {
  top: -2.25rem;
  right: -2rem;
  width: 15rem;
  height: 15rem;
  background: var(--color-primary);
  opacity: var(--cubist-shard-opacity-strong, 16%);
  z-index: 0;
}

@media (max-width: 1023px) {
  .home-hero-shard {
    width: 11rem;
    height: 11rem;
    top: -1.5rem;
    right: -1.25rem;
  }
}

@media (max-width: 1023px) {
  .home-hero-portrait::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: 55%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 140%;
    height: 120%;
    border-radius: 50%;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--color-outline) 18%, transparent) 0%,
        color-mix(in srgb, var(--color-on-surface) 7%, transparent) 45%,
        transparent 72%);
    filter: blur(40px);
    pointer-events: none;
  }

  [data-theme="dark"] .home-hero-portrait::before {
    background: radial-gradient(circle,
        color-mix(in srgb, var(--color-on-surface) 12%, transparent) 0%,
        transparent 70%);
  }
}

.home-hero-plate picture {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
}

.home-hero-plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 52% 18%;
  display: block;
  filter: saturate(1.05) contrast(0.98);
  opacity: 0;
  transition: opacity var(--motion-duration-slow) var(--motion-ease-default),
    transform var(--motion-duration-slow) var(--motion-ease-default),
    filter var(--motion-duration-slow) var(--motion-ease-default),
    mix-blend-mode var(--motion-duration-base) var(--motion-ease-default);
}

.home-hero-plate img.is-shown {
  opacity: 1;
}

/* 16:9 file in a 16:9 plate. contain shows the whole frame. The image stays
   hidden until the chosen file has loaded, so a fallback source does not
   flash before a pool landscape replaces it. The plate is already 16:9, so
   the wait does not move the layout. transition none so the paint is not a fade. */
@media (max-width: 767px) {
  .home-hero-plate--landscape {
    aspect-ratio: 16 / 9;
  }

  .home-hero-plate--landscape img {
    object-fit: contain;
    object-position: center center;
    opacity: 0;
    transition: none;
  }

  .home-hero-plate--landscape img.is-shown {
    opacity: 1;
  }
}

.home-hero-plate:hover img {
  transform: scale(1.02);
}

@media (prefers-reduced-motion: reduce) {

  .home-hero-plate img,
  .home-hero-plate:hover img {
    transform: none;
    transition: none;
  }
}

/* ── Section banners ──
   Atelier plate edge: a denser hairline, a longer accent rule, and a short
   vertical tick so each band reads as a ruled plate rather than a soft fade. */
.home-band:not(.home-band--hero) .ledger-section-banner {
  padding-top: var(--space-lg);
  padding-bottom: var(--space-sm);
  border-top: 1px solid var(--border-gentle);
  box-shadow: 0 4px 0 -3px var(--border-gentle-faint);
  position: relative;
}

.home-band:not(.home-band--hero) .ledger-section-banner::before {
  content: "";
  position: absolute;
  left: 0;
  top: -2px;
  width: 4rem;
  height: 3px;
  background: var(--color-primary);
}

.home-band:not(.home-band--hero) .ledger-section-banner::after {
  content: "";
  position: absolute;
  left: 4.35rem;
  top: -4px;
  width: 1px;
  height: 7px;
  background: color-mix(in srgb, var(--color-primary) 55%, var(--color-outline));
}

.home-section-aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  max-width: 30rem;
}

/* The aside sits at the end of the banner, so its contents align to that same
   edge — button and copy on one axis. Aligning the button left while the copy
   ran right made every band look like a zigzag. */
@media (min-width: 768px) {
  .home-section-aside {
    align-items: flex-end;
    text-align: right;
  }

  .home-section-aside .ledger-cta {
    align-self: flex-end;
  }
}

/* The lead column of a banner holds the kicker, the title and the note, all
   three filled from content/pages/headers.yml. It has to be able to
   shrink: the banner is a flex row and the aside beside it is sized by its
   button, so without this the note pushes the button off the line. */
.ledger-section-banner .ledger-section-lead {
  min-width: 0;
}

/* One line under the title saying what the band holds. It is prose rather than
   a chrome label, so it takes the body face and the reading measure instead of
   the uppercase treatment `.ledger-section-note` carries in base.css — that
   one is the right-hand tally at the end of a banner, which is a different
   thing standing in a different place.

   The element is removed outright when the field is empty (see
   hydrateHomeSections), so this margin never opens a gap of its own. */
.home-section-note {
  margin: var(--space-sm) 0 0;
  max-width: var(--reading-measure, 45rem);
  color: var(--color-on-surface-variant);
}

/* ── Featured article band ── */
/* The lead is a panel, not a row.
   It used to be three bare columns sitting on the band background, which is
   the same ground the three cards below it stand on: nothing about it said it
   was the piece the band leads with, and a reader scanning down met four
   equal entries. It now takes the card rung of the surface ladder, is fenced
   by the same hairline every other panel on the site carries, and opens on a
   rule in the primary, so the eye stops at the top of it. The image inside is
   inset by the panel's own padding rather than running to the band edge, which
   is the other half of the promotion: the lead contains its picture, the cards
   below are contained by theirs.

   Everything here is ladder tokens and the gentle border family; the site
   ships a light and a dark palette, so a literal colour would be wrong in one
   of them.

   The three type terms below are custom properties because the plate in the
   third column is measured against them rather than given a size of its own —
   see --home-featured-plate-height and `.home-featured .ledger-poster`. */
.home-featured {
  --home-featured-title-size: var(--type-card-lg);
  --home-featured-title-line: 1.25;
  --home-featured-copy-line: var(--leading-body);
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
  align-items: stretch;
  background: var(--color-surface-card);
  border: 1.5px solid var(--border-ink);
  border-radius: var(--radius-card);
  border-top: 2px solid var(--color-primary);
  padding: var(--space-md) var(--space-lg);
  transition:
    background-color var(--motion-duration-fast) var(--motion-ease-default),
    border-color var(--motion-duration-fast) var(--motion-ease-default);
  margin-bottom: var(--space-lg);
}

/* The hover rung, same as `.ledger-card` takes: the panel is one link target
   end to end, so the whole surface answers. */
.home-featured:hover {
  background: var(--color-surface-high);
  border-color: color-mix(in srgb, var(--color-primary) 55%, var(--border-gentle-hover));
  border-top-color: var(--color-primary);
}

[data-theme="dark"] .home-featured:hover {
  border-color: color-mix(in srgb, var(--color-primary) 40%, var(--border-gentle-hover));
  border-top-color: var(--color-primary);
}

@media (min-width: 900px) {
  .home-featured {
    --home-featured-title-size: var(--type-section);
    padding: var(--space-lg);
  }

  .home-featured.home-featured--illustrated {
    grid-template-columns: minmax(0, 1fr) 13.5rem;
    gap: var(--space-xl);
  }
}

@media (min-width: 1280px) {
  .home-featured.home-featured--illustrated {
    grid-template-columns: minmax(0, 1fr) 15rem;
  }
}

/* Shards on the featured panel, which carried none: the one card the home
   page leads with was also the only one on the band with no footing in the
   cubist half of the identity.

   The pair is placed around the poster rather than across the card, because
   the poster is opaque and a shard behind it is a shard nobody sees. The
   alpha takes the top-left, over the index column, where there is nothing but
   chrome and air. The beta takes the bottom-right and comes out from *under*
   the poster into the strip below it, which is the same move the index band
   makes with its own plates.

   Hues are the two the home band does not already spend: the index panels
   below run secondary and primary, so this pair runs tertiary and secondary,
   and neither repeats the corner its neighbor uses. Shards are absolutely
   positioned, so they are not grid items and the three-column template is
   untouched. */
.home-featured-shard {
  left: -3rem;
  top: -3.5rem;
  width: 11rem;
  height: 11rem;
  background: var(--color-tertiary);
}

.home-featured-shard--beta {
  left: auto;
  right: -3rem;
  top: auto;
  bottom: -4rem;
  width: 13rem;
  height: 13rem;
  background: var(--color-secondary);
}

/* Below the two-column layout the panel is short and the columns stack, so a
   shard sized for the wide card reaches the title.

   The beta restates `top`/`left` as `auto`. It carries both class names, so
   the rule above also matches it, and an override that gives it a `bottom`
   without taking back the `top` leaves it with all four offsets set — at
   which point top and left win and the pair collapses into one corner. */
@media (max-width: 1023px) {
  .home-featured-shard {
    width: 8rem;
    height: 8rem;
    top: -2.5rem;
    left: -2.5rem;
  }

  .home-featured-shard--beta {
    width: 9rem;
    height: 9rem;
    top: auto;
    left: auto;
    bottom: -3rem;
    right: -2.5rem;
  }
}

/* The columns sit clear of both. */
.home-featured> :not(.shard-accent) {
  position: relative;
  z-index: 1;
}

.home-featured-lead {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-xs);
  min-width: 0;
  max-width: var(--reading-measure, 45rem);
}

.home-featured-rail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  margin-bottom: 0;
}

.home-featured-rail .ledger-meta {
  margin: 0;
}

.home-featured-badge {
  flex: 0 0 auto;
}

.home-featured-title {
  margin: 0;
  font-family: var(--font-content-title);
  font-size: var(--home-featured-title-size);
  font-weight: var(--weight-title);
  font-synthesis: none;
  line-height: var(--home-featured-title-line);
}

/* Articles band only. Two points over the size the title already uses,
   the same point step as the phone hero name. The section heading is
   untouched. Listed cards in other bands are untouched. */
[data-home-kind="articles"] .home-featured-title {
  font-size: calc(var(--home-featured-title-size) + 2pt);
}

[data-home-kind="articles"] .home-card-grid .card-title,
[data-home-kind="articles"] .home-card-grid .ledger-card-title {
  font-size: calc(var(--type-card) + 2pt);
}

/* Phone only: the featured card's text sat against the top rule. One
   step more than the shared top padding, and only on this card. */
@media (max-width: 767px) {
  [data-home-kind="articles"] .home-featured {
    padding-top: calc(var(--space-md) + 0.75rem);
  }
}

/* Home article / rascunho / project cards — content-title voice, not display. */
.home-card-grid .ledger-card-title,
.home-card-grid .card-title,
.home-draft-card .ledger-card-title,
.home-project-specimen .ledger-card-title,
.home-project-inventory-title {
  font-family: var(--font-content-title);
  font-weight: var(--weight-title);
  font-synthesis: none;
}

.home-featured-title a {
  color: var(--color-on-surface);
  text-decoration: none;
  transition: color var(--motion-duration-fast) var(--motion-ease-default);
}

.home-featured:hover .home-featured-title a {
  color: var(--color-primary);
}

.home-featured-copy {
  margin: 0;
  max-width: var(--reading-measure, 45rem);
  font-family: var(--font-body);
  font-size: var(--type-subtitle);
  font-weight: var(--weight-body);
  line-height: var(--home-featured-copy-line);
  color: var(--color-legend);
}

.home-featured-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-top: auto;
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border-gentle-divider);
}

.home-featured-foot .home-featured-cta {
  margin-left: auto;
  padding: 0.35rem var(--space-md);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: var(--weight-label);
}

.home-featured-foot .home-featured-cta:hover {
  background: color-mix(in srgb, var(--color-primary) 85%, var(--color-on-surface));
  color: var(--color-on-primary);
  text-decoration: none;
}

.home-featured-foot .home-featured-cta>span:not(.ledger-cta-arrow):not(.ledger-cta-icon),
.home-featured-foot .home-featured-cta:hover>span:not(.ledger-cta-arrow):not(.ledger-cta-icon) {
  text-decoration: none;
}

/* ── Writing cards ── */
.home-card-grid:empty,
.home-draft-list:empty,
[data-home-featured-slot]:empty {
  min-height: 16rem;
}

.home-project-inventory:empty {
  min-height: 8rem;
}

.home-card-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-lg);
}

@media (min-width: 768px) {
  .home-card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .home-card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* The archive card prints the publication date twice — once in the meta strip
   and once in the footer's date evolution. On a three-card preview the strip
   is enough; the full history stays on the writing index. */
.home-card-grid .ledger-card-foot .date-evolution {
  display: none;
}

.home-card-grid .ledger-card-foot {
  justify-content: flex-end;
}

/* A top rule per card, rotating through the palette triad, is what gives the
   grid its ledger rhythm in the mockup. */
.home-card-grid .ledger-card {
  border-top-width: 2px;
  border-top-style: solid;
  border-top-color: var(--color-primary);
}

.home-card-grid .ledger-card:nth-child(2) {
  border-top-color: var(--color-secondary);
}

.home-card-grid .ledger-card:nth-child(3) {
  border-top-color: var(--color-tertiary);
}

/* ── Rascunhos: dropped sheets ──
   Four compact cards rather than four full-width text rows: the poster is
   visible at every breakpoint now (it used to hide below 640px), each card
   keeps a small fixed tilt for the "dropped on the desk" feel, and the
   whole band reads as shorter for the same four entries. Tertiary is the
   hue "posts" already carries everywhere else on this page (the Network of
   Ideas arcs and legend both key rascunhos to it), so the band's accent
   reuses that variable instead of a new one. */
.home-draft-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md);
}

@media (min-width: 1024px) {
  .home-draft-list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-lg);
  }
}

.home-draft-card {
  overflow: hidden;
  border-top-width: 2px;
  border-top-style: solid;
  border-top-color: var(--color-tertiary);
  transform: rotate(0deg);
  transition: transform var(--motion-duration-fast) var(--motion-ease-default),
    background-color var(--motion-duration-fast) var(--motion-ease-default),
    border-color var(--motion-duration-fast) var(--motion-ease-default);
}

/* Shared 16:9 plate. The previous 16/12.6 crop made these thumbs tall. */
.home-draft-card .ledger-poster {
  aspect-ratio: 16 / 9;
}

/* A handful of fixed degrees per grid position — not a JS random() — so the
   tilt is identical on every render and every screenshot. */
.home-draft-list>*:nth-child(4n + 1) {
  transform: rotate(-1.2deg);
}

.home-draft-list>*:nth-child(4n + 2) {
  transform: rotate(0.9deg);
}

.home-draft-list>*:nth-child(4n + 3) {
  transform: rotate(-0.7deg);
}

.home-draft-list>*:nth-child(4n) {
  transform: rotate(1.1deg);
}

.home-draft-card:hover,
.home-draft-card:focus-within {
  transform: rotate(0deg);
}

.home-draft-card .ledger-card-body {
  /* 20% shorter stack than the previous dropped-sheet body, both breakpoints. */
  padding: calc(var(--space-md) * 0.8);
  gap: calc(var(--space-xs) * 0.8);
}

/* Up from 1rem. The four dropped sheets are the only place on the home page
   where a card title sat at body size, so the band read as a footnote to the
   articles above it rather than as its own section. */
.home-draft-card .ledger-card-title {
  font-size: var(--type-card);
  line-height: 1.3;
}

.home-draft-card .ledger-meta {
  font-family: var(--font-mono);
  font-size: var(--type-mono);
  font-weight: 400;
}

.home-draft-card .ledger-card-copy {
  font-family: var(--font-body);
  font-size: var(--type-subtitle);
  font-weight: var(--weight-body);
  line-height: var(--leading-body);
  color: var(--color-legend);
  /* Fill the surplus the equal-height grid hands the body. `height: 0` with
     `flex: 1` gives the paragraph a definite block size from the flex
     allocation, so line-clamp/overflow clip against that height instead of
     growing past the ellipsis (the old flex:1 + clamp:2 bug that left text
     after "…" and sliced mid-glyph at the card edge). */
  flex: 1 1 auto;
  /* With the 16:9 plate, this band keeps the whole card about 20% shorter
     than the old 16/12.6 poster and 8.4-line excerpt, on narrow and wide grids. */
  min-height: calc(var(--type-subtitle) * var(--leading-body) * 5.33);
  height: 0;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Four-up posters were the tall part of the old card. Give the excerpt a
   little of that height back so the wide card is 20% shorter too, not more. */
@media (min-width: 1024px) {
  .home-draft-card .ledger-card-copy {
    min-height: calc(var(--type-subtitle) * var(--leading-body) * 6.05);
    -webkit-line-clamp: 6;
    line-clamp: 6;
  }
}

.home-draft-card .ledger-card-foot .ledger-cta {
  font-size: var(--type-cta);
}

/* Hover/focus zoom on the poster image only, the card clips it via the
   overflow: hidden above so the scale never blows out the card bounds. */
.home-draft-card .ledger-poster img,
.home-draft-card .ledger-poster video {
  transition: transform var(--motion-duration-slow) var(--motion-ease-default);
}

.home-draft-card:hover .ledger-poster img,
.home-draft-card:hover .ledger-poster video,
.home-draft-card:focus-within .ledger-poster img,
.home-draft-card:focus-within .ledger-poster video {
  transform: scale(1.04);
}

@media (prefers-reduced-motion: reduce) {

  .home-draft-card,
  .home-draft-card .ledger-poster img,
  .home-draft-card .ledger-poster video {
    transition: none;
  }
}

/* ── Engineering artifacts: specimen bench ──
   A specimen card beside a filing rack of project cards. Height is locked to
   the tallest project (home.html measures once, then sets
   `--home-specimen-height`), so swapping projects never resizes the band or
   the inventory. Taglines clamp to two lines with an ellipsis; chips wrap
   whole pills like the projects index; spare height parks chips and the foot
   on the floor. Every plate is 16:9, the ratio the thumbnails are drawn at,
   with the title below it. From 900px the specimen and the rack share equal
   columns (~45.6% each); rows reserve height for three resource icons.
   Below 900px the rack is an icon strip above the specimen, one column
   per project. */
.home-projects-bench {
  --home-specimen-height: 32rem;
  --home-icon-btn-size: 2.75rem;
  --home-project-icon-count: 6;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-md);
}

.home-project-inventory {
  order: -1;
}

.home-project-specimen {
  height: var(--home-specimen-height);
  overflow: hidden;
  gap: var(--space-sm);
  padding: var(--space-md);
  box-sizing: border-box;
}

/* A primary top rule, at a weight that beats the light-paper hairline
   reset on `.ledger-system-card`. */
:root .home-projects-bench .home-project-specimen,
:root .home-projects-bench .home-project-specimen:hover {
  border-top: 2px solid var(--color-primary);
}

.home-band--contrast .home-project-specimen {
  background: var(--color-surface-card-contrast);
}

.home-band--contrast .home-project-specimen:hover {
  background: var(--color-surface-high-contrast);
}

.home-specimen-strip,
.home-project-inventory-code {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  min-width: 0;
}

/* Same chrome voice as `.projects-page .ledger-meta` (label face), stepped
   up to `--type-label-lg` on the specimen so the strip above the plate
   matches the featured scale instead of body-meta. The rack keeps the
   plain label step. */
.home-specimen-strip .ledger-meta,
.home-project-inventory-code .ledger-meta {
  min-width: 0;
  flex-wrap: nowrap;
  overflow: hidden;
  white-space: nowrap;
  font-family: var(--font-label);
  font-size: var(--type-label);
  letter-spacing: 0.03em;
}

.home-specimen-strip .ledger-meta {
  font-size: var(--type-label-lg);
}

.home-specimen-folio,
.home-project-inventory-index {
  color: var(--color-primary);
  font-size: inherit;
}

.home-specimen-strip>.ledger-status,
.home-project-inventory-code>.ledger-status {
  flex: 0 0 auto;
  font-family: var(--font-label);
  font-size: var(--type-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.4;
  padding: 0.1rem 0.45rem;
  background: color-mix(in srgb, var(--color-secondary) 14%, transparent);
}

.home-specimen-strip>.ledger-status {
  font-size: var(--type-label-lg);
}

/* The figure holds the plate and, always below it, the title. The badge
   shares the poster's grid cell; when the image fails, renderPosterMedia
   removes it and the badge hides with it. */
.home-specimen-figure {
  flex: 0 0 auto;
  display: grid;
  gap: var(--space-md);
}

.home-specimen-figure>.ledger-poster,
.home-specimen-figure>.projects-plate {
  grid-area: 1 / 1;
  width: 100%;
  aspect-ratio: 16 / 9;
}

.home-specimen-figure>.projects-plate {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-high);
  color: var(--color-primary);
}

.home-specimen-figure .projects-plate-glyph {
  font-size: 3rem;
}

.home-specimen-figure .is-initial {
  font-family: var(--font-content-title);
  font-weight: var(--weight-title);
  line-height: 1;
}

.home-specimen-figure:has(> .ledger-poster)>.home-specimen-badge.is-initial {
  font-size: var(--type-subtitle);
}

/* Glyph plates have no .ledger-poster::after — mirror the image corners. */
.home-specimen-figure>.projects-plate::after {
  content: "";
  --frame-corner-size: 0.7rem;
  --frame-corner-thickness: 1px;
  position: absolute;
  inset: 0.3rem;
  pointer-events: none;
  background:
    linear-gradient(var(--color-primary), var(--color-primary)) top left / var(--frame-corner-size) var(--frame-corner-thickness) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) top left / var(--frame-corner-thickness) var(--frame-corner-size) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) top right / var(--frame-corner-size) var(--frame-corner-thickness) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) top right / var(--frame-corner-thickness) var(--frame-corner-size) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) bottom left / var(--frame-corner-size) var(--frame-corner-thickness) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) bottom left / var(--frame-corner-thickness) var(--frame-corner-size) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) bottom right / var(--frame-corner-size) var(--frame-corner-thickness) no-repeat,
    linear-gradient(var(--color-primary), var(--color-primary)) bottom right / var(--frame-corner-thickness) var(--frame-corner-size) no-repeat;
}

.home-specimen-figure>.home-specimen-badge {
  display: none;
}

.home-specimen-figure:has(> .ledger-poster)>.home-specimen-badge {
  grid-area: 1 / 1;
  justify-self: end;
  align-self: start;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: var(--space-sm);
  font-size: 1.25rem;
  background: var(--color-surface-card);
  color: var(--color-primary);
}

.home-project-specimen .home-specimen-title {
  margin: 0;
  font-size: var(--type-card-lg);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Tagline fills spare height between the plate and the chips/foot.
   `-webkit-line-clamp` hard-clips mid-glyph on this card, so home.html
   ellipsizes against the flex-allocated box after paint (`height: 0` +
   `flex: 1` is the same definite-size trick as `.home-draft-card`). */
.home-project-specimen .ledger-card-copy {
  flex: 1 1 auto;
  min-height: calc(var(--type-body) * var(--leading-body) * 2);
  height: 0;
  overflow: hidden;
  font-size: var(--type-body);
  line-height: var(--leading-body);
  color: var(--color-on-surface-variant);
}

.home-project-specimen .ledger-chip-row {
  flex: 0 0 auto;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin: 0;
}

.home-specimen-foot {
  flex: 0 0 auto;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-sm);
  padding-top: var(--space-md);
}

.home-project-specimen .ledger-chip-row~.home-specimen-foot {
  margin-top: var(--space-xs);
}

.home-specimen-foot .ledger-card-links {
  position: relative;
  z-index: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  padding-top: 0;
  border-top: 0;
}

.home-specimen-open {
  margin-left: auto;
  flex: 0 0 auto;
}

.home-project-specimen:hover .home-specimen-open {
  color: var(--color-on-primary, var(--color-surface));
  border-color: var(--color-link-hover);
  background: var(--color-primary);
}

.home-project-specimen:hover .home-specimen-open .ledger-cta-arrow {
  transform: translateX(4px);
}

@media (prefers-reduced-motion: reduce) {
  .home-project-specimen:hover .home-specimen-open .ledger-cta-arrow {
    transform: none;
  }
}

/* Mobile: one equal column per project (the script sets the count, up to
   six), so the strip spans the band; fixed button height. */
.home-project-inventory {
  display: grid;
  grid-template-columns: repeat(var(--home-project-icon-count, 6), minmax(0, 1fr));
  gap: var(--space-xs);
  min-width: 0;
  min-height: 0;
  overflow: visible;
  background: transparent;
  border: 0;
  padding: 0;
}

button.home-project-inventory-row {
  font: inherit;
  color: inherit;
  text-align: start;
  width: 100%;
}

.home-project-inventory-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  height: var(--home-icon-btn-size);
  padding: 0;
  border: 1px solid var(--border-gentle-divider);
  background: var(--color-panel-contrast);
  cursor: pointer;
  transition: background-color var(--motion-duration-fast) var(--motion-ease-default),
    border-color var(--motion-duration-fast) var(--motion-ease-default);
}

.home-project-inventory-media,
.home-project-inventory-body {
  display: none;
}

.home-project-inventory-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--color-on-surface-variant);
}

.home-project-inventory-glyph--initial {
  font-family: var(--font-content-title);
  font-size: var(--type-subtitle);
  font-weight: var(--weight-title);
}

.home-project-inventory-row:hover,
.home-project-inventory-row:focus-visible {
  background: var(--color-surface-high);
  outline: none;
}

.home-project-inventory-row.is-selected {
  border-color: var(--color-primary);
  outline: 1px solid var(--color-primary);
  outline-offset: -1px;
  background: var(--color-surface-high);
}

.home-project-inventory-row.is-selected .home-project-inventory-glyph,
.home-project-inventory-row:hover .home-project-inventory-glyph,
.home-project-inventory-row:focus-visible .home-project-inventory-glyph {
  color: var(--color-primary);
}

.home-band--contrast .home-project-inventory-row:hover,
.home-band--contrast .home-project-inventory-row:focus-visible,
.home-band--contrast .home-project-inventory-row.is-selected {
  background: var(--color-surface-high-contrast);
}

@media (min-width: 900px) {

  /* Specimen and inventory share equal columns (~45.6% each). Each row fits
     its square icon mark and two-line code + title body; the specimen height
     matches the N-entry inventory stack. */
  .home-projects-bench {
    --home-inventory-mark-size: 2.75rem;
    --home-inventory-row-min: calc(
      var(--home-inventory-mark-size) + 2 * var(--space-sm) + 2px
    );
    --home-inventory-min-height: calc(
      var(--home-project-icon-count, 6) * var(--home-inventory-row-min) +
      (var(--home-project-icon-count, 6) - 1) * var(--space-sm) +
      2 * var(--space-md)
    );
    --home-specimen-height: var(--home-inventory-min-height);
    display: grid;
    grid-template-columns: minmax(0, 45.6%) minmax(0, 45.6%);
    column-gap: var(--space-xl);
    align-items: stretch;
  }

  .home-project-inventory {
    order: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    padding: var(--space-md);
    background: var(--color-panel-contrast);
  }

  .home-specimen-figure:has(> .ledger-poster, > .projects-plate) {
    flex: 1 1 0;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr) auto;
    gap: var(--space-sm);
  }

  .home-specimen-figure > .ledger-poster,
  .home-specimen-figure > .projects-plate {
    height: 100%;
    min-height: 0;
    aspect-ratio: auto;
  }

  .home-project-specimen .home-specimen-title {
    font-size: var(--type-title);
  }

  .home-project-specimen .ledger-card-copy {
    flex: 0 0 auto;
    height: auto;
    min-height: 0;
    max-height: calc(var(--type-body) * var(--leading-body) * 2);
  }

  .home-project-inventory-row {
    flex: 0 0 auto;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-md);
    height: var(--home-inventory-row-min);
    min-height: var(--home-inventory-row-min);
    box-sizing: border-box;
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--border-gentle-divider);
    background: var(--color-surface-card);
    outline: none;
  }

  .home-band--contrast .home-project-inventory-row {
    background: var(--color-surface-card-contrast);
  }

  .home-project-inventory-row.is-selected,
  .home-band--contrast .home-project-inventory-row.is-selected {
    background: var(--color-surface-high);
    border-color: var(--border-gentle-divider);
    outline: none;
    box-shadow: inset 3px 0 0 var(--color-primary);
  }

  /* Square icon mark beside the two-line code + title body. */
  .home-project-inventory-media {
    display: block;
    flex: 0 0 auto;
    width: var(--home-inventory-mark-size);
    height: var(--home-inventory-mark-size);
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background: var(--color-surface-high);
  }

  .home-project-inventory-row.is-selected .home-project-inventory-media {
    outline: 1px solid var(--color-primary);
    outline-offset: 2px;
  }

  .home-project-inventory-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    overflow: hidden;
    background: var(--color-surface-high);
    color: var(--color-primary);
  }

  .home-project-inventory-mark .material-symbols-outlined {
    font-size: 1.5rem;
  }

  .home-project-inventory-mark--initial {
    font-family: var(--font-content-title);
    font-size: var(--type-card);
    font-weight: var(--weight-title);
    line-height: 1;
    color: var(--color-on-surface);
  }

  .home-project-inventory-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-self: center;
    gap: 0.15rem;
    flex: 1 1 0;
    min-width: 0;
    padding-top: 0;
  }

  .home-project-inventory-code .ledger-meta {
    font-size: var(--type-label-lg);
  }

  .home-project-inventory-title {
    margin: 0;
    font-family: var(--font-content-title);
    font-size: calc(var(--type-card) - 2pt);
    font-weight: var(--weight-title);
    line-height: 1.2;
    color: var(--color-on-surface);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .home-project-inventory-row:hover .home-project-inventory-title,
  .home-project-inventory-row:focus-visible .home-project-inventory-title,
  .home-project-inventory-row.is-selected .home-project-inventory-title {
    color: var(--color-primary);
  }

  /* Two classes: the glyph also carries .material-symbols-outlined, whose
     font stylesheet loads after this one and sets display. */
  .home-project-inventory-row .home-project-inventory-glyph {
    display: none;
  }
}

/* ── Reference band: Sources + Network of Ideas ──────────────────────────
   Two destinations in one band, each a card whose poster is a plate drawn
   from that section's own content by the export and fetched at runtime.
   The plate sits one step *below* the card on the surface ladder, the way
   the mockup recesses its diagram panels: card -> background, no shadow.

   Every stroke and fill is a custom property, because the two SVGs are
   injected inline precisely so that a theme flip repaints them. A hex here,
   or an <img>, would be correct in one palette and wrong in the other.
   The figure is hidden until the markup lands, so a plate that never arrives
   leaves the panel with its title and its link rather than an empty frame. */

/* Ambient pool behind the pair. Dark palette only, for the reason set out
   above the hero's.
 *
 * The two panels sat side by side with a visible seam and nothing behind
 * them. One pool centred on that seam, behind both, lights the pair as a
 * single object rather than giving each panel an opening of its own. Held at
 * 5% against the hero's 7%: at equal strength the page reads as having two
 * openings, and only one of them is where it starts.
 *
 * Centred is right here and nowhere else — the seam is the thing being lit,
 * so the offset is vertical instead, which is what keeps the pool partly
 * outside the band it backs. `.home-band` already carries `position:
 * relative`; `isolation: isolate` is what stops `z-index: -1` escaping behind
 * the page background. */
.home-band--index {
  isolation: isolate;
}

[data-theme="dark"] .home-band--index::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -8%;
  left: 50%;
  width: min(72rem, 100%);
  height: 116%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse,
      color-mix(in srgb, var(--color-primary) 5%, transparent) 0%,
      transparent 70%);
  filter: blur(70px);
  pointer-events: none;
}

.home-index-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
}

@media (min-width: 900px) {
  .home-index-split {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-xl);
  }
}

.home-index-panel {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
  padding: 0 0 var(--space-lg);
  background: var(--color-surface-card-contrast);
  border: 1.5px solid var(--border-ink);
  border-radius: var(--radius-card);
  transition:
    background-color var(--motion-duration-fast) var(--motion-ease-default),
    border-color var(--motion-duration-fast) var(--motion-ease-default);
}

.home-index-panel:hover {
  background: var(--color-surface-high-contrast);
  border-color: var(--border-gentle-hover);
}

/* The plates are line-art, so the cubist half of the identity had no footing
   on this band at all. One shard per panel, the canonical polygons across
   the set, rotating hue the way every other shard on the site does.
 *
 * They sit in the foot of the panel, under the title and the link: the plate
 * above carries an opaque background, so a shard behind it would be a shard
 * nobody sees. `overflow: hidden` on the panel above keeps the negative
 * offsets out of the document scroll width, and the shared utility already
 * unmounts both below 640px. */
.home-index-shard {
  right: -3rem;
  bottom: -3.5rem;
  width: 11rem;
  height: 11rem;
  background: var(--color-secondary);
}

.home-index-shard--beta {
  right: auto;
  left: -3rem;
  bottom: -3.5rem;
  width: 11rem;
  height: 11rem;
  background: var(--color-primary);
}

/* Between the shard cut-off and the layout each panel is the full
   band wide on small screens, so a shard sized for half of it stops being a corner accent. */
@media (max-width: 899px) {

  .home-index-shard,
  .home-index-shard--beta {
    width: 8rem;
    height: 8rem;
    bottom: -2.5rem;
  }
}

.home-index-panel:not(:has(.home-index-plate)) {
  padding-top: var(--space-xl);
}

/* The title and the link have to sit clear of the shard behind them. The
   plate is excluded because it is the one child that must stay full-bleed,
   and the shard because it is the thing being sat clear of. */
.home-index-panel> :not(.home-index-plate):not(.shard-accent) {
  position: relative;
  z-index: 1;
  margin-inline: var(--space-lg);
}

/* Card-scale title, not `.section-title`: that face is for band banners and
   was oversized once the three index panels sat in one row. Locked here so
   Sources / Network / Bibliography share one title register. */
.home-index-title {
  margin: 0;
  font-family: var(--font-title);
  font-size: var(--type-card);
  font-weight: var(--weight-display);
  line-height: 1.2;
  color: var(--color-on-surface);
  font-synthesis: none;
  font-optical-sizing: auto;
}

/* ── The plate ──
   Every panel grows its plate so the title + Open row lands on one baseline
   across Sources, Network, and Bibliography — the bib plate already flexed;
   the other two used to sit shorter and leave their titles higher. */
.home-index-plate {
  align-self: stretch;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  background: var(--color-background);
  border-bottom: 1px solid var(--border-gentle-subtle);
}

/* The legend is not optional: the drawing has no labels, so the colour key
   is the only thing that says which mark is which. The tally beside it is
   counted from the content by the generator — see the script header. */
.home-index-plate-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm) var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border-gentle-divider);
  font-family: var(--font-label);
  font-size: var(--type-label);
  letter-spacing: 0.04em;
  color: var(--color-on-surface-variant);
}

.home-index-legend {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

.home-index-key {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.home-index-swatch {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  flex-shrink: 0;
  background: var(--color-outline);
}

.home-index-tally {
  font-family: var(--font-mono);
  font-size: var(--type-meta);
  letter-spacing: 0.04em;
  text-transform: none;
  font-variant-numeric: tabular-nums;
  color: var(--color-on-surface-variant);
}

.home-index-art {
  display: block;
  width: 100%;
  height: auto;
  padding: var(--space-md) var(--space-sm) var(--space-sm);
}

/* ── Shared plate furniture ── */
/* Hairlines stay hairlines: the viewBox is scaled down hard on a phone, and
   without this the rules fade to a half-pixel smudge. */
.home-index-art line,
.home-index-art path,
.home-index-art rect {
  vector-effect: non-scaling-stroke;
}

.home-index-art line,
.home-index-art path {
  fill: none;
}

/* ── Network of Ideas: the metric card ── */
/* The plate used to draw the whole graph, and at this size fifty entries under
   ninety theme threads came out as a smudge. It reports the graph instead:
   three counts in the display serif over one bar that splits them by what kind
   of writing they are, which is the only quantity here that needs a colour.

   The numerals are SVG text, so they scale with the panel rather than sitting
   at one size. That is the point: they are the drawing. The label register does
   not scale, which is why the legend and the tally stayed in HTML. */
.home-index-metric {
  font-family: var(--font-title);
  font-size: var(--type-page);
  fill: var(--color-on-surface);
}

.home-index-metric-label {
  font-family: var(--font-mono);
  font-size: calc(var(--type-label) - 2pt);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: var(--color-on-surface-variant);
}

.home-index-divider {
  stroke: var(--border-gentle-divider);
  stroke-width: 1;
}

.home-index-spine-rule {
  stroke: var(--color-outline-variant);
  stroke-width: 1;
}

.home-index-spine--articles {
  fill: var(--color-primary);
}

.home-index-spine--posts {
  fill: var(--color-tertiary);
}

.home-index-swatch--articles {
  background: var(--color-primary);
}

.home-index-swatch--posts {
  background: var(--color-tertiary);
}

/* ── Sources: the unit field ── */
/* One square per source, packed into its collection. Medium colour is the
   Sources page's own signal (--color-res-*), repeated here so the plate and
   the grid it opens agree on what a video looks like.

   The tiles are filled rather than outlined. A 32px square is small enough
   that the colour reads as a tint of the block rather than as a shout, and
   an outline at this size would spend most of the tile on its own border. */
.home-index-unit {
  fill: var(--color-outline);
  fill-opacity: 0.8;
}

.home-index-unit--youtube,
.home-index-swatch--youtube {
  fill: var(--color-res-youtube);
  background: var(--color-res-youtube);
}

.home-index-unit--podcast,
.home-index-swatch--podcast {
  fill: var(--color-res-podcast);
  background: var(--color-res-podcast);
}

.home-index-unit--website,
.home-index-swatch--website {
  fill: var(--color-primary);
  background: var(--color-primary);
}

.home-index-shelf {
  stroke: var(--color-outline-variant);
  stroke-width: 1;
  stroke-opacity: 0.6;
}

/* The collection names are the one thing the old drawing never said. They
   take the plate head's label treatment so the two lines of type in the
   plate read as one voice. */
.home-index-collection {
  font-family: var(--font-mono);
  font-size: calc(var(--type-meta) + 2pt);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  fill: var(--color-on-surface-variant);
}

/* ── Hero, merged with the profile ──
   The CV band that used to follow the hero is folded into it: one masthead
   that names the person, says what he does and offers the full record, rather
   than a name band followed by a summary band saying the same thing twice. */

.home-hero-summary {
  max-width: var(--reading-measure);
  margin-top: 0;
  font-size: var(--type-body);
  line-height: var(--leading-body);
  color: var(--color-on-surface);
}

.home-hero-summary p {
  margin-bottom: var(--space-md);
}

.home-hero-summary p:last-child {
  margin-bottom: 0;
}

/* ── Featured article poster ──
   Image stretches to match content height, with object-fit: cover cropping. */
.home-featured .ledger-poster {
  height: 100%;
  min-height: 8rem;
  border: 1.5px solid var(--border-ink);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-on-surface) 10%, transparent);
}

:root:not([data-theme="dark"]) .home-featured .ledger-poster,
html[data-theme="light"] .home-featured .ledger-poster {
  border-width: 1px;
  border-color: var(--border-ink);
}

.home-featured .ledger-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.home-featured .ledger-poster::after {
  inset: 0.4rem;
  --frame-corner-size: 0.85rem;
}

@media (max-width: 899px) {
  .home-featured-lead {
    order: 1;
  }

  .home-featured .ledger-poster {
    order: 2;
    height: 11rem;
  }
}

/* ── Hero portrait, full-bleed on a phone ──
   On a phone the hero is one column and the portrait is the only element that
   can carry the screen's full width, so it runs edge to edge instead of being
   inset like the copy above it. The pull is exactly the gutter the band pads
   with — the same --gutter-mobile token, mirrored on both sides — so the plate
   ends flush with the viewport and adds no scrollable width; this must stay
   below 768px, which is where .home-band-inner swaps that token for --gutter.
   The side hairlines go with it: a border pinned to the screen edge reads as a
   frame cut off rather than as the plate's edge. The plate stays 3:4, the
   same frame as the portrait file, so cover does not crop it again. A
   configured hero_landscape switches this query to 16:9 and contain. */
@media (max-width: 767px) {
  .home-hero-portrait {
    max-width: none;
    width: calc(100% + (2 * var(--gutter-mobile)));
    margin-inline: calc(-1 * var(--gutter-mobile));
  }

  .home-hero-plate {
    max-width: none;
    width: 100%;
    border-inline: 0;
  }
}

/* ── Hero portrait between phone and desktop ──
   Keep the plate modest; the 3:4 crop applies from tablet up. */
@media (min-width: 768px) and (max-width: 1023px) {
  .home-hero-portrait {
    max-width: 14rem;
  }
}

/* ── Bibliography stats plate ── */
#home-bib-panel .home-index-plate {
  display: flex;
  flex-direction: column;
}

#home-bib-panel .home-index-plate-head {
  flex: 0 0 auto;
}

#home-bib-panel .home-index-tally {
  flex-basis: 100%;
}

.bib-stat-table {
  width: 100%;
  border-collapse: collapse;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 0 var(--space-md);
}

.bib-stat-table tbody {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin-top: auto;
}

.bib-stat-table tr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.bib-stat-table td {
  padding: var(--space-xs) var(--space-md);
  font-family: var(--font-label);
  font-size: var(--type-label);
  letter-spacing: 0.03em;
  color: var(--color-on-surface-variant);
  border-bottom: 1px solid var(--border-gentle-subtle);
}

.bib-stat-table tr:last-child td {
  border-bottom: none;
}

.bib-stat-count {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--color-on-surface);
}
