/* chrisforrette.com */

@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300..700&display=swap");

/* Variables */

:root {
  /* Color palette */
  --rich-black: #001219;
  --midnight-green: #005f73;
  --teal: #0a9396;
  --tiffany: #94d2bd;
  --vanilla: #e9d8a6;
  --gamboge: #ee9b00;
  --alloy-orange: #ca6702;
  --rust: #bb3e03;
  --rufous: #ae2012;
  --auburn: #9b2226;

  /* Typography */
  --font-sans: "Space Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-wt-light: 300;
  --font-wt-normal: 400;
  --font-wt-semibold: 600;
  --font-wt-bold: 700;
}

/* Reset / Base */

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 18px;

  /* stylelint-disable-next-line property-no-vendor-prefix -- Safari and iOS
     only support the prefixed form; dropping it lets mobile Safari inflate
     text and reflow the resume. */
  -webkit-text-size-adjust: 100%;
}

@media screen {
  html:has(.landing) {
    font-size: 14px;
  }
}

body {
  font-family: var(--font-sans);
  font-weight: var(--font-wt-normal);
  color: var(--rich-black);
  background: #f6f5f3;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: var(--midnight-green);
  text-decoration: none;
  transition: color 0.2s ease;
}

a:hover {
  color: var(--teal);
}

/* Landing Page */

.landing {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;

  /* Minus the 8px full-bleed color bar above it, so the two together fill the
     viewport exactly rather than overflowing it by the height of the bar. */
  min-height: calc(100vh - 8px);
  padding: 6rem 4rem;
}

/* Name */
.name {
  font-weight: var(--font-wt-bold);
  font-size: 5rem;
  line-height: 1;
  color: var(--rich-black);
  margin-bottom: 0.5rem;
}

/* Color bar — 10 equal segments from the palette */
.color-bar {
  display: flex;
  width: 100%;
  height: 8px;
  margin-bottom: 1rem;
  background: linear-gradient(
    to right,
    var(--rich-black) 0%,
    var(--rich-black) 16.667%,
    var(--midnight-green) 16.667%,
    var(--midnight-green) 33.333%,
    var(--tiffany) 33.333%,
    var(--tiffany) 50%,
    var(--gamboge) 50%,
    var(--gamboge) 66.667%,
    var(--rust) 66.667%,
    var(--rust) 83.333%,
    var(--auburn) 83.333%,
    var(--auburn) 100%
  );
}

.color-bar::before,
.color-bar::after {
  content: none;
}

/* Full-bleed variant — the base bar sits inside a padded container and vents
   1rem below it. Flush against the top of the viewport it wants neither the
   margin nor anything between it and the edges, so it lives outside .landing. */
.color-bar-full {
  margin-bottom: 0;
}

.location {
  font-size: 1.1rem;
  color: #666;
  text-transform: uppercase;
  margin-bottom: 2rem;
}

/* Paragraph rhythm lives on the paragraphs; this margin plus the 1.25rem below
   the last one gives the 2.5rem that separates the whole bio from the icon row.
   .landing is a flex container, so .summary establishes its own formatting
   context and the last paragraph's margin cannot collapse out to do that job on
   its own. Keeping both at 1.25rem also avoids a `:last-child` reset, which
   would outrank `.cover-letter p` further down and trip
   no-descending-specificity. */
.summary {
  max-width: 540px;
  margin-bottom: 1.25rem;
}

.summary p {
  margin: 0 0 1.25rem;
  font-size: 1.125rem;
  line-height: 1.8;
  color: #333;
}

/* Icon links row */
.icon-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  list-style: none;
}

.icon-links a {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--rich-black);
  transform: scale(1);
  transition:
    color 0.2s ease,
    transform 0.2s ease;
}

.icon-links a:hover {
  color: var(--teal);
  transform: scale(1.1);
}

.icon-links svg {
  width: 24px;
  height: 24px;
}

/* Two icon styles share this row: the LinkedIn and GitHub brand marks are
   solid, while the Feather icons (resume, email) are outlined and carry their
   own fill="none" and stroke="currentColor". SVG presentation attributes lose
   to any CSS rule, so an unscoped `fill: currentColor` here would override
   fill="none" and flood the outlined icons solid. Fill only the marks that
   bring no stroke of their own. */
.icon-links svg:not([stroke]) {
  fill: currentColor;
}

@media (prefers-reduced-motion: reduce) {
  .icon-links a {
    transition: color 0.2s ease;
  }

  .icon-links a:hover {
    transform: none;
  }
}

/* --- Cover Letter --- */

.cover-letter {
  margin-top: 2rem;
}

.cover-letter p {
  font-size: 1rem;
  line-height: 1.75;
  color: #2a2a2a;
  margin-bottom: 1rem;
}

.cover-letter-sign-off {
  font-weight: var(--font-wt-bold);
  color: var(--rich-black);
}

/* --- Resume Page --- */

.resume {
  max-width: 780px;
  margin: 0 auto;
  padding: 1.5rem 2.5rem;
}

.resume-header {
  margin-bottom: 2.5rem;
}

.resume .name {
  font-size: 4rem;
  margin: 1.25rem 0;
}

.resume-tagline {
  font-size: 1rem;
  color: #666;
  margin: 1rem 0;
}

