/* Academic Website Styles - Inspired by verso.lean-lang.org */

:root {
  --primary-color: #2c3e50;
  --accent-color: #3498db;
  --text-color: #333;
  --bg-color: #ffffff;
  --light-bg: #f8f9fa;
  --border-color: #dee2e6;
  /* Text blues, darkened to meet WCAG AA (4.5:1) on the white background.
     The old #3498db / #2980b9 measured 3.15:1 and 4.30:1 — both failing, so
     no link state reached the standard. --accent-color keeps the original
     lighter blue for decorative use (borders, top-bars, gradients), where
     contrast minimums do not apply. */
  --link-color: #2874a6;        /* 5.07:1 on white */
  --link-hover: #1b5e8a;        /* 6.97:1 on white */
  /* For text on the dark --primary-color nav, where darkening would hurt:
     the light blue below gives 5.78:1 against #2c3e50. */
  --accent-on-dark: #7fc4f0;

  /* Text color variations */
  --text-muted: #666;           /* Muted gray for secondary text */
  --text-light: #555;           /* Light gray for tertiary text */

  /* Academic level colors */
  --level-bsc-color: #27ae60;   /* Green for BSc level */
  --level-msc-color: #8e44ad;   /* Purple for MSc level */
  --level-phd-color: #e74c3c;   /* Red for PhD level */
  --level-other-color: #7f8c8d; /* Neutral grey for unclassified notes */

  /* RGB values for use in rgba() functions */
  --level-bsc-rgb: 39, 174, 96;
  --level-msc-rgb: 142, 68, 173;
  --level-phd-rgb: 231, 76, 60;
  --level-other-rgb: 127, 140, 141;
  --accent-rgb: 52, 152, 219;

  /* Accent color with alpha - for backgrounds */
  --accent-alpha-10: rgba(var(--accent-rgb), 0.1);  /* 10% opacity accent */
}

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

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  line-height: 1.6;
  color: var(--text-color);
  background-color: var(--bg-color);
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

/* Navigation */
.main-nav {
  background-color: var(--primary-color);
  padding: 1rem;
  border-radius: 8px;
  margin-bottom: 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.nav-links {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.nav-icons {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.main-nav a {
  color: white;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.3s;
}

.main-nav a:hover {
  color: var(--accent-on-dark);
}

.icon-link {
  font-size: 0.85rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 4px;
  transition: all 0.3s;
}

.icon-link:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.6);
  transform: translateY(-1px);
}

/* Main Content */
.content {
  min-height: 70vh;
}

/* Typography */
h1 {
  color: var(--primary-color);
  font-size: 2.5rem;
  margin: 1.5rem 0 1rem;
  border-bottom: 3px solid var(--accent-color);
  padding-bottom: 0.5rem;
}

h2 {
  color: var(--primary-color);
  font-size: 2rem;
  margin: 1.5rem 0 0.75rem;
  border-bottom: 2px solid var(--border-color);
  padding-bottom: 0.3rem;
}

h3 {
  color: var(--primary-color);
  font-size: 1.5rem;
  margin: 1.25rem 0 0.5rem;
}

p {
  margin: 0.75rem 0;
}

/* Links */
/* Body links are underlined so that colour is not the sole indicator that
   text is a link (WCAG 1.4.1). Navigation, CTA buttons, publication link
   chips, card titles and the event button each opt out below, since their
   shape or placement already marks them as controls. */
a {
  color: var(--link-color);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  transition: color 0.2s;
}

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

/* Images */
img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  margin: 1rem 0;
  display: block;        /* Prevents inline spacing issues */
}

/* Embedded media (YouTube etc.).
   The video directive deliberately emits no width/height, so sizing lives
   here. Without this, a fixed-width embed overflows narrow viewports and
   makes the whole page scroll horizontally. */
iframe {
  display: block;
  width: 100%;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: 8px;
  margin: 1.5rem 0;
}

/* Home page intro: contact details with the portrait floated alongside.

   `display: flow-root` establishes a block formatting context, which CONTAINS
   the float. Without it the float escapes the intro: a float only shortens the
   line boxes of following content, it does not push block boxes down, so the
   portrait would overlap whatever block comes next (it overlapped the
   .get-started card by 54px). Containment makes that structural rather than
   dependent on the contact text happening to be taller than the photo.

   Styling hangs off the .intro class, not the image's alt text. The previous
   `img[alt="Profile Photo"]` selector meant improving the alt text silently
   broke the layout, which discouraged the accessibility fix. */
