/* ---------------------------------------------------------------------------
   codex.css — the shared ground for every page on the site.
   Extracted from _layouts/portfolio.html so the homepage and the four content
   pages cannot drift apart. Loaded by both `portfolio` and `codex-page`.

   Note there is deliberately no `scroll-behavior: smooth` here. Anchor scrolls
   are driven by ScrollToPlugin instead: the browser's implementation cannot be
   interrupted mid-flight and fights ScrollTrigger's cached scroll position.
   --------------------------------------------------------------------------- */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: #f0e6cf;
  color: #4a352b;
  font-family: 'Alegreya Sans', system-ui, sans-serif;
  line-height: 1.6;
  overflow-x: hidden;
}

::selection { background: rgba(62,39,35,0.18); color: #3e2723; }

:root {
  --accent: #8a3b25;
  --accent-clinician: #9b2d20;
  --accent-data: #2f5d62;
  --accent-stat: #3f3d6e;
  --ink: #3e2723;
  --ink-soft: #4a352b;
  --ink-faint: #5c4436;
  --rule: rgba(62,39,35,0.2);
}

/* --- Cross-page continuity ------------------------------------------------
   Native view transitions. The parchment cross-fades between pages instead of
   flashing white, which is what makes the homepage and the content pages read
   as one document. No library, no runtime cost, silently ignored where the
   browser doesn't support it. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* --- Keyframes ------------------------------------------------------------
   Only the genuinely ambient loops still run on CSS. The intro sequence moved
   to a single GSAP timeline (see codex.js) so it shares a clock and an easing
   personality with the rest of the page; `fadeUp` survives here purely as the
   no-JS fallback below. */
@keyframes spin      { to { transform: rotate(360deg); } }
@keyframes glowPulse { 0%,100%{opacity:.5; transform:translate(-50%,-50%) scale(1);} 50%{opacity:.85; transform:translate(-50%,-50%) scale(1.08);} }
@keyframes ecgSweep  { from { stroke-dashoffset: 1100; } to { stroke-dashoffset: 0; } }
@keyframes beat      { 0%,100%{transform:scale(1);} 12%{transform:scale(1.12);} 26%{transform:scale(1);} 42%{transform:scale(1.05);} 56%{transform:scale(1);} }
@keyframes fadeUp    { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:translateY(0); } }

/* --- Intro fallback -------------------------------------------------------
   `no-gsap` sits on <html> in the markup and is removed by codex.js the moment
   GSAP is confirmed present. So the intro elements start hidden and are faded
   in by the GSAP timeline — but if gsap.min.js 404s (as it once did, when the
   Jekyll `exclude` list swallowed the vendor directory), the class stays and
   this rule brings the content in anyway. Content must never be trapped
   behind a script that failed to load. */
[data-intro] { opacity: 0; }
html.no-gsap [data-intro] { animation: fadeUp .9s ease both; }
html.no-gsap [data-intro="draw"] { animation: none; opacity: 1; }

#codexMotifs img { backface-visibility: hidden; }

/* --- Cursor states --------------------------------------------------------
   The quill replaces the pointer on fine-pointer devices, but a page whose job
   is reading still has to let you select text — so over a text block the quill
   stands down and the native caret comes back. */
body.cx-quill #codexRoot,
body.cx-quill #codexRoot * { cursor: none !important; }
body.cx-quill.cx-text #codexRoot,
body.cx-quill.cx-text #codexRoot * { cursor: text !important; }
body.cx-quill.cx-text #cxCompass { opacity: 0; }
#cxCompass { transition: opacity .18s ease; }

/* --- Reduced motion -------------------------------------------------------
   The CSS half. codex.js carries the other half: GSAP writes inline transforms
   and is completely unaffected by `animation: none`, so every tween is guarded
   in the script as well. */
@media (prefers-reduced-motion: reduce) {
  #codexMotifs, #cxCompass, #cxGlow, #lensWash { display: none !important; }
  * { animation: none !important; }
  [data-intro] { opacity: 1 !important; }
}

/* --- Homepage responsive --------------------------------------------------- */
@media (max-width: 900px) {
  #home { grid-template-columns: 1fr !important; gap: 40px !important; text-align: center; }
  #home h1 { margin-left: auto; margin-right: auto; }
  #home p { margin-left: auto; margin-right: auto; }
  #home .cta-row { justify-content: center; }
  #heroPortrait { margin: 0 auto; max-width: 360px; }
  .trajectory-grid { grid-template-columns: 1fr !important; }
  .research-pipeline { grid-template-columns: 1fr !important; }
  .cv-grid { grid-template-columns: 1fr !important; }
  .research-grid { grid-template-columns: 1fr !important; gap: 30px !important; }
}

