/* =========================================================
   site.css — the single source of the site-wide design.

   Loaded by every page (via _layouts/default.html), before any
   page-family stylesheet. Change a value here and every page
   follows.

   Contents
   1. Design tokens
   2. Base elements
   3. Page canvas, card, navigation
   4. Page structure (body, headings, lead, sections)
   5. Shared components
      5a. Links and buttons
      5b. Text blocks, panels and callouts
      5c. Action cards and tile grids
      5d. Accordion ribbons
      5e. Loading, empty, error and update notes
   6. Footer
   7. Reveal animation
   8. Responsive rules and reduced motion
   ========================================================= */

/* 1. Design tokens ======================================== */

:root {
  --paper: #f4f5f7;
  --paper-soft: #fafbfc;
  --sheet: #ffffff;
  --panel-deep: #e2e5e9;
  --line: rgba(28, 28, 30, 0.08);
  --line-strong: rgba(28, 28, 30, 0.15);
  --ink: #1c1c1e;
  --ink-soft: #3a3a3c;
  --muted: #71717a;
  /* Brand colour. To recolour the site, change these three together:
     the accent, a darker shade for text, and a very light tint. */
  --accent: #3b5a75;
  --accent-strong: #25394b;
  --accent-soft: #edf2f6;
  --on-accent: #ffffff;           /* text and icons on accent backgrounds */
  --accent-line: color-mix(in srgb, var(--accent) 35%, transparent);
  --accent-border: color-mix(in srgb, var(--accent) 28%, transparent);
  --accent-border-strong: color-mix(in srgb, var(--accent) 50%, transparent);
  --warning: #8a5a12;
  --warning-soft: #fff8e8;
  --error: #9f2d25;
  --error-background: #fdf2f2;
  --error-border: #f5c6cb;

  --display: 'Bitter', Georgia, serif;
  --sans: 'Montserrat', system-ui, sans-serif;
  --mono: 'JetBrains Mono', monospace;

  /* Page-opening animation. Raise --reveal-pace to slow the whole
     sequence (1 = original timing), --reveal-duration for each element. */
  --reveal-pace: 1.5;
  --reveal-duration: 0.7s;

  --radius: 5px;
  --radius-small: 4px;
  --shadow-hover: 0 7px 18px rgba(28, 28, 30, 0.06);
  --transition: 0.16s ease;

  /* Body padding of every page; the card width is set on .card. */
  --body-padding: 3rem 2.5rem;
  --body-padding-mobile: 2rem 1.5rem;
}

/* 2. Base elements ======================================== */

*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  width: 100%;
  overflow-x: hidden;
  background: var(--paper);
  scroll-behavior: smooth;
  scrollbar-gutter: stable;
}

body {
  min-width: 0;
  min-height: 100vh;
  overflow-x: hidden;
  color: var(--ink);
  background: linear-gradient(180deg, var(--paper-soft) 0%, var(--paper) 100%);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
}

img {
  max-width: 100%;
  display: block;
}

a:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  top: 0;
  left: -9999px;
  z-index: 200;
  padding: 0.65rem 0.9rem;
  color: var(--on-accent);
  background: var(--ink);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 500;
  text-decoration: none;
}

.skip-link:focus {
  top: 1rem;
  left: 1rem;
}

/* Read by screen readers only (e.g. table captions). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* 3. Page canvas, card, navigation ======================== */

.page {
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(0.7rem, 4vh, 2.5rem) 1rem 1rem;
}

.card {
  position: relative;
  width: min(100%, 1100px);
  min-width: 0;
  overflow: hidden;
  background: var(--sheet);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(28, 28, 30, 0.03),
              0 20px 48px rgba(28, 28, 30, 0.08);
}

.card::before {
  content: '';
  display: block;
  height: 4px;
  background: var(--accent);
}

.index-nav {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-bottom: 1px solid var(--line-strong);
}

.index-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.1rem 1.4rem;
  color: var(--ink);
  border-left: 1px solid var(--line);
  text-decoration: none;
  transition: color var(--transition), background-color var(--transition);
}

.index-card:first-child {
  border-left: none;
}

.index-nav .idx-label {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
}

.index-nav .idx-label i {
  width: 1.1rem;
  color: var(--accent);
  font-size: 0.85rem;
  text-align: center;
}

.index-card.is-current {
  color: var(--accent-strong);
  background: var(--accent-soft);
}

.index-card.is-current .idx-label i {
  color: var(--accent-strong);
}