.intro {
  display: flow-root;
}

.intro img {
  /* min(...) is needed because `.intro img` (0,1,1) outranks the global
     `img { max-width: 100% }` (0,0,1); a bare 500px would let the portrait
     exceed its container on viewports narrower than ~540px. */
  max-width: min(500px, 100%);
  float: right;
  margin-left: 2rem;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

/* Lists */
ul, ol {
  margin: 0.75rem 0;
  padding-left: 2rem;
}

li {
  margin: 0.5rem 0;
}

/* Publications */
.publication-category {
  margin: 2rem 0;
}

.publication-list {
  margin: 1rem 0;
}

.publication {
  background-color: var(--light-bg);
  padding: 1rem;
  margin: 0.75rem 0;
  border-left: 4px solid var(--accent-color);
  border-radius: 4px;
}

.publication strong {
  color: var(--primary-color);
  font-size: 1.1rem;
}

.publication em {
  color: var(--text-muted);
}

/* Footer */
.site-footer {
  margin-top: 3rem;
  padding: 1.5rem 0;
  border-top: 2px solid var(--border-color);
  text-align: center;
  color: var(--text-muted);
}

.site-footer a {
  color: var(--link-color);
}

/* Code blocks (if any) */
code {
  background-color: var(--light-bg);
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
  font-family: "Courier New", Courier, monospace;
  font-size: 0.9em;
}

pre {
  background-color: var(--light-bg);
  padding: 1rem;
  border-radius: 4px;
  overflow-x: auto;
  margin: 1rem 0;
}

/* Responsive design */
@media (max-width: 768px) {
  .main-nav {
    flex-direction: column;
    align-items: flex-start;
  }

  .nav-links, .nav-icons {
    width: 100%;
    justify-content: center;
  }

  .nav-icons {
    border-top: 1px solid rgba(255, 255, 255, 0.2);
    padding-top: 0.5rem;
  }

  body {
    padding: 10px;
  }

  .main-nav {
    flex-direction: column;
    gap: 0.75rem;
  }

  .intro img {
    float: none;
    display: block;
    margin: 1rem auto;
  }

  h1 {
    font-size: 2rem;
  }

  h2 {
    font-size: 1.5rem;
  }
}

/* Call-to-action buttons section (inspired by verso.lean-lang.org) */
.get-started {
  background: var(--primary-color);
  color: white;
  padding: 3rem 2rem;
  text-align: center;
  border-radius: 1rem;
  margin: 3rem 0;
}

.get-started > p:first-child > strong {
  font-size: 2rem;
  font-weight: 700;
  color: white;
  display: block;
  margin-bottom: 1rem;
}

/* NOTE: there was a `.get-started > p:nth-child(2)` rule here, intended for a
   hero subtitle. No page has one — on Research the second child is the first
   group member, who was therefore centred and resized differently from every
   colleague below, and which member it hit depended on sort order. Style by
   meaning (a wrapper class), never by paragraph position; see the .note-* and
   .pub-* wrappers further down. */

.cta-buttons {
  display: flex;
  gap: 1rem;
  justify-content: center;
  margin-top: 2rem;
  flex-wrap: wrap;
}

.cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 2rem;
  border-radius: 0.5rem;
  font-size: 16px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.3s;
  border: none;
}

.cta-btn p {
  margin: 0;
  padding: 0;
}

.cta-btn.primary {
  background: white;
  color: var(--primary-color);
}

.cta-btn.primary:hover {
  background: rgba(255, 255, 255, 0.9);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.cta-btn.secondary {
  border: 2px solid white;
  background: transparent;
  color: white;
}

.cta-btn.secondary:hover {
  background: rgba(255, 255, 255, 0.15);
  transform: translateY(-2px);
}

/* Three-column pillars layout (inspired by verso.lean-lang.org) */
.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  padding: 3rem 0;
  margin: 2rem 0;
}

.pillar {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 1.5rem;
  background: var(--light-bg);
  border-radius: 8px;
  border: 1px solid var(--border-color);
}

.pillar > :last-child {
  margin-top: auto;
}

.pillar > p:first-child {
  margin-bottom: 0.75rem;
}

.pillar > p:first-child > strong {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--link-color);
  display: block;
  margin-bottom: 0.5rem;
}

/* (A `.pillar > p:nth-child(2)` description rule was removed: pillars contain
   a title and an image, so it targeted the image paragraph, not prose.) */