/* ===========================================================================
   Content pages (/cv/, /publications/, /academics/, /contact/)
   The codex idiom applied to dense reading matter. Same parchment, same ink,
   same masthead as the homepage — but the type is set for someone actually
   reading a CV end to end, not skimming a landing page.
   =========================================================================== */

.codex-page {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  margin: 0 auto;
  padding: 118px 30px 90px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 232px;
  gap: 52px;
  align-items: start;
}

/* No marginal index on this page — don't leave a column of dead space. */
.codex-page--wide { grid-template-columns: minmax(0, 1fr); max-width: 940px; }

@media (max-width: 1000px) {
  .codex-page { grid-template-columns: minmax(0, 1fr); gap: 0; padding-top: 104px; }
  .codex-aside { display: none; }
}

/* The sheet the text is written on. Faintly lighter than the surrounding
   parchment and edged in ink, so the reading column separates from the
   background plates surfacing behind it without becoming a white card. */
.codex-sheet {
  position: relative;
  min-width: 0;
  background: rgba(250, 243, 226, 0.72);
  border: 1px solid rgba(62,39,35,0.16);
  border-radius: 2px;
  box-shadow: 0 2px 0 rgba(62,39,35,0.07), 3px 3px 0 rgba(62,39,35,0.05);
  padding: 46px clamp(26px, 4vw, 58px) 54px;
}

.codex-title {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 600;
  font-size: clamp(38px, 5vw, 62px);
  line-height: 1.02;
  letter-spacing: -0.5px;
  color: var(--ink);
  margin: 0 0 4px;
}

.codex-title em { font-style: italic; color: var(--accent); }

.codex-rule { display: block; width: 220px; height: 16px; margin: 0 0 8px; }

.codex-standfirst {
  font-family: 'Caveat', cursive;
  font-size: 21px;
  color: #8a7256;
  margin: 0 0 30px;
}

/* --- Body type ------------------------------------------------------------ */
/* Clear the title's ink rule before the first block of text. */
.codex-body { font-size: 17px; color: var(--ink-soft); margin-top: 22px; }

.codex-body h2 {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 600;
  font-size: 31px;
  line-height: 1.15;
  color: var(--ink);
  margin: 46px 0 4px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--rule);
  scroll-margin-top: 104px;
}

.codex-body h2:first-child { margin-top: 0; }

.codex-body h3 {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 600;
  font-size: 23px;
  color: var(--ink);
  margin: 30px 0 3px;
  scroll-margin-top: 104px;
}

.codex-body h4 {
  font-family: 'Alegreya Sans', sans-serif;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 24px 0 3px;
}

.codex-body p { margin: 0 0 15px; }
.codex-body ul, .codex-body ol { margin: 0 0 16px; padding-left: 21px; }
.codex-body li { margin: 0 0 6px; }
.codex-body li::marker { color: var(--accent); }
.codex-body strong { color: var(--ink); font-weight: 700; }
.codex-body em { font-style: italic; }

.codex-body a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid rgba(138,59,37,0.38);
  transition: border-color .25s ease, background-color .25s ease;
}

.codex-body a:hover {
  border-bottom-color: var(--accent);
  background: rgba(138,59,37,0.07);
}

/* A horizontal rule in a codex is a hatched flourish, not a grey line. */
.codex-body hr {
  border: 0;
  height: 9px;
  margin: 34px 0;
  background-image: repeating-linear-gradient(
    62deg, rgba(62,39,35,0.30) 0 1px, transparent 1px 7px);
  opacity: 0.6;
}

.codex-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.87em;
  background: rgba(62,39,35,0.07);
  border: 1px solid rgba(62,39,35,0.12);
  border-radius: 2px;
  padding: 1px 5px;
}

.codex-body pre {
  background: rgba(62,39,35,0.06);
  border: 1px solid rgba(62,39,35,0.14);
  border-radius: 2px;
  padding: 14px 16px;
  overflow-x: auto;
}

.codex-body pre code { background: none; border: 0; padding: 0; }

.codex-body blockquote {
  margin: 0 0 16px;
  padding: 2px 0 2px 18px;
  border-left: 2px solid rgba(138,59,37,0.45);
  color: var(--ink-faint);
  font-style: italic;
}