.resume-contact {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  font-size: 0.95rem;
  color: #333;
}

/* stylelint-disable-next-line no-descending-specificity -- .icon-links lives on
   the landing page and .resume-contact on the resume; they never match the same
   element, so cascade order is irrelevant. Satisfying the rule would mean
   hoisting these ~60 lines up into the Landing Page section. */
.resume-contact a {
  color: #333;
  border-bottom: 1px solid transparent;
  transition:
    border-color 0.2s ease,
    color 0.2s ease;
}

.resume-contact a:hover {
  color: var(--midnight-green);
  border-bottom-color: var(--midnight-green);
}

/* Section */
.resume section {
  margin: 2rem 0;
}

.resume h2 {
  font-size: 0.8rem;
  font-weight: var(--font-wt-bold);
  text-transform: uppercase;
  color: var(--midnight-green);
  margin: 1rem 0;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #dcd9d2;
}

.resume-intro {
  color: #2a2a2a;
  max-width: 640px;
}

/* Experience entries */
.job {
  margin-bottom: 1.75rem;
}

.job:last-child {
  margin-bottom: 0;
}

.job-header,
.job-summary,
.job-bullets,
.job-stack {
  margin: 0.5rem 0;
}

.job-dates,
.job-company {
  color: #888;
}

.job-header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  column-gap: 1rem;
}

.job-title {
  grid-column: 1;
  grid-row: 1;
  font-weight: var(--font-wt-bold);
  color: var(--rich-black);
}

.job-dates {
  grid-column: 2;
  grid-row: 1;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.job-company {
  grid-column: 1 / -1;
  grid-row: 2;
}

.job-summary {
  font-size: 0.95rem;
  line-height: 1.6;
  color: #2a2a2a;
  margin-bottom: 0.6rem;
}

.job-stack {
  font-size: 0.875rem;
  line-height: 1.55;
  color: #555;
  margin-top: 1rem;
}

.job-stack strong {
  color: var(--rich-black);
  font-weight: var(--font-wt-bold);
}

.job-bullets {
  list-style: none;
  padding-left: 1rem;
}

.job-bullets li {
  position: relative;
  margin-bottom: 0.35rem;
  line-height: 1.55;
  font-size: 0.95rem;
  color: #2a2a2a;
}

.job-bullets li::before {
  content: "";
  position: absolute;
  left: -1rem;
  top: 0.6em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--alloy-orange);
}

/* Two-column lists (education, certifications) */
.entry {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.6rem;
  flex-wrap: wrap;
}

.entry-main {
  font-size: 0.95rem;
}

.entry-main strong {
  font-weight: var(--font-wt-bold);
  color: var(--rich-black);
}

.entry-dates {
  font-size: 0.9rem;
  color: #888;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Skills grid — frozen.
   Side-by-side columns get zippered together by position-sorting PDF text
   extractors, which scrambles which skills belong to which group. Retained
   only so archived applications in applications/ keep rendering as they were
   sent; new resumes use .skills-list below. */
.skills-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem 2rem;
}

.skills-group-label {
  font-size: 0.9rem;
  font-weight: var(--font-wt-bold);
  color: var(--rich-black);
  margin-bottom: 0.35rem;
}

.skills-group-list {
  font-size: 0.9rem;
  color: #444;
  line-height: 1.5rem;
}

/* Skills rows — full-width, one group per row, label inline with its list.
   Nothing sits beside a wrapped line, so extracted text keeps its order. */
.skills-row {
  margin-bottom: 0.45rem;
}

.skills-row .skills-group-label,
.skills-row .skills-group-list {
  display: inline;
}

/* --- Print Styles --- */

@media print {
  html {
    font-size: 10pt;
  }

  body {
    color: #000;
    background: #fff;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .landing {
    min-height: auto;
  }

  a {
    color: #000;
  }

  .icon-links a {
    color: #000;
  }

  .resume {
    max-width: none;
    padding: 0;
  }

  .resume-header {
    margin-bottom: 1.5rem;
  }

  .resume h2 {
    margin-bottom: 0.75rem;
    padding-bottom: 0.35rem;
    break-after: avoid;
  }

  .resume section {
    margin-bottom: 1.5rem;
  }

  .job {
    margin-bottom: 1rem;
    orphans: 3;
    widows: 3;
  }

  .job-header,
  .job-company {
    break-after: avoid;
  }

  .job-bullets li {
    break-inside: avoid;
  }

  .job-bullets li,
  .entry-main,
  .skills-group-list {
    font-size: 9.5pt;
  }

  @page {
    margin: 0.5in;
  }
}

/* --- Mobile Responsive --- */

@media (width <= 768px) {
  .landing {
    padding: 4rem 2.5rem;
  }

  .name {
    font-size: 3rem;
  }

  .location {
    font-size: 0.95rem;
  }

  .summary {
    font-size: 1rem;
  }

  .resume {
    padding: 1rem 1.5rem;
  }

  .resume .name {
    font-size: 2.75rem;
  }
}

@media (width <= 480px) {
  .landing {
    padding: 3rem 1.5rem;
  }

  .name {
    font-size: 2.2rem;
  }

  .summary {
    font-size: 0.95rem;
  }

  .icon-links {
    gap: 1.25rem;
  }
}
