/* ══════════════════════════════════════════════
   TERZA STUDIO — article index
   Layout only; colour, face and step come from the
   tokens in css/colors|typography|spacing|radius.
   ══════════════════════════════════════════════ */

/* ══ FEATURED ═════════════════════════════════ */
.featured {
  /* clears the fixed nav and its back link */
  padding-block: clamp(120px, 14vh, 170px) var(--space-3xl);
  background: var(--color-bg-subtle);
}

.featured-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(var(--space-xl), 5vw, var(--space-3xl));
  align-items: center;
}

.featured-flags {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 0 var(--space-md);
}

.featured-badge {
  padding: 6px 12px;
  border-radius: var(--radius-xs);
  corner-shape: round;
  background: var(--color-accent);
  color: var(--color-bg);
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  font-weight: var(--fw-600);
  letter-spacing: var(--ls-0-1em);
  text-transform: uppercase;
}

.featured-time {
  font-size: var(--text-14px);
  color: var(--color-text-subtle);
}

.featured-title {
  font-size: var(--text-48px);
  line-height: var(--lh-1-1);
  margin-bottom: var(--space-md);
  text-wrap: balance;
}

.featured-title a {
  transition: color .3s var(--ease-out-expo);
}

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

.featured-excerpt {
  margin: 0 0 var(--space-lg);
  max-width: 48ch;
  font-size: var(--text-18px);
  line-height: var(--lh-1-7);
  color: var(--color-text-muted);
}

.featured-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-lg);
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  font-weight: var(--fw-600);
  letter-spacing: var(--ls-0-1em);
  text-transform: uppercase;
  color: var(--color-accent);
}

.featured-link span {
  transition: translate .3s var(--ease-out-expo);
}

.featured-link:hover span {
  translate: 4px 0;
}

/* the figure holds the ratio, not the image — an <img> inside a grid
   item reports its own intrinsic height, which overrode aspect-ratio */
.featured-media {
  margin: 0;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-subtle);
}

.featured-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── byline, shared by the featured block and the cards ── */
.byline {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: var(--text-14px);
  color: var(--color-text-subtle);
}

.byline b {
  display: block;
  font-weight: var(--fw-500);
  font-size: var(--text-14px);
  color: var(--color-text);
}

.post-card .byline b {
  display: inline;
  font-size: var(--text-14px);
}

.post-card .byline b::after {
  content: ' ·';
  color: var(--color-text-subtle);
}

.byline-avatar {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: var(--radius-full);
  corner-shape: round;
  object-fit: cover;
  border: 1px solid var(--color-border-subtle);
}

.post-card .byline-avatar {
  width: 24px;
  height: 24px;
}

/* ══ FILTERS ══════════════════════════════════ */
.index {
  padding-block: var(--space-xl) var(--space-3xl);
}

.filters {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-xl);
}

.filters-label {
  flex: none;
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  font-weight: var(--fw-600);
  letter-spacing: var(--ls-0-14em);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

/* ── the group: one control, not eight chips ── */
/* a filled track with the selected category as a pill floating inside it, so
   the row reads as a selector with one setting — which is what it is — rather
   than eight independent toggles that happen to sit near each other */
.filter-group {
  display: flex;
  /* the containing block for the travelling pill */
  position: relative;
  /* lets the strip shrink below its content width and scroll instead */
  min-width: 0;
  /* a filled track rather than an outlined one: the selected category is a
     pill floating inside it, so the control reads at a glance instead of
     asking you to spot which of eight outlines is filled. the fill is quiet
     enough to sit under the page, so a hairline gives it back its shape */
  background-color: var(--color-bg-subtle);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  corner-shape: round;
  /* the gutter the active pill floats in */
  padding: 4px;
  /* it scrolls rather than wraps: a wrapped segmented control breaks its own
     outline, and eight categories will not fit a phone on one line */
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.filter-group::-webkit-scrollbar {
  display: none;
}

/* ── the selection, as one thing that moves ─── */
/* a fill that switches segments reads as two separate backgrounds blinking;
   a single pill that travels reads as the selection being carried across.
   built by articles.js, which measures the segment it has to land on */
.filter-indicator {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: var(--radius-pill);
  corner-shape: round;
  background-color: var(--color-accent);
  pointer-events: none;
}

/* armed only once it has been placed, so it does not slide in from the left
   edge of the track on first paint */
.filter-group.is-armed .filter-indicator {
  transition: transform .45s var(--ease-ink), width .45s var(--ease-ink);
}

.filter {
  flex: none;
  /* the label rides above the pill travelling underneath it */
  position: relative;
  z-index: 1;
  scroll-snap-align: start;
  padding: var(--btn-pad-sm);
  /* no divider and no outline: separation comes from the filled pill, the way
     it does on the track this is modelled on */
  border: 0;
  border-radius: var(--radius-pill);
  corner-shape: round;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  /* one weight for every segment. bolding only the selected one re-measures
     that pill and shunts everything to its right along by a few pixels */
  font-weight: var(--fw-600);
  /* muted against the track, but still AA at this size — 4.5:1 is the floor
     for a 14px label and --color-text-muted clears it on this ground */
  color: var(--color-text-muted);
  /* the ink wipe survives, darkened now that the track is light */
  background-color: transparent;
  background-image: linear-gradient(color-mix(in srgb, var(--color-text) 7%, transparent),
      color-mix(in srgb, var(--color-text) 7%, transparent));
  background-repeat: no-repeat;
  background-position: 50% 100%;
  background-size: 100% 0;
  transition: background-size .4s var(--ease-ink), background-color .3s var(--ease-ink),
    color .3s var(--ease-ink), border-color .3s var(--ease-ink);
}

/* the outline would be clipped by the group's own overflow, so it sits inside.
   currentColor keeps it visible on both grounds: espresso on the track,
   sand on the selected pill */
.filter:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: -3px;
}

.filter:hover {
  background-size: 100% 100%;
  color: var(--color-text);
}

/* the selected pill: the accent doing the work it does everywhere else on the
   site, now that the track is quiet enough to let it */
/* no fill of its own any more — the indicator underneath supplies it, so the
   selected segment only has to hand over its label colour */
.filter.is-active,
.filter.is-active:hover {
  background-image: none;
  color: var(--color-bg);
}

/* ══ POST GRID ════════════════════════════════ */
.post-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-lg), 3vw, var(--space-xl)) var(--space-lg);
}

