/* Replication Research (R2) mirror — clean modern academic theme */

/* Self-hosted so headings/body render identically for every visitor,
   instead of falling back to whatever serif/sans a visitor's OS happens to
   ship (previously Sitka Text on Windows, Georgia on macOS, Liberation
   Serif on Linux - three different typefaces for the same heading). Both
   are variable-weight files (Adobe, SIL OFL) covering the full 200-900
   range from one download each. */
@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/SourceSans3-variable.woff2") format("woff2");
}
@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("fonts/SourceSerif4-variable.woff2") format("woff2");
}

:root {
  --accent: #009dd0;      /* sampled from the R2 logo's blue ink */
  --accent-dark: #00769c; /* hover/active state: same hue, darker */
  --accent-soft: #e6f5fa; /* same hue, light tint for backgrounds */
  --accent-deep: #006080;      /* same hue, ~7:1 on white - default text/link color */
  --accent-deep-dark: #004a63; /* hover/active state for accent-deep */
  --highlight-soft: #e6edf5;   /* a cooler, grayer blue for the Under Review card,
                                   kept visually distinct from --accent-soft */
  --ink: #1c2733;
  --ink-soft: #4a5866;
  --muted: #75828f;
  --rule: #e3e8ed;
  --bg: #ffffff;
  --bg-alt: #f6f8fa;
  --serif: "Source Serif 4", "Charter", Cambria, Georgia, serif;
  --sans: "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --shadow: 0 1px 2px rgba(28, 39, 51, .06), 0 4px 16px rgba(28, 39, 51, .07);
  --radius: 10px;
}

* { box-sizing: border-box; }
/* Safety net against page-level horizontal scroll from any descendant
   with real (even if invisible/off-screen) geometry - e.g. .cite-tooltip
   is absolutely positioned relative to wherever its citation happens to
   fall in flowing text, so on narrow viewports it can extend past the
   viewport edge even while hidden via opacity/visibility (which, unlike
   display:none, still counts toward scrollable overflow). Applied to the
   root html/body rather than a nested element so position:sticky
   descendants (the header) keep behaving relative to the real viewport. */
