/* ==========================================================================
   components.css — buttons, chips, timeline, cards, contact
   Depends on tokens.css and base.css.
   ========================================================================== */

/* --- Buttons ---------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius-m);
  font-size: var(--step-0);
  font-weight: var(--weight-medium);
  text-decoration: none;
  border: var(--border-width) solid transparent;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

.btn svg {
  width: 1.1em;
  height: 1.1em;
}

.btn--primary {
  background-color: var(--accent);
  color: var(--accent-contrast);
}

.btn--primary:hover {
  background-color: var(--accent-hover);
  color: var(--accent-contrast);
}

.btn--secondary {
  border-color: var(--border-strong);
  color: var(--text);
}

.btn--secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* --- Chips -------------------------------------------------------------------- */

.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.chip {
  display: inline-block;
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-pill);
  background-color: var(--surface-sunken);
  color: var(--text-muted);
  font-size: var(--step--1);
  line-height: 1.5;
  white-space: nowrap;
}

/* --- Experience timeline ------------------------------------------------------
   Two levels: an employer block (.timeline-group) for a company with more
   than one engagement, and a single role entry (.role) inside it. A company
   with one engagement skips the group wrapper entirely — see index.html. */

/* Scoped to .wrap's direct children only — top-level Experience entries
   (a company group, or a standalone single-role company). Without the
   `.wrap >` scope this also matches roles nested inside a
   .timeline-group__roles, stacking on top of that group's own spacing rule
   below and doubling the gap between a company's own engagements. */
.wrap > .timeline-group + .timeline-group,
.wrap > .timeline-group + .role,
.wrap > .role + .timeline-group,
.wrap > .role + .role {
  margin-top: var(--space-l);
}

.timeline-group__header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-s);
  margin-bottom: var(--space-m);
}

.timeline-group__header h3 {
  font-family: var(--font-display);
}

/* Company name links through to the company's own site, but reads as plain
   heading text — no colour or underline change, just a click target.
   :focus-visible keeps the site-wide focus ring (base.css), so it's still
   operable and visible to a keyboard user; only the resting/hover colour
   and underline are suppressed. */
.timeline-group__company-link {
  color: inherit;
  text-decoration: none;
}

.timeline-group__span {
  color: var(--text-muted);
  font-size: var(--step--1);
}

.timeline-group__roles {
  position: relative;
  padding-left: var(--space-l);
  border-left: var(--border-width) solid var(--border);
}

.role {
  position: relative;
  max-width: none;
}

.timeline-group__roles .role {
  /* Deliberately less than the --space-l gap between top-level entries
     above — roles within one company should read as closer together than
     two different companies. */
  padding-bottom: var(--space-m);
}

.timeline-group__roles .role:last-child {
  padding-bottom: 0;
}

.timeline-group__roles .role::before {
  content: '';
  position: absolute;
  left: calc(-1 * var(--space-l) - 4px);
  top: 0.5em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--accent);
  border: 2px solid var(--surface);
}

.role__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2xs) var(--space-m);
}

.role__title {
  font-weight: var(--weight-semibold);
  font-size: var(--step-1);
}

.role__dates {
  flex-shrink: 0;
  color: var(--text-muted);
  font-size: var(--step--1);
  white-space: nowrap;
}

.role__meta {
  margin-top: var(--space-3xs);
  color: var(--text-muted);
  font-size: var(--step--1);
}

.role__summary {
  margin-top: var(--space-s);
  /* Matches .role__highlights li's own padding-left below, so the
     summary text lines up with the bullet text under it instead of
     starting slightly further left. */
  padding-left: 0.3em;
}

.role__highlights {
  margin-top: var(--space-2xs);
  padding-left: 1.1em;
}

.role__highlights li {
  margin-top: var(--space-3xs);
  padding-left: 0.3em;
}

.role__tech {
  margin-top: var(--space-s);
}

/* --- Skills -------------------------------------------------------------------- */

.skills-grid {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .skills-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.skills-group h3 {
  font-size: var(--step-0);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-xs);
}

/* --- Education & certifications card grid --------------------------------------- */

.info-grid {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .info-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.info-card {
  display: block;
  padding: var(--space-m);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-l);
  background-color: var(--surface-raised);
  color: inherit;
  text-decoration: none;
}

.info-card > * + * {
  margin-top: var(--space-3xs);
}

.info-card h3 {
  font-size: var(--step-0);
  font-weight: var(--weight-semibold);
}

.info-card__meta {
  color: var(--text-muted);
  font-size: var(--step--1);
}

/* Certification links: same invisible-link treatment as company names
   (no colour, no underline) — but these sit inline in running text with
   nothing else marking them as clickable, so a small external-link icon
   (matching .contact-card's) stands in for the colour/underline cue that
   was removed. Plain inline, not flex: a flex row keeps the icon glued
   to the end of an unwrapped line, so on a narrow viewport — where the
   title wraps onto two lines — the icon ends up stranded out at the
   width of the longest line instead of sitting right after the last
   word.

   The markup wraps the last word + icon in .info-card__cert-link-tail
   with white-space: nowrap, so they always move to the next line
   together if they don't both fit. A bare &nbsp; between them was
   tried first and didn't work, and neither did nowrap alone at first —
   the actual cause of both failures was base.css's global
   svg { display: block }, which pulls the icon out of inline text flow
   entirely regardless of nowrap on its container. Fixed by overriding
   display back to inline on this specific svg, below. */
.info-card__cert-link {
  color: inherit;
  text-decoration: none;
}

.info-card__cert-link-tail {
  white-space: nowrap;
}

.info-card__cert-link svg {
  /* Overrides base.css's global svg { display: block } reset — a
     block-level svg can't flow inline with text at all, which is what
     was actually breaking the nowrap grouping above (not the nowrap
     itself, which was working correctly all along). */
  display: inline;
  width: 0.875rem;
  height: 0.875rem;
  vertical-align: -0.125em;
  color: var(--text-muted);
}

.info-card ul {
  margin-top: var(--space-s);
}

.info-card ul li + li {
  margin-top: var(--space-xs);
}

.info-card ul li > * + * {
  margin-top: 0;
}

/* --- Contact -------------------------------------------------------------------- */

.contact-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
}

.contact-card {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-s) var(--space-m);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-l);
  color: var(--text);
  text-decoration: none;
  min-height: 44px;
}

.contact-card:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.contact-card svg {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  color: var(--text-muted);
}

.contact-card:hover svg {
  color: var(--accent);
}

/* --- Narrow-viewport overrides ---------------------------------------------
   Below 640px a bold title and a date range/location line, crammed onto one
   flex row, either collide or half-wrap depending on how long the title
   happens to be — "Java Developer" (short) sits inline; "Senior Data
   Engineer" (longer) wraps. That inconsistency reads as broken even where
   each individual case is technically fine. Force every entry onto the same
   two-line shape instead, regardless of title length. */
@media (max-width: 640px) {
  .role__head,
  .timeline-group__header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3xs);
  }
}
