/* ===========================================================================
   Paula R. Henderson — site styles
   ---------------------------------------------------------------------------
   The design idea, so later edits don't accidentally undo it:

   The page is set like a printed page with a HUNG MARGIN. Section names
   ("Research", "Education", "Presentations") sit out in a left-hand rail,
   right-aligned against a hairline rule, beside the text they belong to
   rather than above it. You read the rail top-to-bottom to find a section —
   so the margin is doing the job a navigation menu would otherwise do, and
   the page needs no cards, boxes, or shadows to show its structure.

   One accent colour (a warm brick maroon, for Texas A&M) marks section names,
   links, and the rule. Everything else is ink on paper. That is the whole
   system; resist adding a second accent.

   Every colour pair below was checked against WCAG 2.1 AA:
     ink on paper 15.1:1 · maroon on paper 11.1:1 · muted on paper 6.2:1
   If you change a colour, re-check it before shipping.
   =========================================================================== */

/* --- Fonts -----------------------------------------------------------------
   Literata (SIL Open Font License, see assets/fonts/Literata-OFL.txt) is a
   variable font: one file covers every weight, so asking for 600 below costs
   no extra download. It is self-hosted rather than loaded from Google Fonts
   because the site makes no third-party requests at all.
   font-display:swap shows fallback text immediately instead of blank space. */
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin-wght-normal.woff2") format("woff2-variations");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin-wght-italic.woff2") format("woff2-variations");
  font-weight: 200 900;
  font-style: italic;
  font-display: swap;
}

/* --- Tokens ---------------------------------------------------------------- */
:root {
  --paper:       #FFFCF9;  /* barely-warm white */
  --ink:         #2B2320;  /* warm near-black, like printed ink */
  --maroon:      #6E1B27;  /* the single accent */
  --maroon-deep: #4A101A;  /* hover / pressed */
  --muted:       #6A5D57;  /* dates and other secondary text */
  --rule:        #DCD2C9;  /* hairline dividers (decorative, not text) */
  --tint:        #F6F0EA;  /* the faintest fill, used once, on the CV entries */

  --serif: "Literata", Georgia, "Iowan Old Style", "Times New Roman", serif;
  /* A neutral system sans for dates, nav and other small structural text.
     Costs nothing to download and is clearly distinct from the serif. */
  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;

  /* The hung-margin geometry. --indent is how far the body column is pushed
     right to make room for the rail; it is derived, so changing --rail alone
     keeps everything aligned. */
  --rail:      12rem;
  --rail-gap:  1.5rem;   /* rail text  →  rule */
  --prose-gap: 2.25rem;  /* rule       →  body text */
  --indent:    calc(var(--rail) + var(--rail-gap) + 1px + var(--prose-gap));

  --measure: 36rem;      /* ~68 characters of body text per line */
  --sheet:   55rem;
}

/* --- Reset ----------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* Fights iOS Safari's habit of enlarging text after a rotation. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.65;
  /* Literata reads better with slightly open text; these are safe everywhere. */
  font-variant-numeric: oldstyle-num proportional-nums;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; }

/* --- Links -----------------------------------------------------------------
   Underlined by default. Colour alone never signals that something is a link
   (WCAG 1.4.1), and the offset keeps the underline clear of descenders. */
a {
  color: var(--maroon);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
  text-decoration-color: color-mix(in srgb, var(--maroon) 40%, transparent);
}
a:hover,
a:focus-visible {
  color: var(--maroon-deep);
  text-decoration-color: currentColor;
}

/* A focus ring that is visible on every background here, for keyboard users. */
:focus-visible {
  outline: 2px solid var(--maroon);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Off-screen until tabbed to; then it appears at the top of the page. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--maroon);
  color: var(--paper);
  padding: 0.6rem 1rem;
  font-family: var(--sans);
  font-size: 0.9rem;
  text-decoration: none;
  z-index: 10;
}
.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
}

/* --- Page frame ------------------------------------------------------------ */
.sheet {
  max-width: var(--sheet);
  margin: 0 auto;
  padding: 0 1.5rem 4rem;
}

/* --- Masthead --------------------------------------------------------------
   Name on the left, two links on the right; wraps to two lines on a phone. */
.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding: 2.25rem 0 1.1rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 3rem;
}

.masthead__name {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
}
.masthead__name:hover,
.masthead__name:focus-visible { color: var(--maroon); }

.masthead__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  font-family: var(--sans);
  font-size: 0.875rem;
}
.masthead__nav a {
  color: var(--muted);
  text-decoration: none;
}
.masthead__nav a:hover,
.masthead__nav a:focus-visible { color: var(--maroon); }