.index-card:hover {
  color: var(--on-accent);
  background: var(--accent);
}

.index-card:hover .idx-label,
.index-card:hover .idx-label i {
  color: var(--on-accent);
}

/* 4. Page structure ======================================= */

/* Every page wraps its content in <section class="page-body ...">. */
.page-body {
  padding: var(--body-padding);
}

.page-title {
  margin-bottom: 2rem;
  color: var(--ink);
  font-family: var(--display);
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.15;
}

/* Title with an action on the right (e.g. Download PDF). */
.page-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
}

.page-heading .page-title {
  margin-bottom: 0;
}

/* Back button and an action on one row (guidance notes). */
.page-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
}

.page-toolbar .back-link {
  margin-bottom: 0;
}

/* Introductory paragraph under the page title. */
.lead {
  width: 100%;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.75;
  text-align: justify;
}

/* A block directly after the lead paragraph (cards, notes, callouts). */
.lead + :not(.content-section) {
  margin-top: 1.5rem;
}

.content-section {
  margin-top: 3.5rem;
}

.section-title {
  padding-bottom: 0.4rem;
  margin-bottom: 1.5rem;
  color: var(--accent-strong);
  border-bottom: 1px solid var(--line-strong);
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Short explanatory sentence directly under a section title. */
.section-introduction {
  margin-bottom: 1.5rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.7;
  text-align: justify;
}

/* Grouping inside a section: dashed divider above, except the first. */
.subsection-title {
  padding-top: 1.25rem;
  margin-top: 2rem;
  margin-bottom: 0.8rem;
  color: var(--accent-strong);
  border-top: 1px dashed var(--line-strong);
  font-family: var(--display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.subsection-title.is-first {
  padding-top: 0;
  margin-top: 0;
  border-top: none;
}

/* Smaller display heading for a group of items (e.g. project groups). */
.group-title {
  margin-bottom: 0.55rem;
  color: var(--accent-strong);
  font-family: var(--display);
  font-size: 1.16rem;
  font-weight: 700;
}

/* 5a. Links and buttons =================================== */

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 2rem;
  padding: 0.7rem 0.95rem;
  color: var(--accent-strong);
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: var(--radius-small);
  font-size: 0.86rem;
  font-weight: 600;
  text-decoration: none;
  transition: color var(--transition), background-color var(--transition),
              border-color var(--transition), transform var(--transition);
}

.back-link:hover {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-1px);
}

/* CV-style text link, e.g. "Download PDF". */
.download-link {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  color: var(--accent);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  transition: color var(--transition);
}

.download-link:hover {
  color: var(--accent-strong);
}

.download-link i {
  margin-right: 0.3rem;
}

/* Underlined link inside running text. */
.text-link,
.prose a:not([class]) {
  color: var(--accent);
  font-weight: 600;
  text-decoration-line: underline;
  text-decoration-color: var(--accent-line);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
  transition: color var(--transition), text-decoration-color var(--transition);
}

.text-link:hover,
.prose a:not([class]):hover {
  color: var(--accent-strong);
  text-decoration-color: var(--accent-strong);
}

/* Small rectangular button, e.g. "Read the paper". */
.button-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 0.75rem;
  color: var(--accent-strong);
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: var(--radius-small);
  font-size: 0.8rem;
  font-weight: 600;
  text-decoration: none;
  transition: color var(--transition), background-color var(--transition),
              border-color var(--transition);
}

.button-link:hover {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

/* 5b. Text blocks, panels and callouts ==================== */

/* Running text: paragraphs and lists with consistent rhythm. */
.prose {
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.7;
  text-align: justify;
}

.prose > * + * {
  margin-top: 1rem;
}

.prose ul,
.prose ol {
  display: grid;
  gap: 0.45rem;
  padding-left: 1.4rem;
  text-align: left;
}

.prose li::marker {
  color: var(--accent);
}

.prose strong {
  color: var(--accent-strong);
  font-weight: 600;
}

/* Soft boxed area. */
.panel {
  padding: 1.35rem 1.5rem;
  background: var(--paper-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}

/* Highlighted note with a coloured left border. */
.callout {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 1.15rem 1.25rem;
  color: var(--accent-strong);
  background: var(--accent-soft);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-small);
  font-size: 0.94rem;
  font-weight: 600;
  line-height: 1.6;
}

.callout > i {
  flex: 0 0 auto;
}

.callout.is-quiet {
  color: var(--muted);
  background: var(--paper-soft);
  border-left-width: 3px;
  font-size: 0.86rem;
  font-weight: 400;
}

.callout.is-warning {
  color: var(--warning);
  background: var(--warning-soft);
  border-left-color: var(--warning);
  font-size: 0.91rem;
  font-weight: 400;
}

.callout.is-warning strong {
  font-weight: 700;
}

/* Small uppercase label in monospace, e.g. "Empirical analysis". */
.meta-label {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-align: left;
}

/* 5c. Action cards and tile grids ========================= */

/* A prominent link: round icon, title + description, chevron. */
.action-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1.25rem;
  padding: 1.35rem 1.5rem;
  color: var(--ink);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}