/* Responsive: Stack on mobile */
@media (max-width: 768px) {
  .pillars {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }

  .cta-buttons {
    flex-direction: column;
    align-items: center;
  }

  .cta-btn {
    width: 100%;
    max-width: 300px;
  }

  .get-started {
    padding: 2rem 1.5rem;
  }

  .get-started > p:first-child > strong {
    font-size: 1.5rem;
  }
}

/* Build cards layout (inspired by verso.lean-lang.org "What Can You Build?") */
.builds {
  margin: 3rem 0;
  padding: 2rem;
  background: var(--light-bg);
  border-radius: 1rem;
  border: 1px solid var(--border-color);
}

.builds > p:first-child > strong {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--primary-color);
  display: block;
  margin-bottom: 1rem;
}

/* (A `.builds > p:nth-child(2)` description rule was removed: the second child
   is the .build-cards div, so it never matched.) */

.build-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}

.build-card {
  padding: 1.25rem;
  background: white;
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  transition: all 0.3s;
  border-top: 3px solid var(--border-color);
}

/* BSc level courses - green top border */
.build-card.bsc {
  border-top-color: var(--level-bsc-color);
  background: linear-gradient(to bottom, rgba(var(--level-bsc-rgb), 0.05) 0%, white 30%);
}

/* MSc level courses - purple top border */
.build-card.msc {
  border-top-color: var(--level-msc-color);
  background: linear-gradient(to bottom, rgba(var(--level-msc-rgb), 0.05) 0%, white 30%);
}

.build-card:hover {
  border-color: var(--accent-color);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

/* Maintain colored top border on hover */
.build-card.bsc:hover {
  border-top-color: var(--level-bsc-color);
}

.build-card.msc:hover {
  border-top-color: var(--level-msc-color);
}

/* PhD level - red top border.
   These colours are used only as a border and as a 5%-opacity gradient wash:
   #e74c3c is 3.82:1 on white, fine for a border but below the 4.5:1 text
   threshold, so it must not be reused for card text. */
.build-card.phd {
  border-top-color: var(--level-phd-color);
  background: linear-gradient(to bottom, rgba(var(--level-phd-rgb), 0.05) 0%, white 30%);
}

.build-card.phd:hover {
  border-top-color: var(--level-phd-color);
}

/* Unclassified notes (NotesLevel.other) - neutral grey, stated explicitly so
   the fallback is a decision rather than an unstyled gap. */
.build-card.other {
  border-top-color: var(--level-other-color);
  background: linear-gradient(to bottom, rgba(var(--level-other-rgb), 0.05) 0%, white 30%);
}

.build-card.other:hover {
  border-top-color: var(--level-other-color);
}

/* Lecture-note cards: semantic .note-* wrappers emitted by the lectureNotes
   directive, so styling no longer depends on paragraph position (the icon and
   description are both optional). */
.build-card > .note-title > p,
.build-card > .note-icon > p,
.build-card > .note-desc > p {
  text-align: center;
}

/* Title (applies through the wrapping link, unlike the old direct-child rule) */
.build-card > .note-title strong {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--link-color);
  display: block;
  margin-bottom: 0.5rem;
}

.build-card > .note-icon > p {
  margin: 0;
}

/* Description, styled consistently on every card (with or without an icon) */
.build-card > .note-desc > p {
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.6;
  margin: 0;
}

/* Lecture note card icons: uniform, responsive slot (variant A).
   Every icon fills the same 160px square box, scaled to fit (contain) regardless
   of the source image's pixel dimensions, so widths are consistent at any window
   width. `aspect-ratio` replaces the previously-inert `max-height: 90%`. */
.build-card img {
  display: block;
  margin: 1rem auto 0;
  width: 100%;
  max-width: 160px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border-radius: 4px;
}

/* Responsive: Ensure at least 2 columns on tablet, 1 on mobile */
@media (max-width: 768px) {
  .build-cards {
    grid-template-columns: 1fr;
  }

  .builds {
    padding: 1.5rem;
  }
}

@media (min-width: 769px) and (max-width: 1024px) {
  .build-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Print styles */
@media print {
  .main-nav, .site-footer {
    display: none;
  }

  body {
    max-width: 100%;
  }
}

/* Clickable lecture notes cards */

/* Publication Cards */
.publication-card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  transition: box-shadow 0.2s, border-color 0.2s;
}