.post-card[hidden] {
  display: none;
}

.post-link {
  display: grid;
  /* the byline pins to the foot so uneven excerpts still line up */
  grid-template-rows: auto auto auto 1fr auto;
  height: 100%;
}

/* the frame holds the ratio, not the image: as a direct grid item an
   <img> gets its auto row from its own intrinsic height, so the box
   ended up as tall as the source file rather than 4:3 */
.post-thumb-frame {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-xs);
  border: 1px solid var(--color-border-subtle);
  margin-bottom: var(--space-sm);
  transition: border-color .4s var(--ease-out-expo);
}

.post-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.post-card:hover .post-thumb-frame {
  border-color: var(--color-accent);
}

/* ── cards for a post with no artwork ───────── */
/* an article can be ready before its image is. the frame keeps its 4:3 so the
   grid stays even, and the category fills it rather than a grey rectangle */
.post-thumb-frame.is-textual {
  display: grid;
  place-items: center;
  background: var(--color-bg-subtle);
}

.post-thumb-text {
  font-family: var(--font-serif);
  font-size: var(--text-28px);
  letter-spacing: var(--ls-neg-0-02em);
  color: var(--color-text-subtle);
}

.post-flags {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.post-category {
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  font-weight: var(--fw-600);
  letter-spacing: var(--ls-0-14em);
  text-transform: uppercase;
  color: var(--color-accent);
}

.post-time {
  font-size: var(--text-14px);
  color: var(--color-text-subtle);
}

.post-title {
  font-size: var(--text-24px);
  line-height: var(--lh-1-25);
  margin-bottom: var(--space-xs);
  transition: color .3s var(--ease-out-expo);
}

.post-card:hover .post-title {
  color: var(--color-accent);
}

.post-excerpt {
  display: block;
  margin-bottom: var(--space-md);
  font-size: var(--text-18px);
  line-height: var(--lh-1-6);
  color: var(--color-text-muted);
}

.post-empty {
  margin: var(--space-xl) 0 0;
  font-size: var(--text-16px);
  color: var(--color-text-subtle);
}

/* ══ PAGINATION ═══════════════════════════════ */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin-top: var(--space-3xl);
}

.pager[hidden] {
  display: none;
}

.pager-pages {
  display: flex;
  gap: var(--space-xs);
}

.pager-btn {
  min-width: 40px;
  padding: var(--btn-pad-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  corner-shape: round;
  background-color: transparent;
  background-image: linear-gradient(var(--color-fill), var(--color-fill));
  background-repeat: no-repeat;
  background-position: 50% 100%;
  background-size: 100% 0;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: var(--text-14px);
  color: var(--color-text);
  transition: background .3s var(--ease-out-expo), color .3s var(--ease-out-expo),
    border-color .3s var(--ease-out-expo);
}

.pager-btn:hover:not(:disabled) {
  background-size: 100% 100%;
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.pager-btn:disabled {
  opacity: .4;
  cursor: default;
}

.pager-btn.is-active {
  background-image: none;
  background-color: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-bg);
}

/* ══ RESPONSIVE ═══════════════════════════════ */
@media (max-width: 1200px) {
  .post-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .featured-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* the image leads once the block stacks */
  .featured-media {
    order: -1;
  }

  .featured-title {
    font-size: var(--text-40px);
  }
}

@media (max-width: 1200px) {
  .filters {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-sm);
  }

}

/* the grid collapses at the tablet boundary; the headline holds its size
   until the column is actually narrow */
@media (max-width: 680px) {
  .featured-title {
    font-size: var(--text-32px);
  }
}

/* ══ INDEX — phone ════════════════════════════ */
@media (max-width: 600px) {
  .post-grid {
    grid-template-columns: minmax(0, 1fr);
    /* one column reads as a list, and a list needs the rows told apart */
    gap: var(--space-2xl);
  }

  /* a 4:3 frame at full phone width is most of a screen before the title
     even appears. 16:9 halves that without dropping the image, so two cards
     land in a viewport instead of most of one */
  .post-thumb-frame,
  .featured-media {
    aspect-ratio: 16 / 9;
  }

  /* the stand-in for a missing image has less height to fill now */
  .post-thumb-text {
    font-size: var(--text-24px);
  }

  /* the excerpt is a taster, not the article. three lines is enough to
     decide on, and it keeps the whole card above the fold */
  .post-excerpt {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
  }
}

