/* ==========================================================================
   components.css — the visual pieces
   One block per component: intro, entry, contact.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Intro — portrait, greeting, two paragraphs
   -------------------------------------------------------------------------- */

/* A fixed frame that the photo is cropped into, at every width. The min()
   only bites on viewports narrower than the frame plus its gutters, where the
   frame narrows and the crop tightens rather than the photo distorting. */
.intro__photo {
  width: min(100%, var(--photo-width));
  height: var(--photo-height);
  object-fit: cover;
  object-position: var(--photo-focus);
}

.intro > .label {
  margin-top: var(--space-photo-to-heading);
  margin-bottom: var(--space-heading-to-text);
}

.intro__paragraph {
  color: var(--color-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.intro__paragraph + .intro__paragraph {
  margin-top: var(--space-paragraph);
}

/* --------------------------------------------------------------------------
   Entry — one row of Education / Work / Projects / Skills
   -------------------------------------------------------------------------- */

.entry__meta {
  color: var(--color-meta);
  font-size: var(--text-entry);
  line-height: var(--leading-entry);
  font-variant-numeric: lining-nums;
}

.entry__title {
  color: var(--color-ink);
  font-size: var(--text-entry);
  font-weight: var(--weight-bold);
  line-height: var(--leading-entry);
}

.entry__description {
  color: var(--color-detail);
  font-size: var(--text-detail);
  line-height: var(--leading-detail);
}

/* A description that follows a title needs a little air; one that stands
   alone (Coursework) sits flush with the meta column. */
.entry__title + .entry__description {
  margin-top: var(--space-title-to-detail);
}

/* A skills row carries a value rather than a description: it is set at the
   entry size, not the smaller detail size, which is what gives that section
   its looser rhythm. */
.entry__value {
  color: var(--color-detail);
  font-size: var(--text-entry);
  line-height: var(--leading-entry);
}

/* "Read paper" sits inline at the end of the project title, but in the
   regular weight so the title still reads as the heading. It wraps with the
   title rather than being held together. */
.entry__link {
  font-weight: var(--weight-regular);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  transition: color 0.15s ease;
}

.entry__link:hover {
  color: var(--color-detail);
}

/* --------------------------------------------------------------------------
   Contact — the inverted block at the foot of the page
   -------------------------------------------------------------------------- */

.contact {
  margin-top: var(--space-contact-above);
  padding: var(--contact-padding-block) var(--contact-padding-inline);
  background: var(--color-inverse-surface);
  color: var(--color-inverse-ink);
  text-align: center;
}

.contact__title {
  font-size: var(--text-heading);
  font-weight: var(--weight-bold);
  line-height: var(--leading-flat);
  letter-spacing: var(--tracking-heading);
  text-transform: uppercase;
  margin-bottom: var(--contact-title-gap);
}

.contact__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  column-gap: var(--contact-column-gap);
  row-gap: var(--contact-row-gap);
}

.contact__item {
  display: inline-flex;
  align-items: baseline;
  gap: var(--contact-pair-gap);
  line-height: var(--leading-flat);
}

.contact__label {
  color: var(--color-inverse-meta);
  font-size: var(--text-contact);
}

.contact__value {
  color: var(--color-inverse-ink);
  font-size: var(--text-contact);
}

.contact__value--link {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 0.15s ease;
}

.contact__value--link:hover {
  color: var(--color-inverse-meta);
}