html { scroll-behavior: smooth; }
body {
  margin: 0;
  overflow-x: clip;
  font-family: var(--sans);
  font-size: 16.5px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
a { color: var(--accent-deep); text-decoration: none; }
a:hover { color: var(--accent); text-decoration: underline; }
h1, h2, h3, h4 { font-family: var(--serif); line-height: 1.25; color: var(--ink); }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.meta { color: var(--muted); font-size: .88rem; margin: .2rem 0; }
.skip-link {
  position: absolute; left: -9999px; top: 0; background: var(--accent);
  color: #fff; padding: .5rem 1rem; z-index: 100;
}
.skip-link:focus { left: 0; }

/* Buttons & pills */
.btn {
  display: inline-block; padding: .55rem 1.15rem; border-radius: 999px;
  font-weight: 600; font-size: .92rem; border: 1.5px solid transparent;
  cursor: pointer; text-decoration: none !important; transition: all .15s ease;
}
.btn-primary { background: var(--accent); color: #fff !important; }
.btn-primary:hover { background: var(--accent-dark); }
.btn-ghost { border-color: var(--accent); color: var(--accent) !important; background: transparent; }
.btn-ghost:hover { background: var(--accent-soft); }
.btn-lg { padding: .75rem 1.6rem; font-size: 1rem; }
.btn-block { display: block; text-align: center; margin-bottom: .6rem; }

.pill {
  display: inline-block; padding: .12rem .65rem; border-radius: 999px;
  font-size: .8rem; font-weight: 600; margin: 0 .3rem .3rem 0;
}
.pill-pdf { background: var(--accent); color: #fff; }
.pill-pdf:hover { background: var(--accent-dark); color: #fff; text-decoration: none; }
.pill-download { background: transparent; color: var(--accent-dark); border: 1.5px solid var(--accent); }
.pill-download:hover { background: var(--accent-soft); text-decoration: none; }
.pill-stat { background: var(--bg-alt); color: var(--ink-soft); border: 1px solid var(--rule); }

/* Compact Read|Download split pill on article cards, mirroring the hero's
   split bubble at pill scale. */
.pill-split {
  display: inline-flex; border-radius: 999px; overflow: hidden;
  border: 1.5px solid var(--accent); margin: 0 .3rem .3rem 0;
}
.pill-split a {
  padding: .12rem .7rem; font-size: .8rem; font-weight: 600;
  text-decoration: none !important; transition: background .15s ease;
}
.split-read { background: var(--accent); color: #fff; }
.split-read:hover { background: var(--accent-dark); color: #fff; }
.split-dl { background: #fff; color: var(--accent-dark); }
.split-dl:hover { background: var(--accent-soft); }

/* Write review | Read reviews split pill - unlike Read|Download above,
   neither half is filled; both look like a plain .pill-download pill,
   with a divider line between them instead of a filled/white contrast. */
.pill-split-outline { background: transparent; }
.pill-split-outline a { background: transparent; color: var(--accent-dark); }
.pill-split-outline a:hover { background: var(--accent-soft); }
.pill-split-outline a:first-child { border-right: 1.5px solid var(--accent); }

/* Quiet per-article usage numbers at the bottom right of a card. */
.article-links { display: flex; align-items: center; flex-wrap: wrap; }
.article-stats {
  margin-left: auto; display: inline-flex; gap: .9rem;
  color: var(--muted); font-size: .78rem;
}
.stat-item { display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; }
.stat-item svg { flex-shrink: 0; }

/* Header (dark) */
.site-header {
  position: sticky; top: 0; z-index: 50; background: rgba(38, 45, 52, .97);
  backdrop-filter: blur(8px); border-bottom: 1px solid #1b2127;
}
/* Wider cap than the site's usual .wrap (1120px) - the header needs the
   extra room so its nav items never wrap to a second row instead of
   falling back to the hamburger menu below. */
.header-inner { max-width: 1600px; display: flex; align-items: center; gap: 1.5rem; min-height: 72px; }
.brand { flex-shrink: 0; font-family: var(--serif); font-size: 1.3rem; font-weight: 700; color: #fff; }
.brand img { max-height: 46px; width: auto; display: block; }
.site-nav { margin-left: auto; }
.site-nav > ul { list-style: none; display: flex; align-items: center; gap: .25rem; margin: 0; padding: 0; flex-wrap: wrap; }
.site-nav > ul > li { position: relative; }
.site-nav a:not(.btn) {
  display: block; padding: .45rem .7rem; color: #c9d4de;
  font-weight: 600; font-size: .93rem; border-radius: 6px;
}
.site-nav a:not(.btn):hover { color: #fff; background: rgba(255, 255, 255, .1); text-decoration: none; }
.nav-cta { margin-left: .5rem; }
/* Quiet Login link in the top-right corner: OJS's /submissions route shows
   the login form to anonymous visitors (returning here after login) and the
   user's own dashboard to anyone already signed in - authors included. */
.site-nav .nav-login a { font-size: .78rem; font-weight: 500; color: #8ba2b5; }
.site-nav .nav-login a:hover { color: #fff; }

/* "About"-style dropdowns use <details>, so they open on tap/click on every
   device - a hover-only menu is unreachable on touchscreens (tablets,
   landscape phones, anything wider than the mobile breakpoint below). */
.nav-dropdown { position: relative; }
.nav-dropdown > summary {
  display: block; padding: .45rem .7rem; color: #c9d4de;
  font-weight: 600; font-size: .93rem; border-radius: 6px;
  cursor: pointer; list-style: none; user-select: none;
}
.nav-dropdown > summary::-webkit-details-marker { display: none; }
.nav-dropdown > summary::after { content: "▾"; font-size: .7em; margin-left: .35em; opacity: .8; }
.nav-dropdown > summary:hover,
.nav-dropdown[open] > summary { color: #fff; background: rgba(255, 255, 255, .1); }
.dropdown {
  min-width: 210px; background: #2d353d;
  border: 1px solid #1b2127; border-radius: var(--radius); box-shadow: var(--shadow);
  list-style: none; margin: 0; padding: .4rem; z-index: 60;
  display: none;
}
/* Explicit show/hide instead of relying on the browser's native <details>
   content-hiding default - some engines don't apply it reliably here. */
.nav-dropdown[open] > .dropdown { display: block; }
.dropdown a:not(.btn):hover { background: rgba(255, 255, 255, .12); }
.dropdown a { white-space: nowrap; }
.nav-toggle, .nav-toggle-label { display: none; }
/* Range syntax (not min-width: 1121px) so this is the exact complement of
   the max-width: 1120px query below, with no fractional-viewport-width gap
   between them. */
@media (width > 1120px) {
  .dropdown { position: absolute; top: 100%; left: 0; }
}

/* Hero */
.hero {
  background: linear-gradient(160deg, #f2f7fb 0%, #ffffff 55%, var(--accent-soft) 130%);
  border-bottom: 1px solid var(--rule);
  padding: 4.5rem 0 4rem;
  text-align: center;
}
.hero-compact { padding: 3.4rem 0 3rem; }
.hero-kicker {
  text-transform: uppercase; letter-spacing: .14em; font-size: .78rem;
  font-weight: 700; color: var(--accent-deep); margin: 0 0 .8rem;
}
.hero h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); margin: 0 0 1rem; }

/* Layered logo: black ink image + color layer shown through the blue-parts
   mask, so the accent color can animate while staying pixel-aligned.
   The .hero h1 selector must not win over the auto margins (centering). */
.hero-logo,
.hero h1.hero-logo {
  position: relative; max-width: 620px; margin: 0 auto 1.2rem;
}
.hero-logo img { display: block; width: 100%; height: auto; }
/* Smaller variant used on the About page, above the page's own h1. */
.about-brand { text-align: center; margin-bottom: 2.2rem; }
.hero-logo-sm { max-width: 380px; }
.logo-color {
  position: absolute; inset: 0; background-color: #009fd4;
  -webkit-mask-image: url("img/logo-mask.png");
  -webkit-mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-image: url("img/logo-mask.png");
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
  animation: logo-cycle 220s linear infinite;
  /* Randomized per page load to a value below (see base.html's inline
     r2RandomizeLogoColor script) so the logo starts already settled on a
     checkpoint color instead of always opening on blue mid-cycle. */
  animation-delay: 0s;
}
/* 10 checkpoint colors, each held for 12s then faded to the next over 10s
   (the same transition speed the original 6-color version used) - a full
   cycle takes 220s. Every 10% of keyframe range is one color's hold+fade
   segment, so the timings stay easy to re-derive: hold ends at
   segment-start + 12/22 of the segment (~5.4545%). A pure color fade (no
   motion), so it is deliberately not gated behind prefers-reduced-motion. */
@keyframes logo-cycle {
  0%      { background-color: #009fd4; } /* azure (brand blue) */
  5.455%  { background-color: #009fd4; }
  10%     { background-color: #14b8a6; } /* teal */
  15.455% { background-color: #14b8a6; }
  20%     { background-color: #4caf50; } /* leaf green */
  25.455% { background-color: #4caf50; }
  30%     { background-color: #f2a900; } /* amber */
  35.455% { background-color: #f2a900; }
  40%     { background-color: #ff6a00; } /* tangerine */
  45.455% { background-color: #ff6a00; }
  50%     { background-color: #e8505b; } /* coral red */
  55.455% { background-color: #e8505b; }
  60%     { background-color: #b3446c; } /* raspberry */
  65.455% { background-color: #b3446c; }
  70%     { background-color: #c46fd1; } /* orchid */
  75.455% { background-color: #c46fd1; }
  80%     { background-color: #7c6fd1; } /* indigo */
  85.455% { background-color: #7c6fd1; }
  90%     { background-color: #8f979f; } /* grey-blue */
  95.455% { background-color: #8f979f; }
  100%    { background-color: #009fd4; }
}

/* Split action bubble: any number of segments, first one filled as the
   primary action, the rest flat with a divider - works the same with 2
   or 3+ items instead of hardcoding a left/right pair. */
.btn-split {
  display: inline-flex; border-radius: 999px; overflow: hidden;
  border: 1.5px solid var(--accent); box-shadow: var(--shadow);
}
.split-item {
  display: inline-block; padding: .75rem 1.4rem; font-weight: 600;
  font-size: 1rem; text-decoration: none !important; transition: background .15s ease;
  background: #fff; color: var(--accent-dark); white-space: nowrap;
}
.split-item:not(:first-child) { border-left: 1.5px solid var(--accent); }
.split-item:hover { background: var(--accent-soft); color: var(--accent-dark); }
/* Submit manuscript: the primary action, in the darker high-contrast blue. */
.split-primary { background: var(--accent-deep); color: #fff; }
.split-primary:hover { background: var(--accent-deep-dark); color: #fff; }
/* Pre-submission inquiry: a secondary action, filled with the brighter R2
   blue so it's still visually a step down from Submit. */
.split-secondary { background: var(--accent); color: #fff; }
.split-secondary:hover { background: var(--accent-dark); color: #fff; }
.hero-tagline {
  max-width: 46rem; margin: 0 auto 1.8rem; color: var(--ink-soft);
  font-size: 1.12rem;
}
.hero-actions { display: flex; gap: .8rem; justify-content: center; flex-wrap: wrap; }

/* Sections */
.section { padding: 3.2rem 0; }
.section-alt { background: var(--bg-alt); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1.4rem; }
.section-head h2 { font-size: 1.7rem; margin: 0; }
.more { font-weight: 600; font-size: .92rem; white-space: nowrap; }

/* Issue feature (home) */
.issue-feature {
  display: grid; grid-template-columns: 110px 1fr; gap: 1.6rem; align-items: start;
  margin-bottom: 2.4rem; padding-bottom: 2.4rem; border-bottom: 1px solid var(--rule);
}
.issue-feature:last-child:not(.issue-feature-highlight) {
  margin-bottom: 0; padding-bottom: 0; border-bottom: none;
}
.issue-cover img, .issue-cover-lg {
  border-radius: var(--radius); box-shadow: var(--shadow); display: block;
}
.issue-feature-body h3 { font-size: 1.35rem; margin: 0 0 .3rem; }
/* An issue with no cover (issue.cover falsy) renders no first grid item, so
   .issue-feature-body ends up alone in the 110px/1fr grid and would
   otherwise be squeezed into that narrow first column. */
.issue-feature-body:only-child { grid-column: 1 / -1; }

/* Subtle callout treatment for the "Under Review" card - it's live,
   editable content rather than a fixed published issue, so it earns a
   little visual distinction without being loud about it. A cooler, grayer
   blue than --accent-soft so it doesn't blend with the accent-soft tint
   used elsewhere (hover states etc). */
.issue-feature-highlight {
  background: var(--highlight-soft); border-radius: var(--radius);
  padding: 1.8rem 2rem; margin-bottom: 0; border-bottom: none;
}
.issue-feature-highlight .issue-cover img { box-shadow: none; border: 1px solid var(--rule); }

/* Article cards: plain, divider-only by default (home/issues/issue pages -
   a boxed card per article read as too "boxes-within-boxes" alongside the
   issue-feature sections they already sit inside). The dedicated Articles
   browsing page opts back into a fully boxed card via .article-card-boxed,
   where a bordered result row reads better. */
.article-list { list-style: none; margin: 0; padding: 0; }
.article-card {
  padding: 0 0 1.1rem; margin-bottom: 1.1rem; border-bottom: 1px solid var(--rule);
}
.article-list li.article-card:last-child { margin-bottom: 0; border-bottom: none; padding-bottom: 0; }
.article-card-boxed {
  background: #fff; border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.1rem 1.3rem; margin-bottom: .9rem; transition: box-shadow .15s ease;
}
.article-card-boxed:hover { box-shadow: var(--shadow); }
.article-card h3, .article-card h4 { margin: .1rem 0 .35rem; font-size: 1.18rem; }
.article-card .subtitle { font-weight: 400; color: var(--ink-soft); }
.article-section {
  text-transform: uppercase; letter-spacing: .1em; font-size: .72rem;
  font-weight: 700; color: var(--accent-deep); margin: 0 0 .2rem;
}
.article-authors { color: var(--ink-soft); font-size: .92rem; margin: 0 0 .5rem; }
.article-excerpt { color: var(--ink-soft); font-size: .93rem; margin: 0 0 .6rem; }
.article-links { margin: .3rem 0 0; }

/* Abstract/Lay Summary disclosures on an under-review article card - each
   one's own title is the click target, collapsed by default. Same
   marker-toggle technique as .issue-articles. */
.article-extend { margin: .5rem 0 0; }
.article-extend > summary {
  cursor: pointer; list-style: none; display: inline-block;
  font-size: .78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted);
}
.article-extend > summary::-webkit-details-marker { display: none; }
.article-extend > summary::before { content: "▾ "; }
.article-extend:not([open]) > summary::before { content: "▸ "; }
.article-extend .prose { margin-top: .4rem; font-size: .92rem; color: var(--ink-soft); }
.article-extend .prose p { margin: 0 0 .5rem; }

/* News cards */
.news-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.1rem; }
.news-card {
  background: #fff; border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 1.2rem 1.3rem;
}
.news-card h3 { font-size: 1.1rem; margin: .2rem 0 .5rem; }
.news-card p { font-size: .92rem; color: var(--ink-soft); margin: 0; }

/* Further-projects tiles: an auto-advancing carousel that always shows
   --carousel-per-page tiles at once (3 on desktop, fewer as the viewport
   narrows), plus manual page dots below. See the inline script in
   home.html for the pagination logic this variable drives. */
:root { --carousel-per-page: 3; }
@media (max-width: 900px) { :root { --carousel-per-page: 2; } }
@media (max-width: 600px) { :root { --carousel-per-page: 1; } }

.project-carousel { overflow: hidden; }
.project-carousel-track { display: flex; gap: 1.3rem; transition: transform .5s ease; }
.project-tile {
  flex: 0 0 calc((100% - (var(--carousel-per-page) - 1) * 1.3rem) / var(--carousel-per-page));
  min-width: 0;
  display: flex; flex-direction: column; background: #fff; border: 1px solid var(--rule);
  border-radius: var(--radius); overflow: hidden; color: var(--ink); text-decoration: none !important;
  transition: box-shadow .15s ease, transform .15s ease;
}
.project-tile:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.project-tile-img {
  display: flex; align-items: center; justify-content: center; height: 130px;
  background: var(--bg-alt); padding: 1rem;
}
.project-tile-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
.project-tile-body { padding: 1rem 1.2rem 1.3rem; }
.project-tile-title { display: block; font-family: var(--serif); font-size: 1.05rem; font-weight: 700; margin-bottom: .35rem; }
.project-tile-blurb { display: block; font-size: .87rem; color: var(--ink-soft); }

.carousel-dots { display: flex; justify-content: center; gap: .55rem; margin-top: 1.4rem; }
.carousel-dot {
  width: 9px; height: 9px; padding: 0; border: none; border-radius: 50%;
  background: var(--rule); cursor: pointer; transition: background .15s ease;
}
.carousel-dot:hover { background: var(--accent-soft); }
.carousel-dot.is-active { background: var(--accent); }

/* Generic page */
/* padding-top/-bottom only (not the shorthand): this class always sits on
   the same element as .wrap, and a padding shorthand here would overwrite
   .wrap's horizontal padding with 0, pushing text flush to the viewport
   edge on narrow screens. */
.page-body { padding-top: 2.6rem; padding-bottom: 4rem; }
.page-narrow { max-width: 780px; }
.page-heading { font-size: clamp(1.8rem, 4vw, 2.4rem); margin: .4rem 0 1.2rem; }
.breadcrumbs { font-size: .85rem; color: var(--muted); margin-bottom: .6rem; }
.breadcrumbs a { color: var(--muted); }

/* Issues list (all-issues page) */
.issue-list { display: block; }
.issue-feature-body h2 { font-size: 1.35rem; margin: 0 0 .3rem; }
.issue-articles { margin-top: .9rem; }
.issue-articles > summary {
  cursor: pointer; list-style: none; font-size: .85rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--accent-dark);
  margin-bottom: .8rem;
}
.issue-articles > summary::-webkit-details-marker { display: none; }
.issue-articles > summary::before { content: "▾ "; }
.issue-articles:not([open]) > summary::before { content: "▸ "; }
.issue-header { display: grid; grid-template-columns: 165px 1fr; gap: 2rem; align-items: start; margin-bottom: 2rem; }
.issue-cover-lg { max-width: 165px; }
/* Same reasoning as .issue-feature-body:only-child above - no cover means
   the title/meta div is alone in the grid and shouldn't be squeezed into
   the 165px cover column. */
.issue-header > div:only-child { grid-column: 1 / -1; }
.toc-section-title {
  font-size: 1rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--accent-deep); border-bottom: 2px solid var(--accent-soft);
  padding-bottom: .4rem; margin: 2rem 0 1rem;
}

/* Article page */
.article-page { max-width: 1120px; }
.article-header { max-width: 860px; margin-bottom: 2rem; }
.article-header h1 { font-size: clamp(1.7rem, 3.6vw, 2.3rem); margin: .3rem 0 .4rem; }
.article-subtitle { font-family: var(--serif); font-size: 1.25rem; color: var(--ink-soft); margin: 0 0 1rem; }
.author-list { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem 1.6rem; }
.author-list li { font-size: .95rem; }
.author-name { font-weight: 600; }
.orcid { margin-left: .3rem; vertical-align: -1px; }
.author-affiliation { display: block; color: var(--muted); font-size: .84rem; }
.article-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 2.5rem; align-items: start; position: relative; }
.article-abstract h2, .article-lay-summary h2, .article-fulltext > h2, .pdf-preview h2 { font-size: 1.35rem; margin: 0 0 .6rem; }
.article-lay-summary { margin-top: 1.6rem; }
.keyword-row { margin: 1.2rem 0; font-size: .93rem; color: var(--ink-soft); }

/* Full text extracted from the PDF */
.article-fulltext { margin-top: 2.2rem; border-top: 1px solid var(--rule); padding-top: 1.4rem; }
/* .prose.fulltext-body-content outranks .prose's later overflow-wrap:
   break-word; "anywhere" (unlike break-word) also shrinks min-content
   size, so long reference URLs can't widen the flex column on phones. */
.prose.fulltext-body-content { font-size: .97rem; overflow-wrap: anywhere; }
.fulltext-body h3 { font-size: 1.2rem; margin-top: 1.8rem; }
.fulltext-body h4 { font-size: 1.05rem; margin-top: 1.4rem; }
.fulltext-figure { margin: 1.6rem 0; text-align: center; }
/* Zoom/lightbox removed – figures are now static images. */
.fulltext-figure .figure-zoom {
  display: inline-block; padding: 0; border: 1px solid var(--rule);
  border-radius: var(--radius); background: #fff;
  max-width: 100%; overflow: hidden;
}
.fulltext-figure img { display: block; max-width: 100%; height: auto; }
.fulltext-figure figcaption {
  font-size: .85rem; color: var(--ink-soft); margin-top: .6rem; text-align: left;
}
.fulltext-equation { text-align: center; }
.fulltext-equation img { max-width: 100%; height: auto; }

/* Footnotes: detected in scripts/pdf_fulltext.py's _extract() via a
   leading small-font marker + page-bottom position, pulled out of
   reading order into one list at the end of the extracted text, linked
   both ways to their in-text marker. scroll-margin-top matches .guide-toc's
   existing offset so a jump lands clear of the sticky header. */
.fulltext-footref { position: relative; font-size: .72em; }
.fulltext-footref a { color: var(--accent-deep); text-decoration: none; padding: 0 1px; }
.fulltext-footref a:hover, .fulltext-footref a:focus { text-decoration: underline; }
/* Hovering a footnote number shows its text the same way hovering an
   in-text citation does - reuses .cite-tooltip's look/positioning as-is,
   just adding the trigger for this element. :focus-within (not :focus)
   since the focusable element is the <a> inside, not .fulltext-footref
   itself. */
.fulltext-footref:hover .cite-tooltip, .fulltext-footref:focus-within .cite-tooltip {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
}
.fulltext-footnotes {
  margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--rule);
  font-size: .88rem; color: var(--ink-soft);
}
.fulltext-footnotes ol { margin: 0; padding-left: 1.4rem; }
.fulltext-footnotes li { margin-bottom: .6rem; }
.fulltext-footnotes li, .fulltext-footref a { scroll-margin-top: 90px; }
.footnote-backref { margin-left: .3rem; color: var(--muted); text-decoration: none; font-size: .85em; }
.footnote-backref:hover, .footnote-backref:focus { color: var(--accent-dark); }

/* Reading-options toolbar (gear toggle) above the extracted full text. */
.fulltext-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.fulltext-note { margin: 0; font-style: italic; }
.fulltext-settings-toggle {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; background: #fff; border: 1.5px solid var(--rule);
  border-radius: 50%; color: var(--muted); cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.fulltext-settings-toggle:hover, .fulltext-settings-toggle[aria-expanded="true"] {
  color: var(--accent-dark); border-color: var(--accent);
}

/* The reading-options box itself - a row of labeled button groups, shown
   between the toolbar and the full text when the gear is toggled open. */
.fulltext-settings {
  display: flex; flex-wrap: wrap; gap: 1.2rem 2rem; margin-bottom: 1.4rem;
  padding: 1rem 1.2rem; background: var(--bg-alt); border: 1px solid var(--rule); border-radius: var(--radius);
}
/* Column width and the sidebar-collapse it triggers, in particular, don't
   do much on a phone-sized screen where the sidebar already stacks below
   the content - only shown below the same breakpoint the article layout
   itself switches to single-column at. */
.fulltext-settings-mobile-note {
  display: none; flex: 1 0 100%; margin: 0 0 .8rem;
  font-size: .8rem; font-style: italic; color: var(--muted);
}
@media (max-width: 900px) {
  .fulltext-settings-mobile-note { display: block; }
}
/* Explicit override: [hidden] and .fulltext-settings{display:flex} are
   otherwise tied at equal specificity, so the browser's own [hidden]
   default (display:none) loses to this rule and the panel never actually
   hides - same class of bug as the nav dropdown's explicit show/hide. */
.fulltext-settings[hidden] { display: none; }
.setting-row { display: flex; flex-direction: column; gap: .4rem; }
.setting-label {
  font-size: .75rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted);
}
.setting-options { display: flex; border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; }
.setting-options button {
  background: #fff; border: none; border-right: 1px solid var(--rule);
  padding: .4rem .8rem; font: 600 .82rem var(--sans); color: var(--ink-soft);
  cursor: pointer; transition: background .15s ease, color .15s ease;
}
.setting-options button:last-child { border-right: none; }
.setting-options button:hover { background: var(--accent-soft); }
.setting-options button.is-active { background: var(--accent); color: #fff; }
.setting-options-aa button { font-family: var(--serif); line-height: 1; padding: .4rem 1rem; }

/* Reading-option effects, applied to the extracted full text itself via
   data attributes set by the inline script in article.html. Targeted at
   .fulltext-body-content directly (not just inherited from the outer
   .fulltext-body) because .prose.fulltext-body-content's own font-size
   rule below would otherwise block inheritance of font-size/line-height
   from ever reaching the actual text. */
.fulltext-body[data-font="serif"] .fulltext-body-content { font-family: var(--serif); }
.fulltext-body[data-font="sans"] .fulltext-body-content { font-family: var(--sans); }
.fulltext-body[data-size="sm"] .fulltext-body-content { font-size: .85rem; }
.fulltext-body[data-size="md"] .fulltext-body-content { font-size: .97rem; }
.fulltext-body[data-size="lg"] .fulltext-body-content { font-size: 1.15rem; }
.fulltext-body[data-spacing="tight"] .fulltext-body-content { line-height: 1.4; }
.fulltext-body[data-spacing="normal"] .fulltext-body-content { line-height: 1.65; }
.fulltext-body[data-spacing="loose"] .fulltext-body-content { line-height: 2; }
/* Column width constrains the reading measure of the text itself, not the
   background box below - that box (data-bg) always spans the full width
   of its container so a colored background reaches both edges regardless
   of how narrow the text column is set to. */
.fulltext-body[data-width="narrow"] .fulltext-body-content { max-width: 540px; margin: 0 auto; }
.fulltext-body[data-width="normal"] .fulltext-body-content { max-width: 760px; margin: 0 auto; }
.fulltext-body[data-width="wide"] .fulltext-body-content { max-width: none; }
.fulltext-body[data-bg="forrt"] {
  background: #FEFDF6; padding: 1.6rem clamp(1.5rem, 5vw, 3.5rem); border-radius: var(--radius);
}
.fulltext-body[data-bg="dark"] {
  background: #1c2733; color: #dbe4ee; padding: 1.6rem clamp(1.5rem, 5vw, 3.5rem); border-radius: var(--radius);
}
/* Headings have their own site-wide color (h1-h4 { color: var(--ink) }),
   which wins over inheriting the container's lighter color set above -
   without this they render var(--ink) text on a var(--ink)-ish
   background, i.e. invisible. */
.fulltext-body[data-bg="dark"] h3,
.fulltext-body[data-bg="dark"] h4 { color: inherit; }
.fulltext-body[data-bg="dark"] a,
.fulltext-body[data-bg="dark"] .cite-ref { color: #8fd0ff; }
.fulltext-body[data-bg="dark"] .cite-ref { border-bottom-color: rgba(143, 208, 255, .35); }
.fulltext-body[data-bg="dark"] .fulltext-figure figcaption { color: #b8c4d0; }
.fulltext-body[data-bg="dark"] .fulltext-figure .figure-zoom { background: #26313d; border-color: #34404c; }
.fulltext-body[data-bg="dark"] .fulltext-footref a { color: #8fd0ff; }
.fulltext-body[data-bg="dark"] .fulltext-footnotes { border-top-color: #34404c; color: #b8c4d0; }
.fulltext-body[data-bg="dark"] .footnote-backref { color: #8697a8; }
/* .cite-tooltip's own background (var(--ink)) is byte-identical to this
   dark reading background, so without an override the tooltip box is
   invisible here - only its text and a barely-visible same-hue shadow show. */
.fulltext-body[data-bg="dark"] .cite-tooltip { background: #26313d; border: 1px solid #34404c; }

/* In-text citations, hoverable to show the matching full reference (from
   OJS's own reference list, not the PDF's copy of it). */
.cite-ref { position: relative; color: var(--accent-deep); border-bottom: 1px solid var(--accent-soft); cursor: help; }
.cite-tooltip {
  position: absolute; left: 0; bottom: 100%; margin-bottom: 6px;
  width: max-content; max-width: 320px; background: var(--ink); color: #fff;
  font-size: .82rem; line-height: 1.45; padding: .6rem .8rem;
  border-radius: 8px; box-shadow: var(--shadow); z-index: 20;
  opacity: 0; visibility: hidden; transform: translateY(4px); pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.cite-ref:hover .cite-tooltip, .cite-ref:focus .cite-tooltip {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
}
.cite-tooltip a { color: #9ec8e8; text-decoration: underline; }

/* Article view tabs: PDF (default) + experimental HTML full text */
.article-views { margin-top: 2.2rem; }
.view-tabs {
  display: flex; gap: .3rem; border-bottom: 1px solid var(--rule); margin-bottom: 1.2rem;
}
.view-tab {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem 1.1rem; font: 600 .95rem var(--sans); color: var(--muted);
  background: none; border: none; border-bottom: 2px solid transparent;
  margin-bottom: -1px; cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.view-tab:hover { color: var(--ink); }
.view-tab.is-active { color: var(--accent-dark); border-bottom-color: var(--accent); }
.view-tab-badge {
  font: 700 .62rem var(--sans); text-transform: uppercase; letter-spacing: .06em;
  color: var(--accent-dark); background: var(--accent-soft);
  padding: .1rem .45rem; border-radius: 999px;
}
.view-panel[hidden] { display: none; }

.pdf-frame {
  width: 100%; height: min(78vh, 900px); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: var(--shadow); background: #525659;
}

.article-references { margin-top: 2rem; border-top: 1px solid var(--rule); padding-top: 1.2rem; }
.article-references summary { cursor: pointer; list-style: none; }
.article-references summary h2 { display: inline; font-size: 1.35rem; }
.article-references summary::after { content: " ▸"; color: var(--accent); font-size: 1.3em; vertical-align: -.05em; }
.article-references[open] summary::after { content: " ▾"; }
.references-body { margin-top: 1rem; font-size: .92rem; }
.references-body p { margin: 0 0 .7rem; padding-left: 1.6rem; text-indent: -1.6rem; }

/* Merged sidebar: one column, separated from the article by a single
   subtle rule rather than each block being its own boxed card. Individual
   .aside-section blocks get a thin divider between them instead. */
.article-aside { border-left: 1px solid var(--rule); padding-left: 1.8rem; }
.aside-section { padding-bottom: 1.2rem; margin-bottom: 1.2rem; border-bottom: 1px solid var(--rule); }
.aside-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
.aside-section h2 { font-family: var(--sans); font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 0 0 .6rem; }
.aside-actions .altmetric-embed { margin-top: .7rem; }

/* Sits on .article-layout, not inside .article-aside, so it stays visible
   (and clickable) even when the sidebar itself is display:none - otherwise
   collapsing removes the only way to expand it again. */
.sidebar-toggle { display: none; }
/* Range syntax (not min-width: 901px) so this is the exact complement of
   the max-width: 900px query below, with no fractional-viewport-width gap
   between them. */
@media (width > 900px) {
  .sidebar-toggle {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 2px; right: calc(300px - 15px); width: 30px; height: 30px;
    padding: 0; background: #fff; border: 1.5px solid var(--rule); border-radius: 50%;
    box-shadow: var(--shadow); color: var(--muted); cursor: pointer; z-index: 3;
    transition: right .2s ease, color .15s ease, border-color .15s ease;
  }
  .sidebar-toggle:hover { color: var(--accent-dark); border-color: var(--accent); }
  .sidebar-toggle-icon { display: block; transition: transform .2s ease; }
  .article-layout.sidebar-collapsed { grid-template-columns: minmax(0, 1fr); }
  .article-layout.sidebar-collapsed .article-aside { display: none; }
  .article-layout.sidebar-collapsed .sidebar-toggle { right: 8px; }
  .article-layout.sidebar-collapsed .sidebar-toggle-icon { transform: rotate(180deg); }
}
.detail-list { margin: 0; }
.detail-list dt { font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-top: .6rem; }
.detail-list dd { margin: 0; font-size: .93rem; overflow-wrap: anywhere; }
.citation-text { font-size: .88rem; color: var(--ink-soft); }
.cite-box-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; margin-bottom: .6rem; }
.cite-box-head h2 { margin: 0; }
.copy-btn {
  flex-shrink: 0;
  font: 600 .7rem var(--sans); color: var(--muted);
  background: #fff; border: 1px solid var(--rule); border-radius: 6px;
  padding: .15rem .5rem; cursor: pointer; transition: all .15s ease;
}
.copy-btn:hover { color: var(--accent-dark); border-color: var(--accent); }
.citation-links a { margin-right: .9rem; font-size: .88rem; font-weight: 600; }
.citation-links .copy-btn-link {
  background: none; border: none; padding: 0; margin-right: .9rem;
  font: 600 .88rem var(--sans); color: var(--accent-deep); cursor: pointer;
}
.citation-links .copy-btn-link:hover { color: var(--accent); text-decoration: underline; }
.license-box img { margin-top: .4rem; }

/* Usage chart */
.stats-chart { margin-top: .2rem; }
.stats-chart svg { display: block; }
.line-views { fill: none; stroke: #7fb3d8; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.line-downloads { fill: none; stroke: var(--accent-dark); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.dot-views { fill: #7fb3d8; }
.dot-downloads { fill: var(--accent-dark); }
.chart-axis { stroke: var(--rule); stroke-width: 1; }
.chart-label { font-size: 9px; fill: var(--muted); font-family: var(--sans); }
.chart-legend { font-size: .78rem; color: var(--muted); margin: .3rem 0 0; }
.legend-dot { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin: 0 .25rem 0 .6rem; vertical-align: -1px; }
.legend-dot:first-child { margin-left: 0; }
.legend-views { background: #7fb3d8; }
.legend-downloads { background: var(--accent-dark); }

/* Submissions page: resources + funnel charts */
.resource-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.1rem; margin: 1.4rem 0 2.4rem; }
.resource-card {
  display: block; background: var(--bg-alt); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 1.1rem 1.3rem; text-decoration: none !important;
  transition: box-shadow .15s ease;
}
.resource-card:hover { box-shadow: var(--shadow); }
.resource-card h3 { font-size: 1.02rem; margin: 0 0 .35rem; color: var(--accent-dark); }
.resource-card p { font-size: .88rem; color: var(--ink-soft); margin: 0; }

/* Long guide content (Submissions page only): a sticky table of contents
   plus collapsible sections, so the page is scannable instead of one long
   wall of text. */
.guide-layout { display: grid; grid-template-columns: 220px 1fr; gap: 2.5rem; align-items: start; margin-top: 2rem; }
.guide-toc { position: sticky; top: 90px; }
.guide-toc h2 { font-family: var(--sans); font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 0 0 .7rem; }
.guide-toc ul { list-style: none; margin: 0; padding: 0; }
.guide-toc li { margin-bottom: .55rem; }
.guide-toc a { font-size: .88rem; color: var(--ink-soft); }
.guide-toc a:hover { color: var(--accent-deep); }
.guide-section { border-bottom: 1px solid var(--rule); padding: 1.3rem 0; }
.guide-section:first-child { padding-top: 0; }
.guide-section:last-child { border-bottom: none; }
.guide-section summary { cursor: pointer; list-style: none; }
.guide-section summary::-webkit-details-marker { display: none; }
.guide-section summary h2 { display: inline; font-size: 1.25rem; }
.guide-section summary::after { content: " ▸"; color: var(--accent); font-size: 1.2em; }
.guide-section[open] summary::after { content: " ▾"; }
.guide-section-body { margin-top: .9rem; }
@media (max-width: 860px) {
  .guide-layout { grid-template-columns: 1fr; }
  .guide-toc {
    position: static; border: 1px solid var(--rule); border-radius: var(--radius);
    padding: 1rem 1.3rem; margin-bottom: 1.6rem;
  }
}

.submission-charts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 2rem; margin-top: 1.2rem; padding-top: 2rem; border-top: 1px solid var(--rule);
}
.submission-chart-box h3 { font-size: 1rem; margin: 0 0 .8rem; }
.bar-submissions { fill: var(--accent); }

/* status_stacked_bar(): plain HTML/CSS, not SVG - a native SVG <title>
   tooltip is unreliable across browsers (and absent on touch), so each
   segment gets a custom hover/focus tooltip instead, matching the
   in-text citation tooltip's look. The counts are shown only in that
   tooltip, not a separate legend. */
.status-bar { display: flex; height: 26px; border-radius: 4px; overflow: visible; }
.status-segment {
  position: relative; height: 100%; cursor: default;
  outline-offset: 2px;
}
.status-segment:first-child { border-radius: 4px 0 0 4px; }
.status-segment:last-child { border-radius: 0 4px 4px 0; }
.status-published { background: #2a8a5f; }
.status-underreview { background: #d9a441; }
.status-declined { background: #c1594f; }
.status-tooltip {
  position: absolute; left: 50%; bottom: 100%; margin-bottom: 6px;
  transform: translateX(-50%) translateY(4px);
  width: max-content; max-width: 220px; background: var(--ink); color: #fff;
  font-size: .82rem; line-height: 1.4; padding: .5rem .75rem;
  border-radius: 8px; box-shadow: var(--shadow); z-index: 5; white-space: nowrap;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.status-segment:hover .status-tooltip, .status-segment:focus .status-tooltip {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translateX(-50%) translateY(0);
}
/* First/last segments are near the bar's edges, so their tooltip anchors
   to that same edge (like the citation tooltip's left:0) instead of
   centering, which would push half of it past the bar. */
.status-segment:first-child .status-tooltip { left: 0; transform: translateY(4px); }
.status-segment:first-child:hover .status-tooltip, .status-segment:first-child:focus .status-tooltip { transform: translateY(0); }
.status-segment:last-child .status-tooltip { left: auto; right: 0; transform: translateY(4px); }
.status-segment:last-child:hover .status-tooltip, .status-segment:last-child:focus .status-tooltip { transform: translateY(0); }

/* Homepage "Under Review" card: same status-breakdown chart as the
   Submissions page. */
.under-review-status { margin-top: 1.2rem; padding-top: 1.2rem; border-top: 1px solid var(--rule); }
.under-review-status h4 { font-size: .95rem; margin: 0 0 .7rem; }

/* Articles browsing page */
.articles-filters { margin-bottom: 1.6rem; }
.articles-search {
  display: block; width: 100%; max-width: 420px; margin-bottom: 1rem;
  padding: .6rem .9rem; font-size: .95rem; font-family: var(--sans);
  border: 1.5px solid var(--rule); border-radius: 999px; color: var(--ink);
}
.articles-search:focus { outline: none; border-color: var(--accent); }
.articles-filter-row { display: flex; flex-wrap: wrap; gap: 1.2rem 1.8rem; align-items: flex-start; }
.articles-filter { display: flex; flex-direction: column; gap: .35rem; font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }

.articles-categories { position: relative; }
.articles-categories summary {
  cursor: pointer; list-style: none; display: flex; flex-direction: column; gap: .35rem;
  font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
.articles-categories summary::-webkit-details-marker { display: none; }
.articles-categories-summary { font: 600 .92rem var(--sans); color: var(--ink); text-transform: none; letter-spacing: normal; }
/* Arrow sits inline after the value ("(all)") rather than dropping onto its
   own line below it — the summary is a flex column, so a summary::after
   would become an orphaned third row. */
.articles-categories-summary::after { content: " ▾"; color: var(--accent); }
.articles-categories[open] .articles-categories-summary::after { content: " ▴"; }
.category-panel {
  position: absolute; top: calc(100% + .4rem); left: 0; z-index: 5; width: 260px;
  background: #fff; border: 1px solid var(--rule); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: .9rem 1rem;
}
.category-actions { display: flex; gap: .8rem; margin-bottom: .6rem; padding-bottom: .6rem; border-bottom: 1px solid var(--rule); }
.category-actions button {
  background: none; border: none; padding: 0; font: 600 .8rem var(--sans); color: var(--accent-dark);
  cursor: pointer; text-decoration: underline;
}
.category-list { max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: .4rem; }
.category-list label { display: flex; align-items: center; gap: .5rem; font-size: .88rem; font-weight: 400; color: var(--ink); text-transform: none; letter-spacing: normal; }

.year-filter { min-width: 220px; }
.year-slider { position: relative; height: 24px; margin-top: .3rem; }
.year-track { position: absolute; top: 50%; left: 0; right: 0; height: 4px; margin-top: -2px; background: var(--rule); border-radius: 2px; }
.year-track-fill { position: absolute; top: 0; height: 4px; background: var(--accent); border-radius: 2px; }
.year-range {
  position: absolute; top: 0; left: 0; width: 100%; margin: 0; height: 24px;
  background: transparent; -webkit-appearance: none; appearance: none; pointer-events: none;
}
.year-range::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto; width: 16px; height: 16px; margin-top: -6px;
  border-radius: 50%; background: #fff; border: 2px solid var(--accent); cursor: pointer;
}
.year-range::-moz-range-thumb {
  pointer-events: auto; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; border: 2px solid var(--accent); cursor: pointer;
}
.year-range::-webkit-slider-runnable-track { background: transparent; }
.year-range::-moz-range-track { background: transparent; }

.article-year { color: var(--muted); font-size: .85rem; margin-right: .7rem; }
#articles-count { margin: 0 0 1rem; }

/* Editorial team */
.team-section { margin-bottom: 2.6rem; }
.team-section-title {
  font-size: 1rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--accent-deep); border-bottom: 2px solid var(--accent-soft);
  padding-bottom: .4rem; margin: 2rem 0 1.2rem;
}
.team-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 1.4rem 1.2rem;
}
.team-card { text-align: center; }
.team-photo {
  width: 112px; height: 112px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow); border: 3px solid #fff; outline: 1px solid var(--rule);
}
.team-placeholder {
  font-family: var(--serif); font-size: 2rem; font-weight: 700; color: #fff;
}
.hue-0 { background: #1e6ea8; }
.hue-1 { background: #2a8a8a; }
.hue-2 { background: #5a7fb5; }
.hue-3 { background: #14507c; }
.hue-4 { background: #427da3; }
.team-name { font-family: var(--serif); font-size: 1.02rem; margin: .7rem 0 .15rem; }
.team-affiliation { color: var(--ink-soft); font-size: .84rem; margin: 0; }
.team-roles { color: var(--muted); font-size: .78rem; margin: .25rem 0 0; }
.team-plain { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 3rem; }
.team-plain li { margin-bottom: .55rem; font-size: .93rem; break-inside: avoid; }
.team-plain .team-name { font-weight: 600; font-family: var(--sans); font-size: .93rem; }
.team-plain .team-affiliation { font-size: .88rem; }
.team-note { margin-top: 1.2rem; color: var(--ink-soft); font-size: .92rem; }
@media (max-width: 700px) { .team-plain { columns: 1; } }

.team-intro { margin-bottom: 3rem; padding-bottom: 2.2rem; border-bottom: 1px solid var(--rule); }
.team-intro .page-heading { margin-bottom: 1rem; }
.team-intro .team-section-title { margin-top: 1.8rem; }
/* Comfortable reading measure for the intro copy; the section-title rules
   above stay full width so their underlines still span the column. */
.team-intro .prose { max-width: 800px; }

/* Media coverage */
.team-media { margin-top: 3rem; padding-top: .5rem; }
.media-list { list-style: none; margin: 0; padding: 0; }
.media-item {
  display: flex; gap: 1.2rem; align-items: baseline; padding: 1rem 0;
  border-bottom: 1px solid var(--rule);
}
.media-item:last-child { border-bottom: none; }
.media-date {
  flex-shrink: 0; width: 4.2rem; font-size: .78rem; font-weight: 700;
  color: var(--muted); letter-spacing: .04em;
}
.media-body { font-size: .97rem; }
.media-body a { font-weight: 600; }
.media-outlet { display: block; color: var(--muted); font-size: .84rem; margin-top: .15rem; }
@media (max-width: 500px) {
  .media-item { flex-direction: column; gap: .3rem; }
  .media-date { width: auto; }
}

/* Announcements */
.announcement-list { list-style: none; margin: 0; padding: 0; }
.announcement-item { border-bottom: 1px solid var(--rule); padding: 1.3rem 0; }
.announcement-item h2 { font-size: 1.25rem; margin: .2rem 0 .4rem; }
.announcement-item p { color: var(--ink-soft); margin: 0; }

/* Prose (scraped OJS / Quarto content) */
.prose { font-size: 1rem; overflow-wrap: break-word; }
.prose a { overflow-wrap: break-word; word-break: break-word; }
.prose h1 { font-size: 1.7rem; }
.prose h2 { font-size: 1.4rem; margin-top: 2rem; }
.prose h3 { font-size: 1.15rem; margin-top: 1.5rem; }
.prose p, .prose ul, .prose ol { margin: 0 0 1rem; }
.prose img { border-radius: 6px; }
.prose table { border-collapse: collapse; width: 100%; margin: 1rem 0; font-size: .92rem; display: block; overflow-x: auto; }
.prose th, .prose td { border: 1px solid var(--rule); padding: .5rem .7rem; text-align: left; }
.prose th { background: var(--bg-alt); }
.prose hr { border: none; border-top: 1px solid var(--rule); margin: 1.6rem 0; }
.prose blockquote { border-left: 3px solid var(--accent-soft); margin: 1rem 0; padding: .2rem 0 .2rem 1rem; color: var(--ink-soft); }

/* Keep body copy at a readable measure, matching the article/page columns,
   rather than letting it run the full 1120px content width. */
.home-about { max-width: 800px; }
.home-about h2 { font-size: 1.35rem; }

/* Quarto "callout" box in the homepage blurb (the disciplines list) -
   arrives from the scrape with none of Quarto's own callout CSS/icon font,
   so by default it's a bare paragraph + bullet list with an invisible,
   broken icon glyph. Give it a proper card treatment and turn the bullet
   list into wrapped pill tags, echoing the .pill style used for article
   sections/categories elsewhere on the site. */
.home-about .callout {
  background: var(--bg-alt); border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 1.3rem 1.5rem; margin: 1.6rem 0;
}
.home-about .callout-icon-container { display: none; }
.home-about .callout-title-container { font-weight: 700; color: var(--ink); }
.home-about .callout-body-container ul {
  list-style: none; margin: .9rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .5rem;
}
.home-about .callout-body-container li {
  background: var(--accent-soft); color: var(--accent-deep-dark);
  font-size: .87rem; font-weight: 600; padding: .35rem .85rem;
  border-radius: 999px;
}

/* Our Network page (organizers/funders/partners/preprint-review, moved
   here from the footer) */
.network-intro { max-width: 860px; font-size: 1.05rem; color: var(--ink-soft); margin: 0 0 2.4rem; }
.network-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 2.2rem; }
.network-block h2 { font-size: 1rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 0 0 1rem; }
.network-content img { max-width: 220px; height: auto; background: #fff; border-radius: 8px; padding: 8px; border: 1px solid var(--rule); margin: 0 .6rem .8rem 0; }
.network-content p { margin: 0 0 .6rem; }

/* Footer */
.site-footer { background: #262d34; color: #c6d2dd; margin-top: 3rem; padding: 3rem 0 2rem; }
.site-footer a { color: #9ec8e8; }
.footer-connect {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.6rem; border-top: 1px solid #35485c; padding-top: 1.8rem; margin-bottom: 1.8rem;
}
.connect-block h2 { font-family: var(--sans); font-size: .78rem; text-transform: uppercase; letter-spacing: .12em; color: #8ba2b5; margin: 0 0 .7rem; }
.connect-list { list-style: none; margin: 0; padding: 0; }
.connect-list li { margin-bottom: .45rem; font-size: .92rem; }
.connect-list a { display: inline-flex; align-items: center; gap: .5rem; }
.social-icon { width: 16px; height: 16px; flex-shrink: 0; }
.footer-credits { display: flex; flex-direction: column; align-items: flex-end; gap: .7rem; }
.hosted-by img { max-height: 70px; width: auto; background: #fff; border-radius: 6px; padding: 6px; }
.ojs-badge { display: block; }
.ojs-badge img { background: #fff; border-radius: 6px; padding: 8px; }
.footer-meta { border-top: 1px solid #35485c; padding-top: 1.4rem; font-size: .85rem; }
.footer-links img { max-height: 70px; width: auto; background: #fff; border-radius: 6px; padding: 5px; }
.footer-links p { margin: 0 0 .5rem; }
.mirror-note { color: #8ba2b5; margin-top: .8rem; }

/* Responsive */
@media (max-width: 900px) {
  /* Single column, but interleave main and aside content into a sensible
     reading order: abstract, then the action buttons (Download PDF etc.),
     then the PDF viewer and references, then the remaining aside boxes
     (details, usage, citation, license). display:contents lifts the boxes
     out of their two columns so flex order can arrange them. */
  .article-layout { display: flex; flex-direction: column; }
  .article-main, .article-aside, .aside-inner { display: contents; }
  .article-aside { border-left: none; padding-left: 0; }
  .article-abstract { order: 1; }
  .keyword-row { order: 2; }
  .article-lay-summary { order: 2; }
  .article-aside .aside-section { order: 6; }
  .article-aside .aside-actions { order: 3; }
  /* min-width:0 - a flex item's default min-width:auto sizes it to its
     longest unbreakable word (reference URLs), overflowing the viewport. */
  .article-views { order: 4; min-width: 0; }
  .article-references { order: 5; }
  .issue-feature, .issue-header { grid-template-columns: 1fr; }
  .issue-cover img { max-width: 130px; }
  .issue-cover-lg { max-width: 160px; }
  /* The category dropdown panel is absolutely positioned under its summary
     on desktop; on a narrow screen the summary can sit anywhere in the
     wrapped filter row, so a fixed-width absolute panel can overflow the
     viewport - let it flow inline at full width instead. */
  .category-panel { position: static; width: 100%; margin-top: .5rem; }
}
/* Nav collapses to the hamburger menu well before the header actually runs
   out of room (1120px, vs. the more typical ~760px "mobile" breakpoint used
   below for hero/pdf sizing) - a partial wrap, e.g. just the Login link
   dropping to its own row, reads far worse than switching to the menu a
   bit earlier than strictly necessary. The full nav row (brand + gap +
   About/Articles/Announcements/Submissions/Reviewer Guidelines/Submit/
   Login) needs ~1075px before it stops fitting on one line - 1120px
   leaves a safety margin for font-rendering differences across
   browsers/OSes instead of cutting it exactly at that measured width. */
@media (max-width: 1120px) {
  .header-inner { flex-wrap: wrap; padding-top: .6rem; padding-bottom: .6rem; }
  .nav-toggle-label {
    display: block; margin-left: auto; cursor: pointer; padding: .8rem;
  }
  .nav-toggle-label span, .nav-toggle-label span::before, .nav-toggle-label span::after {
    display: block; width: 24px; height: 2.5px; background: #fff;
    border-radius: 2px; position: relative; transition: transform .2s ease;
  }
  .nav-toggle-label span::before, .nav-toggle-label span::after { content: ""; position: absolute; }
  .nav-toggle-label span::before { top: -7px; }
  .nav-toggle-label span::after { top: 7px; }
  .site-nav { display: none; width: 100%; margin: 0; }
  .nav-toggle:checked ~ .site-nav { display: block; }
  .site-nav > ul { flex-direction: column; align-items: stretch; gap: 0; padding-bottom: .8rem; }
  .site-nav a:not(.btn), .nav-dropdown > summary { padding: .75rem .7rem; font-size: 1rem; }
  .site-nav .nav-login a { font-size: .85rem; }
  .dropdown { border: none; box-shadow: none; padding-left: 1rem; }
  .nav-cta { margin: .6rem 0 0; }
}
@media (max-width: 760px) {
  .hero { padding: 3rem 0 2.6rem; }
  .hero-compact { padding: 2.4rem 0 2.2rem; }
  .hero-logo-sm { max-width: 280px; }
  .pdf-frame { height: 70vh; }
}
@media (max-width: 640px) {
  /* Stack the split bubble so long labels never overflow tiny/narrow
     screens - with 3 segments this is needed well before phone-sized
     widths, not just under ~430px. */
  .btn-split { flex-direction: column; width: 100%; max-width: 320px; border-radius: 26px; }
  .split-item { text-align: center; }
  .split-item:not(:first-child) { border-left: none; border-top: 1.5px solid var(--accent); }
  .hero-actions { flex-direction: column; align-items: center; }
}