.publication-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border-color: var(--accent-color);
}

/* Title row: title + DOI/arXiv/PDF links.
   The publicationList directive emits semantic `.pub-title-row` / `.pub-authors`
   / `.pub-venue` wrappers, so styling no longer depends on paragraph position. */
.publication-card > .pub-title-row > p {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 0.75rem;
  flex-wrap: wrap;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--primary-color);
}

.publication-card > .pub-title-row > p strong {
  flex: 1;
  min-width: 0;
  overflow-wrap: break-word;  /* Wrap long titles */
  word-break: break-word;     /* Break long titles */
}

.publication-card > .pub-title-row > p a {
  color: var(--link-color);
  text-decoration: none;
  padding: 0.25rem 0.75rem;
  border-radius: 4px;
  background: var(--accent-alpha-10);
  transition: background 0.2s, color 0.2s;
  font-weight: 500;
  font-size: 0.9rem;
  white-space: nowrap;
}

/* White on the lighter accent measures only 3.15:1, so the filled hover
   state uses the darker text blue (5.07:1). */
.publication-card > .pub-title-row > p a:hover {
  background: var(--link-color);
  color: white;
}

/* Authors line */
.publication-card > .pub-authors > p {
  margin-bottom: 0.5rem;
  color: var(--text-light);
  font-size: 0.95rem;
}

/* Venue and date line */
.publication-card > .pub-venue > p {
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* Responsive adjustments for publications */
@media (max-width: 768px) {
  .publication-card > .pub-title-row > p {
    flex-direction: column;
    align-items: flex-start;
  }

  .publication-card {
    padding: 1rem;
  }
}
/* Clickable lecture-note cards.

   The whole card is a click target via the "stretched link" pattern: the
   title link grows an absolutely-positioned ::after overlay that covers the
   card. This replaces a JS click handler that hijacked Ctrl/Cmd/Shift+click
   (it tested e.target.tagName === 'A', which misses clicks landing on the
   <strong> nested inside the link) and was unreachable by keyboard.

   Because the real <a> is what is clicked, modifier-clicks, middle-click,
   keyboard focus, the context menu and the status-bar URL preview all behave
   natively. */
.clickable-card {
  position: relative;
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
}

.clickable-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.clickable-card .note-title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Keyboard focus lands on the title link, but the visible ring belongs on the
   card, since that is what reads as the control. */
.clickable-card:focus-within {
  outline: 3px solid var(--link-color);
  outline-offset: 2px;
}

.clickable-card .note-title a:focus-visible {
  outline: none;
}

.clickable-card a {
  text-decoration: none;
  color: inherit;
  display: block;
}

.clickable-card a:hover {
  text-decoration: none;
}

/* Course metadata, emitted as a real <dl> by the currentCourses directive.
   Laid out as a two-column grid so the labels align, collapsing to stacked
   rows on narrow screens. `overflow-wrap` on the value keeps a long course
   URL from pushing the page sideways. */
.course-meta dl {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.35rem 1rem;
  margin: 0.5rem 0 1.75rem;
}

.course-meta dt {
  font-weight: 600;
  color: var(--text-muted);
}

.course-meta dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Verso wraps each <dd> value in a <p>; drop the global paragraph margin so it
   does not break the grid's row rhythm. */
.course-meta dt > p,
.course-meta dd > p {
  margin: 0;
}

@media (max-width: 560px) {
  .course-meta dl {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.1rem;
  }

  .course-meta dd {
    margin-bottom: 0.75rem;
  }
}

/* Past course list: a <dl> whose term is the course title and whose
   description is the institution, year/semester and any notes. Stacked rather
   than two-column, because course titles are long and would force a very wide
   label column. */
.past-courses dl {
  margin: 0.5rem 0 1.5rem;
}

.past-courses dt {
  font-weight: 600;
  margin-top: 0.9rem;
  overflow-wrap: anywhere;
}

.past-courses dd {
  margin: 0.1rem 0 0 1.25rem;
  color: var(--text-muted);
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}

.past-courses dd > p {
  margin: 0;
}

/* Small globe icon linking to a group member's own website.
   Deliberately understated so that members with and without a recorded site
   read as the same kind of entry — the icon sits after the name rather than
   turning the name itself into a link. */
.member-site {
  display: inline-flex;
  align-items: center;
  margin-left: 0.3em;
  color: var(--link-color);
  text-decoration: none;   /* icon, not prose: opts out of the global underline */
  vertical-align: -0.15em;
}

.member-site:hover {
  color: var(--link-hover);
}

.member-site-icon {
  width: 0.95em;
  height: 0.95em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pillar images */
.pillar img {
  display: block;
  margin: 1.5rem auto 0;
  max-width: 90%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.pillar img:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transition: box-shadow 0.2s;
}

/* Event Cards */
.event-card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 2rem;
  margin-bottom: 2.5rem;
  transition: box-shadow 0.3s, border-color 0.3s;
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}

.event-card:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1);
  border-color: var(--accent-color);
}