.action-card:hover {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 8px 20px rgba(28, 28, 30, 0.07);
  transform: translateY(-1px);
}

.action-icon {
  width: 2.75rem;
  height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 50%;
  font-size: 0.95rem;
}

.action-content {
  min-width: 0;
}

.action-title {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--accent-strong);
  font-family: var(--display);
  font-size: 1.08rem;
  font-weight: 700;
  line-height: 1.4;
}

.action-description {
  display: block;
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1.6;
}

.action-arrow {
  color: var(--accent);
  font-size: 0.78rem;
}

/* Two-column grid of cards; one column on narrow screens. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  list-style: none;
}

/* A card in a tile grid (link or static). */
.tile {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 1rem;
  min-width: 0;
  padding: 1.35rem;
  color: var(--ink);
  background: var(--paper-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  text-decoration: none;
  transition: background-color var(--transition), border-color var(--transition),
              box-shadow var(--transition), transform var(--transition);
}

a.tile:hover {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: var(--shadow-hover);
  transform: translateY(-1px);
}

.tile-wide {
  grid-column: 1 / -1;
}

.tile-content {
  min-width: 0;
}

.tile-title {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--accent-strong);
  font-family: var(--display);
  font-size: 1.08rem;
  font-weight: 700;
  line-height: 1.4;
}

.tile-description {
  display: block;
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* 5d. Accordion ribbons (native <details>) ================ */

.ribbon {
  margin-bottom: 0.85rem;
  overflow: hidden;
  background: var(--sheet);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.ribbon:last-child {
  margin-bottom: 0;
}

.ribbon[open] {
  border-color: var(--accent-border-strong);
  box-shadow: var(--shadow-hover);
}

.ribbon summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 1rem;
  padding: 1.05rem 1.2rem;
  color: var(--accent-strong);
  background: var(--sheet);
  cursor: pointer;
  list-style: none;
  transition: color var(--transition), background-color var(--transition);
}

.ribbon summary::-webkit-details-marker {
  display: none;
}

.ribbon summary:hover,
.ribbon[open] summary {
  background: var(--accent-soft);
}

.ribbon[open] summary {
  border-bottom: 1px solid var(--line);
}

.ribbon-title {
  grid-column: 1;
  min-width: 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.45;
}

.ribbon-date {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 500;
  white-space: nowrap;
}

.ribbon-chevron {
  grid-column: -2;
  color: var(--accent);
  font-size: 0.72rem;
  transition: transform 0.2s ease;
}

.ribbon[open] .ribbon-chevron {
  transform: rotate(180deg);
}

.ribbon-content {
  padding: 1.25rem;
  color: var(--ink-soft);
  font-size: 0.94rem;
  line-height: 1.65;
}

.ribbon-content > * + * {
  margin-top: 0.8rem;
}

.ribbon-content h3 {
  margin-top: 1.25rem;
  margin-bottom: 0.55rem;
  color: var(--accent-strong);
  font-family: var(--display);
  font-size: 0.96rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.ribbon-content h3:first-child {
  margin-top: 0;
}

.ribbon-content ul {
  padding-left: 1.25rem;
}

.ribbon-content li + li {
  margin-top: 0.3rem;
}

/* 5e. Loading, empty, error and update notes ============== */

.loading-message,
.empty-message {
  padding: 1rem 1.1rem;
  color: var(--muted);
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  font-size: 0.94rem;
  font-style: italic;
}

.render-error {
  padding: 1.2rem;
  color: var(--error);
  background: var(--error-background);
  border: 1px solid var(--error-border);
  border-radius: var(--radius-small);
  font-size: 0.95rem;
  line-height: 1.5;
}

.render-error strong,
.render-error-title {
  display: block;
  margin-bottom: 0.4rem;
  font-weight: 700;
}

.render-error-message {
  padding: 0.4rem;
  color: var(--ink-soft);
  background: rgba(0, 0, 0, 0.04);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.85rem;
}

/* "Information updated on DD/MM/YYYY", centred at the end of a page. */
.update-note {
  margin-top: 3rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  text-align: center;
}

/* Small centred note at the end of a page (copyright, status). */
.page-note {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
  font-size: 0.78rem;
  line-height: 1.65;
  text-align: center;
}

.page-note strong {
  color: var(--ink-soft);
  font-weight: 600;
}

/* 6. Footer =============================================== */

.foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.5rem;
  background: var(--panel-deep);
  border-top: 1px solid var(--line);
}

.socials {
  display: flex;
  align-items: center;
  justify-self: start;
  gap: 0.4rem;
}

.socials a,
.back-to-top {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  background: var(--sheet);
  border: 1px solid var(--line-strong);
  font-size: 0.85rem;
  text-decoration: none;
  transition: color var(--transition), background-color var(--transition),
              border-color var(--transition), transform var(--transition),
              box-shadow var(--transition);
}

.socials a {
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-small);
}