/* Shown only by the print stylesheet. */
.masthead__print-contact { display: none; }

/* The page you are on is marked by an underline as well as a colour change,
   and aria-current tells a screen reader the same thing. */
.masthead__nav a[aria-current="page"] {
  color: var(--maroon);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}

/* --- The hung margin -------------------------------------------------------
   .prose pushes the body column right by --indent and draws the rule as its
   left border. Anything given .rail (a section heading, the portrait) is
   floated back out into that indent with a matching negative margin.

   Why float rather than grid: a floated element with a negative left margin
   sits entirely outside the content box, so it never shortens the lines of
   text beside it — which lets each section heading sit alongside a section of
   any length. CSS Grid would force the heading onto its own row instead.
   The trade-off is that floats must be cleared; ::after below does that. */
.prose {
  margin-left: var(--indent);
  border-left: 1px solid var(--rule);
  padding-left: var(--prose-gap);
  max-width: var(--measure);
}
.prose::after {
  content: "";
  display: block;
  clear: both;
}

.rail,
.prose > h2 {
  float: left;
  clear: both;                       /* keeps consecutive headings from stacking */
  width: var(--rail);
  margin-left: calc(-1 * var(--indent));
  text-align: right;
}

/* --- Headings --------------------------------------------------------------
   h1 → h2 → h3 in order, no levels skipped and no heading faked with bold. */
h1, h2, h3 {
  font-weight: 600;
  line-height: 1.2;
  text-wrap: balance;
}

.page-title {
  font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem);
  letter-spacing: -0.015em;
  margin: 0 0 0.75rem;
}

.lede {
  font-size: clamp(1.2rem, 1.05rem + 0.6vw, 1.4rem);
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 2.75rem;
  max-width: 32rem;
}

/* Section names in the rail. Sentence case, not all-caps: they are words to
   read, not labels to decorate. */
.prose > h2 {
  font-size: 0.9375rem;
  letter-spacing: 0.005em;
  color: var(--maroon);
  /* Set top and bottom only. The `margin` shorthand would reset the negative
     margin-left above, and the heading would fall back into the text column.
     Both must be zero: any top margin on a float moves the label down without
     moving the section beside it. */
  margin-top: 0;
  margin-bottom: 0;
  line-height: 1.35;

  /* The label is 15px and the text beside it is 18px, so their first lines do
     not sit on the same baseline on their own. These paddings drop the label
     by the difference. Three values because the difference depends on what the
     section starts with — measured, not guessed. */
  padding-top: 0.34rem;                                 /* section starts with a paragraph */
}
.prose > h2:has(+ h3)           { padding-top: 0.02rem; }
.prose > h2:has(+ .list-ledger) { padding-top: 0.22rem; }

.prose > h3 {
  font-size: 1.0625rem;
  margin: 2rem 0 0.15rem;
}

.prose > p { margin: 0 0 1.25rem; }

/* Air between sections.
   This has to be set as margin-BOTTOM on the last element of the previous
   section, never as margin-top on the heading. A floated heading is out of
   normal flow, so a margin on it moves the label without moving the section
   beside it, and the two drift apart. Pushing from above moves both by the
   same amount, so label and text stay on the same line. */
.prose > *:has(+ h2) { margin-bottom: 3rem; }

/* The first element of a section must not add its own top margin on top of
   that — h3 and the ledger lists both carry one by default. */
.prose > h2 + * { margin-top: 0; }

/* --- Lists ----------------------------------------------------------------- */
.prose ul { padding-left: 1.15rem; margin: 0 0 1.25rem; }
.prose li { margin-bottom: 0.4rem; }
.prose li::marker { color: var(--rule); }

/* A plain list of items with no bullets — used for affiliations and
   certifications, where the bullet adds nothing. */
.list-plain {
  list-style: none;
  padding-left: 0;
}
.list-plain li {
  padding-left: 0;
  margin-bottom: 0.3rem;
}

/* --- CV entries ------------------------------------------------------------
   An entry is a heading whose date sits at the right-hand end of the line and
   drops onto its own line when there is no room. Written in Markdown as:

     ### Ph.D., Special Education <span class="when">Expected May 2029</span>

   flex + wrap is what makes the date fall below the title on a narrow screen
   instead of forcing the page to scroll sideways. */
.prose > h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.15rem 1.25rem;
}

.when {
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--muted);
  white-space: nowrap;
  /* Pushes the date to the right edge even when the title wraps to two lines. */
  margin-left: auto;
}

/* The institution / department line under an entry heading. */
.where {
  color: var(--muted);
  font-size: 0.9375rem;
  margin: 0 0 0.5rem;
}