/* Left column - poster image */
.event-left {
  flex-shrink: 0;
  width: 280px;
}

.event-left img {
  width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transition: box-shadow 0.3s, transform 0.3s;
  display: block;
}

.event-left img:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  transform: translateY(-2px);
}

/* Right column - event details */
.event-right {
  flex: 1;
  min-width: 0;
  overflow-wrap: break-word;  /* Wrap long words at arbitrary points */
  word-break: break-word;     /* Break long words to prevent overflow */
}

.event-right p {
  margin: 0 0 1rem 0;
  line-height: 1.7;
  color: var(--text-color);
}

/* Event title (semantic .event-title wrapper emitted by the eventList directive) */
.event-right > .event-title > p {
  margin-bottom: 0.5rem;
}

.event-right > .event-title strong {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--primary-color);
  line-height: 1.3;
}

/* Date line (only emitted when the event has a date) */
.event-right > .event-date > p {
  color: var(--text-muted);
  font-size: 0.95rem;
  font-style: italic;
  margin-bottom: 1rem;
}

/* Event website link */
.event-right a {
  display: inline-block;
  color: white;
  /* Darker blue: white on the lighter accent is only 3.15:1. */
  background: var(--link-color);
  text-decoration: none;
  padding: 0.6rem 1.5rem;
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.2s;
}

.event-right a:hover {
  background: var(--link-hover);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.3);
  text-decoration: none;
}

/* Responsive: Stack on mobile */
@media (max-width: 768px) {
  .event-card {
    grid-template-columns: 1fr;
    gap: 1.5rem;
    padding: 1.5rem;
  }

  .event-left {
    width: 100%;         /* Force full width */
    max-width: 400px;    /* But cap it */
    margin: 0 auto;      /* Center it */
  }

  .event-left img {
    width: 100%;         /* Image fills container */
  }

  .event-right > .event-title strong {
    font-size: 1.5rem;
  }
}

/* Link Cards */
.link-card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 1.5rem;
  margin-bottom: 1.5rem;
  transition: box-shadow 0.3s, border-color 0.3s;
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: center;
}

.link-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border-color: var(--accent-color);
}

/* Left column - small thumbnail */
.link-left {
  flex-shrink: 0;
  width: 80px;
}

.link-left img {
  width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
  transition: transform 0.2s;
}

.link-left a:hover img {
  transform: scale(1.05);
}

/* Right column - link details */
.link-right {
  flex: 1;
  min-width: 0;
  overflow-wrap: break-word;  /* Wrap long words */
  word-break: break-word;     /* Break long words */
}

.link-right p {
  margin: 0 0 0.5rem 0;
  line-height: 1.6;
  color: var(--text-color);
}

/* Link name (first paragraph with strong) */
.link-right > p:first-child {
  margin-bottom: 0.5rem;
}

.link-right > p:first-child strong {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--primary-color);
}

.link-right > p:first-child a {
  text-decoration: none;
  color: var(--primary-color);
  transition: color 0.2s;
}

.link-right > p:first-child a:hover {
  color: var(--link-hover);
  text-decoration: none;
}

/* Description paragraph */
.link-right > p:nth-child(2) {
  margin: 0;
  color: var(--text-light);
  font-size: 0.95rem;
}

/* Force URL wrapping in all card content */
.event-right a,
.link-right a,
.publication-card a {
  overflow-wrap: break-word;
  word-break: break-all;      /* More aggressive: break URLs anywhere */
  hyphens: none;              /* Don't add hyphens to URLs */
}

/* Responsive: Adjust layout on mobile */
@media (max-width: 768px) {
  .link-card {
    grid-template-columns: 60px 1fr;
    gap: 1rem;
    padding: 1rem;
  }

  .link-left {
    width: 60px;
  }

  .link-right > p:first-child strong {
    font-size: 1.1rem;
  }
}