.back-to-top {
  width: 2.55rem;
  height: 2.55rem;
  justify-self: center;
  border-radius: 50%;
  box-shadow: 0 4px 12px rgba(28, 28, 30, 0.05);
}

.socials a:hover,
.back-to-top:hover {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.back-to-top:hover {
  box-shadow: 0 6px 16px rgba(28, 28, 30, 0.1);
  transform: translateY(-2px);
}

.foot-loc {
  justify-self: end;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* 7. Reveal animation ===================================== */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.reveal {
  animation: rise var(--reveal-duration) cubic-bezier(0.2, 0.6, 0.2, 1) both;
  animation-delay: calc(var(--reveal-delay, 0ms) * var(--reveal-pace));
}

/* Pages that load data (CV, Research, A&F hours) set body_class: is-loading.
   Their animation waits until the data is in (site.js removes the class),
   so sections appear in reading order instead of static ones first. */
.is-loading .reveal {
  animation-play-state: paused;
}

.delay-40  { --reveal-delay: 40ms; }
.delay-80  { --reveal-delay: 80ms; }
.delay-120 { --reveal-delay: 120ms; }
.delay-140 { --reveal-delay: 140ms; }
.delay-160 { --reveal-delay: 160ms; }
.delay-180 { --reveal-delay: 180ms; }
.delay-220 { --reveal-delay: 220ms; }
.delay-260 { --reveal-delay: 260ms; }
.delay-280 { --reveal-delay: 280ms; }
.delay-300 { --reveal-delay: 300ms; }
.delay-340 { --reveal-delay: 340ms; }

/* 8. Responsive rules and reduced motion ================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal {
    animation: none;
  }

  .index-card,
  .back-link,
  .download-link,
  .text-link,
  .prose a,
  .button-link,
  .action-card,
  .tile,
  .ribbon,
  .ribbon summary,
  .ribbon-chevron,
  .socials a,
  .back-to-top {
    transition: none;
  }
}

@media (max-width: 768px) {
  .index-nav {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .page-body {
    padding: var(--body-padding-mobile);
  }

  .tile-grid {
    grid-template-columns: 1fr;
  }

  .tile-wide {
    grid-column: auto;
  }
}

@media (max-width: 680px) {
  .index-nav {
    grid-template-columns: 1fr;
  }

  .index-card {
    border-top: 1px solid var(--line);
    border-left: none;
  }

  .index-card:first-child {
    border-top: none;
  }

  .page-title {
    font-size: 2.15rem;
  }

  .page-heading {
    flex-direction: column;
    align-items: flex-start;
  }

  .page-toolbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .action-card,
  .tile {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .action-arrow,
  .tile .action-arrow {
    display: none;
  }

  .ribbon summary {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.45rem 0.8rem;
    padding: 1rem;
  }

  .ribbon summary:has(.ribbon-date) .ribbon-title {
    grid-column: 1 / -1;
  }

  .ribbon-date {
    grid-column: 1;
  }

  .ribbon summary:has(.ribbon-date) .ribbon-chevron {
    grid-column: 2;
    grid-row: 2;
  }

  .ribbon-content {
    padding: 1rem;
  }

  .foot {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }

  .back-to-top {
    grid-row: 1;
  }

  .socials {
    grid-row: 2;
    justify-self: center;
  }

  .foot-loc {
    grid-row: 3;
    justify-self: center;
  }
}