.codex-body table { width: 100%; border-collapse: collapse; margin: 0 0 18px; font-size: 15.5px; }
.codex-body th, .codex-body td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--rule); }
.codex-body th { font-weight: 700; color: var(--ink); }

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

/* The CV's download button, and any other themed button that survives. */
.codex-body .btn,
.codex-body .btn--primary {
  display: inline-block;
  text-decoration: none;
  border: 0;
  font-family: 'Alegreya Sans', sans-serif;
  font-size: 15px;
  color: #faf3e2;
  background: var(--accent);
  padding: 11px 24px;
  border-radius: 2px;
  box-shadow: 2px 2px 0 rgba(62,39,35,0.5);
  transition: transform .22s ease;
}

.codex-body .btn:hover { background: var(--accent); }

/* --- Coursework cards -----------------------------------------------------
   /academics/ renders its collection through the theme's `archive-single.html`
   include, so the markup is academicpages' but the styling is ours — the cards
   become folio plates rather than the theme's white list items. Restyling the
   existing markup avoids forking a template that still works. */
.codex-body .grid__wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: 18px;
  margin: 0 0 34px;
}

.codex-body .grid__item,
.codex-body .list__item { min-width: 0; }

.codex-body .archive__item {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: rgba(244,236,216,0.6);
  border: 1px solid rgba(62,39,35,0.22);
  border-radius: 2px;
  padding: 16px 18px 18px;
  box-shadow: 2px 2px 0 rgba(62,39,35,0.07);
  transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}

.codex-body .archive__item:hover {
  transform: translateY(-4px);
  border-color: rgba(138,59,37,0.5);
  box-shadow: 3px 5px 0 rgba(62,39,35,0.12);
}

/* Card headings are not document structure — keep them out of the h2 rule. */
.codex-body .archive__item-title {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 600;
  font-size: 20px;
  line-height: 1.2;
  margin: 0 0 5px;
  padding: 0;
  border: 0;
}

.codex-body .archive__item-title a { border-bottom: 0; color: var(--ink); }
.codex-body .archive__item-title a:hover { color: var(--accent); background: none; }
.codex-body .archive__item-title .fa-link { display: none; }

.codex-body .archive__item-excerpt {
  font-size: 15px;
  color: var(--ink-soft);
  margin: 0;
}

.codex-body .page__date,
.codex-body .page__meta {
  font-family: 'Caveat', cursive;
  font-size: 16px;
  color: #8a7256;
  margin: 0 0 7px;
}

.codex-body .page__date strong,
.codex-body .page__date i { display: none; }

.codex-body .archive__subtitle {
  font-family: 'Cormorant Garamond', serif;
  font-size: 25px;
  color: var(--ink);
  margin: 34px 0 14px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}

/* --- Marginal table of contents ------------------------------------------
   The theme never shipped a `toc.html` include, so `toc: true` in front matter
   was inert. A long CV wants one; this is it, set in the margin like a
   rubricated index rather than a boxed widget. */
.codex-aside {
  position: sticky;
  top: 104px;
  align-self: start;
  font-family: 'Alegreya Sans', sans-serif;
  font-size: 14px;
}

.codex-aside-title {
  font-family: 'Caveat', cursive;
  font-size: 19px;
  color: #8a7256;
  margin: 0 0 9px;
}

.codex-toc { list-style: none; margin: 0; padding: 0 0 0 13px; border-left: 1px solid var(--rule); }
.codex-toc li { margin: 0 0 3px; }

.codex-toc a {
  display: block;
  padding: 3px 0;
  color: var(--ink-faint);
  text-decoration: none;
  line-height: 1.35;
  transition: color .25s ease, transform .25s ease;
}

.codex-toc a:hover { color: var(--accent); transform: translateX(2px); }
.codex-toc a.is-active { color: var(--accent); font-weight: 700; }
.codex-toc .toc-h3 { padding-left: 12px; font-size: 13.3px; }

/* --- Print ----------------------------------------------------------------
   Committees print the CV. Strip the atmosphere and leave the document. */
@media print {
  #codexMotifs, #cxCompass, #cxGlow, #lensWash, #inkLine,
  .codex-aside, nav { display: none !important; }
  body, #codexRoot { background: #fff !important; }
  .codex-page { display: block; padding: 0; max-width: none; }
  .codex-sheet { background: none; border: 0; box-shadow: none; padding: 0; }
  .codex-body a { border-bottom: 0; color: #000; }
  [data-intro] { opacity: 1 !important; }
}