/* A ledger list: one line each, date pushed to the right edge, hairline
   between rows. Used for service, honours and certifications, where a full
   heading-and-detail entry would be more structure than the content needs.
   Written in Markdown as a normal list with `{: .list-ledger}` beneath it. */
.list-ledger {
  list-style: none;
  padding-left: 0;
  margin: 0 0 1.25rem;
}
.list-ledger > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.1rem 1.25rem;
  margin: 0;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--tint);
  line-height: 1.45;
}
.list-ledger > li:first-child { padding-top: 0; }
.list-ledger > li:last-child { border-bottom: 0; }

/* --- Footer ---------------------------------------------------------------- */
.footer {
  margin-top: 4.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
}
.footer__contact { margin: 0 0 0.75rem; line-height: 1.7; }
.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  font-family: var(--sans);
  font-size: 0.875rem;
  margin-bottom: 0.75rem;
}
.footer__meta {
  font-family: var(--sans);
  font-size: 0.8125rem;
  color: var(--muted);
  margin: 0;
}

/* --- Portrait --------------------------------------------------------------
   Sits in the rail, so the photograph is part of the margin rather than a
   banner across the top. Small on purpose: this is a scholar's page, and the
   first thing to read should be the sentence, not the picture. */
.portrait {
  display: block;
  width: var(--rail);
  height: auto;
  /* Tuned, with the 5:6 crop of the source image, so the bottom of the
     photograph falls just above the first section label — otherwise `clear`
     pushes that label down away from the text it names. If you swap the
     photograph for one of a different shape, re-check that first label. */
  margin-bottom: 1.05rem;
  border-radius: 2px;
  /* Keeps the light background of the photo from dissolving into the page. */
  box-shadow: 0 0 0 1px var(--rule);
}

/* --- Narrow screens --------------------------------------------------------
   Below this width the rail is folded away: headings return to sitting above
   their sections and the body column runs the full width. Tested at 320px,
   the narrowest viewport WCAG 1.4.10 asks for. */
@media (max-width: 60rem) {
  .prose {
    margin-left: 0;
    border-left: 0;
    padding-left: 0;
    max-width: var(--measure);
  }
  .rail,
  .prose > h2 {
    float: none;
    width: auto;
    margin-left: 0;
    text-align: left;
  }
  .prose > h2 {
    padding-top: 0;
    margin-bottom: 0.5rem;
    /* Now that it is a heading in the flow, it needs to look like one. */
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--rule);
  }
  .prose > h2 + * { margin-top: 0; }

  .portrait {
    width: 11rem;
    margin-bottom: 2rem;
  }
}

@media (max-width: 30rem) {
  .sheet { padding: 0 1.15rem 3rem; }
  body { font-size: 1.0625rem; }
  .masthead { padding-top: 1.5rem; margin-bottom: 2rem; }
  /* On the narrowest phones a nowrap date can overflow; let it break. */
  .when { white-space: normal; }
}

/* --- Motion ----------------------------------------------------------------
   There is no page animation to disable, but transitions still count as
   motion for anyone who has asked the system to reduce it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Print -----------------------------------------------------------------
   The CV is meant to be printable: "Print → Save as PDF" in any browser
   produces a clean copy, which is why the site does not need a separate PDF
   file to keep in sync. */
@media print {
  :root { --indent: 0; }
  body {
    background: #fff;
    color: #000;
    font-size: 10.5pt;
    line-height: 1.4;
  }
  .sheet { max-width: none; padding: 0; }
  /* A printed CV wants no navigation, no standfirst and no photograph — just
     the name, the contact line, and the record. */
  .masthead__nav,
  .skip-link,
  .footer__meta,
  .lede,
  .portrait { display: none; }
  .masthead {
    display: block;
    border-bottom: 1px solid #999;
    margin-bottom: 1.5rem;
    padding-top: 0;
  }
  .masthead__name { font-size: 15pt; }
  .masthead__print-contact {
    display: block;
    margin: 0.2rem 0 0;
    font-size: 9.5pt;
  }
  .prose {
    margin-left: 0;
    border-left: 0;
    padding-left: 0;
    max-width: none;
  }
  .prose > h2 {
    float: none;
    width: auto;
    margin-left: 0;
    text-align: left;
    color: #000;
    border-bottom: 1px solid #999;
    margin-top: 1.4rem;
  }
  /* Don't strand a heading at the foot of a page. */
  h2, h3 { break-after: avoid; }
  .list-ledger > li, li { break-inside: avoid; }
  a { color: #000; text-decoration: none; }
}
