/* ============================================================
   CiteLink.org — Design System v2 "Aurora"
   Modern SaaS aesthetic: indigo-violet gradients, glass header,
   soft-depth cards, light + dark themes (html[data-theme]).
   Class names are stable — pages depend on them.
   ============================================================ */

:root {
  /* Brand scale (indigo) — names kept for page compatibility */
  --brand-950: #0b1029;
  --brand-900: #171e4b;
  --brand-800: #232c6e;
  --brand-700: #3730a3;
  --brand-600: #4338ca;
  --brand-500: #4f46e5;
  --brand-400: #6366f1;
  --brand-300: #818cf8;
  --brand-200: #c7d2fe;
  --brand-100: #e0e7ff;
  --brand-50:  #eef2ff;

  --violet-500: #8b5cf6;
  --cyan-400: #22d3ee;
  --grad-brand: linear-gradient(135deg, #4f46e5 0%, #7c3aed 55%, #9333ea 100%);
  --grad-text: linear-gradient(110deg, #4f46e5, #8b5cf6 60%, #6366f1);
  /* Same ramp as --grad-text, one step deeper at every stop, for the one place the
     gradient carries SMALL text. Worst stop 5.32:1 on --page (was 3.96), 5.70 on
     --surface (was 4.23). Every stop here is already in the palette: --brand-500,
     the #7c3aed of --grad-brand, and --brand-600. */
  --grad-eyebrow: linear-gradient(110deg, #4f46e5, #7c3aed 60%, #4338ca);

  /* Accent (emerald — OA / success flavour) */
  --accent-600: #059669;
  --accent-500: #10b981;
  --accent-100: #d1fae5;

  /* Ink & surfaces (light) */
  --ink: #0f172a;
  --ink-2: #46536b;
  /* --ink-3 WAS #8b96ab, WHICH IS 2.98:1 ON WHITE AND 2.70:1 ON --surface-2.
     It is a text colour in every one of its twenty-odd uses -- every .table th on
     the site, every facet count on journals.html (97 of them), every .field .hint,
     .meta-item dt, .art-meta, .clv-cap, .breadcrumbs and everything carrying
     .text-xs. None of them reached the 4.5:1 that SC 1.4.3 requires of body text,
     in either theme. Moved down the same slate ramp until the WORST backdrop
     passes: 2.70 -> 4.70 on --surface-2, 2.98 -> 5.18 on --surface,
     2.78 -> 4.84 on --page. */
  --ink-3: #626d86;
  --surface: #ffffff;
  --surface-2: #f1f4f9;
  --page: #f6f7fb;
  --line: #e5e8f0;
  /* --line-2 WAS #cbd2e0 = 1.52:1 on --surface. It is the entire visible boundary
     of .input, .field input/select/textarea, .cl-combo-btn and .pagination button
     -- the only thing that says "this is a control" -- so SC 1.4.11 asks 3:1 of it
     and it was at half that. 1.52 -> 3.42 on --surface, 3.10 on --surface-2. */
  --line-2: #818ba1;
  /* The focus ring was 35% alpha, which composites to 1.75:1 against --surface and
     1.73:1 against --page -- SC 1.4.11 asks 3:1 of a focus indicator. Opaque
     brand-400 is the same hue at full strength: 4.47 on --surface, 4.17 on --page,
     4.05 on --surface-2, and 4.20 on the light theme's dark footer. */
  --ring: #6366f1;
  --header-glass: rgba(255, 255, 255, 0.72);
  --footer-bg: #0b1029;
  --hero-ink: #e4e9f7;

  /* Status */
  --good: #0ca30c;
  --good-text: #0a7a2f;
  --warning: #f59e0b;
  --serious: #f97316;
  /* was #e11d48 = 4.24:1 on --critical-bg, the pairing .badge-crit, .notice-crit
     and .checklist .no all use. 4.24 -> 4.55; on --surface 4.70 -> 5.05. */
  --critical: #d81b45;
  --critical-bg: #fdf0f3;
  --good-bg: #eafaf1;
  --warn-bg: #fdf6e3;

  /* Tier tints (pricing.html). Each tier owns a pale tint, a saturated top edge
     and a tone -- the one colour allowed to carry text on that tint. Measured
     (tools: a WCAG sRGB script, 5 Sep 2026): every tone clears 5.0:1 on its own
     tint, --ink-2 clears 6.8:1, --brand-600 links 6.9:1; --ink-3 sits at
     4.55-4.76 so muted text INSIDE a tint is forced to --ink-2 (.tinted below).
     Reader green and Premium indigo are the palette the site already has;
     Member cyan, Team peach and the institutional violet are new pairs, named for
     the tier, kept at the saturation of --brand-50. --series-1..5 are scoped to
     .viz-root and are not used here. */
  --tint-reader: #e9f9f0;  --edge-reader: #059669;  --tone-reader: #0a7a2f;
  --tint-member: #e6f6fb;  --edge-member: #0e7c9a;  --tone-member: #0b5f78;
  --tint-premium: #eef2ff; --edge-premium: #4f46e5; --tone-premium: #3730a3;
  --tint-team: #fff2e6;    --edge-team: #d9541b;    --tone-team: #9a3412;
  --tint-inst: #f3eefc;    --edge-inst: #7c3aed;    --tone-inst: #5b21b6;
  /* A pill that sits on a column's top edge: white on the tone (6.5:1 or better
     on all five; the edge itself is 3.77-6.29 and too light for 12px text). */
  --pill-ink: #ffffff;

  /* Type */
  --font: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  --fs-xs: 0.75rem;
  --fs-sm: 0.85rem;
  --fs-base: 0.95rem;
  --fs-md: 1.07rem;
  --fs-lg: 1.28rem;
  --fs-xl: 1.6rem;
  --fs-2xl: 2rem;
  --fs-3xl: 2.6rem;

  --radius: 14px;
  --radius-sm: 9px;
  --radius-lg: 20px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05), 0 1px 6px rgba(15, 23, 42, 0.04);
  --shadow: 0 4px 16px rgba(15, 23, 42, 0.07), 0 2px 6px rgba(15, 23, 42, 0.05);
  --shadow-lg: 0 18px 44px rgba(23, 30, 75, 0.14), 0 6px 16px rgba(23, 30, 75, 0.08);
  --glow: 0 6px 22px rgba(79, 70, 229, 0.35);

  --header-h: 68px;
  --maxw: 1200px;
  color-scheme: light;
}

html[data-theme="dark"] {
  --brand-950: #05070f;
  --brand-900: #dbe3ff;   /* headings on dark */
  --brand-800: #c3cdfd;
  --brand-700: #a5b4fc;
  --brand-600: #818cf8;
  --brand-500: #6d7cfa;
  --brand-400: #7c8cfb;
  --brand-300: #5865f2;
  --brand-200: #31386e;
  --brand-100: #262c56;
  --brand-50:  #1b2040;

  --grad-text: linear-gradient(110deg, #93a2ff, #b593ff 60%, #8ea0ff);
  /* the dark gradient already measures 7.83-8.08:1 on --page, so the eyebrow keeps it */
  --grad-eyebrow: linear-gradient(110deg, #93a2ff, #b593ff 60%, #8ea0ff);

  --accent-600: #34d399;
  --accent-500: #2dd4a0;
  --accent-100: #123b2e;

  --ink: #eef1fa;
  --ink-2: #a8b1c7;
  /* was #6b7590 — 3.90 / 3.57 / 4.17 against --surface / --surface-2 / --page.
     Now 5.33 / 4.89 / 5.71. */
  --ink-3: #828ca6;
  --surface: #10162b;
  --surface-2: #171e38;
  --page: #0a0e1f;
  --line: #232a47;
  /* was #323b60 — 1.65:1 on --surface. Now 4.09, and 3.75 on --surface-2. */
  --line-2: #6d7899;
  /* was rgba(129,140,248,.45) — 2.22:1 composited. Now 6.01 on --surface,
     5.50 on --surface-2, 6.43 on --page, 6.62 on the footer. */
  --ring: #818cf8;
  --header-glass: rgba(10, 14, 31, 0.66);
  --footer-bg: #070a16;
  --hero-ink: #dee5f8;

  --good-text: #4ade80;
  --critical: #fb7185;
  --critical-bg: #3a1622;
  --good-bg: #12301f;
  --warn-bg: #33270e;

  /* Tier tints, dark: deep versions of the same hue, edges brighten, the pill
     text switches to the page ink (6.4:1 or better on every edge). Every tone
     clears 7.9:1 on its tint and --brand-600 links 5.07:1. The Team tint is kept
     at low chroma on purpose -- a dark orange is a brown, and the top edge
     carries the hue instead. */
  --tint-reader: #0f2b21;  --edge-reader: #34d399;  --tone-reader: #6ee7b7;
  --tint-member: #0c2733;  --edge-member: #22d3ee;  --tone-member: #67e8f9;
  --tint-premium: #1b2040; --edge-premium: #818cf8; --tone-premium: #a5b4fc;
  --tint-team: #2c2118;    --edge-team: #fb923c;    --tone-team: #fdba74;
  --tint-inst: #241a3d;    --edge-inst: #a78bfa;    --tone-inst: #c4b5fd;
  --pill-ink: #0a0e1f;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.5);
  --glow: 0 6px 26px rgba(109, 124, 250, 0.4);
  color-scheme: dark;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* scroll-padding-top is SC 2.4.11 Focus Not Obscured, and it was `auto`.
   .site-header is position:sticky with a 68px band over the top of the scrollport.
   Walking journals.html backwards with Shift+Tab, two controls came to rest wholly
   inside that band -- elementFromPoint at their centre returned NAV.main-nav, not
   the control -- because they were already inside the scrollport and the browser
   saw no reason to scroll. Excluding the header band from the optimal viewing
   region makes the browser treat them as out of view and scroll them clear. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 12px); }

/* THE FIRST TAB STOP ON EVERY PAGE (SC 2.4.1). Off-screen until focused. */
.skip-link {
  position: absolute; left: 0.75rem; top: -6rem;
  z-index: 100; padding: 0.7rem 1.1rem;
  background: var(--surface); color: var(--brand-600);
  border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  font-weight: 700; font-size: var(--fs-sm); text-decoration: none;
  box-shadow: var(--shadow);
  /* absolutely positioned inside a header whose width the shrink-to-fit pass can
     resolve as 0 mid-layout, which wrapped the phrase onto three lines */
  white-space: nowrap;
}
.skip-link:focus { top: 0.75rem; text-decoration: none; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink);
  background: var(--page);
  transition: background 0.25s ease, color 0.25s ease;
}
img, svg { max-width: 100%; vertical-align: middle; }
a { color: var(--brand-500); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
h1, h2, h3, h4 { line-height: 1.22; margin: 0 0 0.5em; color: var(--brand-900); font-weight: 800; letter-spacing: -0.022em; }
h1 { font-size: var(--fs-3xl); }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }
p { margin: 0 0 1em; }
ul, ol { margin: 0 0 1em; padding-left: 1.4em; }
hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; }
code { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; font-size: 0.85em; background: var(--surface-2); border: 1px solid var(--line); padding: 0.12em 0.42em; border-radius: 6px; }
pre {
  background: #0b1029; color: #cfd8f7;
  padding: 1.1rem 1.3rem; border-radius: var(--radius);
  border: 1px solid rgba(129, 140, 248, 0.25);
  overflow-x: auto; font-size: var(--fs-sm); line-height: 1.55;
  /* Belt and braces with the grid rule above: even outside a grid, a long
     unbreakable token (a URL, a base64 blob) must not widen the page. */
  max-width: 100%;
}
pre code { background: none; border: 0; color: inherit; padding: 0; }
::selection { background: rgba(99, 102, 241, 0.25); }
/* The transparent outline is not decoration. outline:none plus a box-shadow means
   the focus indicator disappears completely in Windows High Contrast / forced-colors,
   which does not paint box-shadow but does force a colour onto a transparent outline. */
:focus-visible { outline: 2px solid transparent; outline-offset: 2px; box-shadow: 0 0 0 3px var(--ring); border-radius: 6px; }

/* THREE CONTROLS HAD NO FOCUS INDICATOR AT ALL, not a weak one.
   .btn-primary/.btn-accent (:314, :316) and .pagination button.current (:846) set
   box-shadow: var(--glow) in a later rule of equal specificity to :focus-visible
   above, so the ring lost the cascade and base and focused box-shadow were
   byte-identical -- measured on the header "Apply for Indexing" CTA, which is on
   every one of the thirty pages, and on every primary form button.
   The glow is kept and the ring is added outside it, separated from the button by
   2px of page surface so it reads against the brand gradient the button is painted
   with: #fff on #4f46e5 is 6.29:1, and --ring on --surface is 4.47:1 (light) /
   6.01:1 (dark). */
.btn-primary:focus-visible,
.btn-accent:focus-visible,
.pagination button.current:focus-visible {
  box-shadow: var(--glow), 0 0 0 2px var(--surface), 0 0 0 5px var(--ring);
}

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 8px; border: 3px solid var(--page); }
::-webkit-scrollbar-track { background: transparent; }

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 1.4rem; }
.container-narrow { max-width: 880px; margin: 0 auto; padding: 0 1.4rem; }
.section { padding: 4.25rem 0; }
.section-alt { background: var(--surface); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section-head { max-width: 740px; margin: 0 auto 2.5rem; text-align: center; }
.section-head p { color: var(--ink-2); font-size: var(--fs-md); }
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  /* --grad-text's middle stop is --violet-500 #8b5cf6: 3.96:1 on --page, 4.23:1 on
     --surface. That is fine for .text-gradient, which only ever runs across large
     headings (3:1), and it fails for .eyebrow, which renders at 12px and so needs
     4.5:1. .eyebrow therefore takes its own gradient rather than dragging every
     gradient heading on the site darker with it. See --grad-eyebrow. */
  background: var(--grad-eyebrow); -webkit-background-clip: text; background-clip: text; color: transparent;
  margin-bottom: 0.6rem;
}

/* ---------- Header (glass) ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--header-glass);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border-bottom: 1px solid var(--line);
}
/* The header bar is full-bleed, so its inner row does not have to obey the
   1200px page container: with 8 nav items plus a CTA the row needs ~1210px and
   was overflowing the 1155px inner box at every desktop width — which turned
   into whole-page sideways scrolling below ~1374px. */
.site-header .container { display: flex; align-items: center; gap: 1rem; height: var(--header-h); max-width: 1400px; }
.logo { display: flex; align-items: center; gap: 0.6rem; font-size: 1.3rem; font-weight: 800; color: var(--ink); text-decoration: none; letter-spacing: -0.03em; }
.logo:hover { text-decoration: none; }
.logo .logo-mark { width: 36px; height: 36px; flex: none; filter: drop-shadow(0 3px 8px rgba(79, 70, 229, 0.35)); }
.logo .logo-cite { color: var(--ink); }
.logo .logo-link { background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
.logo .logo-tld { font-size: 0.68em; font-weight: 600; color: var(--ink-3); align-self: flex-end; margin: 0 0 3px 1px; }

.main-nav { display: flex; align-items: center; gap: 0.1rem; margin-left: auto; }
.main-nav .nav-item { position: relative; }
.main-nav a.nav-link, .main-nav button.nav-link {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.5rem 0.6rem; border-radius: 999px;
  color: var(--ink-2); font-size: var(--fs-sm); font-weight: 600;
  background: none; border: 0; cursor: pointer; font-family: inherit; white-space: nowrap;
  transition: background 0.16s, color 0.16s;
}
.main-nav a.nav-link:hover, .main-nav button.nav-link:hover { background: var(--brand-50); color: var(--brand-600); text-decoration: none; }
.main-nav .nav-link.active { color: var(--brand-500); background: var(--brand-50); }
.nav-caret { width: 8px; height: 8px; border-right: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor; transform: rotate(45deg) translateY(-2px); opacity: 0.7; }
.dropdown {
  position: absolute; top: calc(100% + 10px); left: 0; min-width: 250px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.45rem;
  opacity: 0; visibility: hidden; transform: translateY(-6px) scale(0.98);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}
/* THE MENU THAT WOULD NOT GO AWAY.
   This used to say :focus-within, and the trigger is a <button>. Clicking it with a
   mouse focuses it, focus survives the pointer leaving, and :focus-within kept the
   panel open until focus happened to move somewhere else — so a single click left
   "For Publishers" hanging over the page indefinitely. Reported on two different menus,
   which is what a rule rather than an accident looks like.

   :has(:focus-visible) keeps the half that was worth having. A keyboard user tabbing to
   the button gets :focus-visible and the menu opens; tabbing into the links inside it
   keeps matching, so the menu stays open for as long as the keyboard is in it. A mouse
   click sets focus but not :focus-visible, so it no longer sticks, and hover goes on
   doing what hover did. */
.nav-item:hover .dropdown, .nav-item:has(:focus-visible) .dropdown { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }

/* SAME BUG, SECOND CAUSE -- and this one was the one the owner kept seeing.
   buildHeader() marks the nav-item whose section contains the current page with
   .open, so the button can render highlighted. That class was ALSO in the selector
   above, which meant: on every page inside a menu -- apply.html, criteria.html,
   services.html, panel.html and all four About pages -- the flyout was pinned open
   from first paint, before any mouse or keyboard had touched it.
   That is why the :focus-visible fix appeared to do nothing. It fixed a real defect
   on the pages I tested it on, and those were pages the class was never applied to.
   .open belongs to the collapsed nav only, where it is a disclosure control and the
   media query below gives it display: block. Up here it has no business existing:
   "you are in this section" is the button's .active state, not an open panel. */

/* Browsers without :has() -- the selector above never matches there, so keyboard users
   would lose the menu entirely. They fall back to the old behaviour, which is worse on
   a mouse and correct on a keyboard; that is the right way round for a fallback. */
@supports not selector(:has(*)) {
  .nav-item:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
}
.dropdown a { display: block; padding: 0.55rem 0.8rem; border-radius: var(--radius-sm); color: var(--ink-2); font-size: var(--fs-sm); font-weight: 600; }
.dropdown a:hover { background: var(--brand-50); color: var(--brand-600); text-decoration: none; }
.dropdown .dd-desc { display: block; font-size: var(--fs-xs); color: var(--ink-3); font-weight: 400; }
.header-cta { margin-left: 0.4rem; padding-left: 1.1rem; padding-right: 1.1rem; }

.theme-toggle {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--line); cursor: pointer;
  font-size: 1.05rem; line-height: 1; margin-left: 0.35rem;
  transition: transform 0.2s, background 0.16s, border-color 0.16s;
}
.theme-toggle:hover { transform: rotate(18deg) scale(1.06); border-color: var(--brand-300); }

.nav-toggle { display: none; margin-left: auto; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0.5rem 0.62rem; cursor: pointer; }
.nav-toggle span { display: block; width: 20px; height: 2px; background: var(--ink); margin: 4px 0; border-radius: 2px; }

/* Collapse to the hamburger while the full row still fits comfortably.
   Was 960px, which left a 961–1374px band where the desktop nav was shown
   but overflowed the viewport on every page. Then 1320, then 1380 when the
   Articles item made it a 9-item nav.

   1380 was honest arithmetic and a bad experience: the row genuinely needed a
   1334px viewport, so every 1280 and 1366 laptop -- which is most of them --
   met a hamburger on a full-size screen. The owner reported exactly that.

   The fix was to shorten the row rather than to shave the threshold onto it.
   Statistics now sits inside a "Rankings" menu (NAV_ITEMS in app.js records the
   label choice and what each candidate cost), which took the nav from 1116px to
   1056px and the whole row from 1289 to 1230. Measured, not guessed: logo 157 +
   gap 16 + nav 1056, inside a container that gives (viewport - 44.8). So the row
   fits from a 1275px viewport up, and 1320 keeps ~45px of slack -- the same
   margin 1380 kept over 1334, for the same reason: system font stacks differ
   across platforms and browser zoom is not free.

   1366 now gets the full nav with 91px to spare. 1280 still collapses, and that
   is deliberate: it would clear by 5px, which is inside the noise. */
@media (max-width: 1320px) {
  .nav-toggle { display: block; }
  .main-nav {
    display: none; position: absolute; top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface); border-bottom: 1px solid var(--line);
    padding: 0.85rem 1.4rem 1.4rem; box-shadow: var(--shadow-lg);
  }
  .main-nav.open { display: flex; }
  .main-nav a.nav-link, .main-nav button.nav-link { width: 100%; justify-content: space-between; padding: 0.75rem 0.7rem; font-size: var(--fs-base); border-radius: var(--radius-sm); }
  .dropdown { position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: 0; border-left: 2px solid var(--line); border-radius: 0; margin: 0 0 0.3rem 0.85rem; padding: 0; display: none; min-width: 0; }
  .nav-item.open .dropdown { display: block; }
  .header-cta { margin: 0.85rem 0 0; width: 100%; text-align: center; }
  .theme-toggle { margin: 0.6rem 0 0; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  padding: 0.62rem 1.35rem; border-radius: 999px;
  font-family: inherit; font-size: var(--fs-sm); font-weight: 700; line-height: 1.2;
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  transition: transform 0.16s, box-shadow 0.16s, background 0.16s, border-color 0.16s, color 0.16s, filter 0.16s;
  white-space: nowrap;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--grad-brand); color: #fff; box-shadow: var(--glow); }
.btn-primary:hover { filter: brightness(1.08); }
.btn-accent { background: linear-gradient(135deg, #059669, #10b981); color: #fff; box-shadow: 0 6px 20px rgba(16, 185, 129, 0.35); }
.btn-accent:hover { filter: brightness(1.07); }
.btn-outline { background: transparent; color: var(--brand-600); border-color: var(--line-2); }
.btn-outline:hover { background: var(--brand-50); border-color: var(--brand-400); }
.btn-ghost { background: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-2); color: var(--brand-600); }
.btn-white { background: #fff; color: #3730a3; }
.btn-white:hover { filter: brightness(0.97); }
.btn-lg { padding: 0.9rem 1.85rem; font-size: var(--fs-base); }
.btn-sm { padding: 0.38rem 0.9rem; font-size: var(--fs-xs); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none !important; }

/* ---------- Hero (aurora mesh) ---------- */
.hero {
  background:
    radial-gradient(56rem 30rem at 78% -8%, rgba(124, 58, 237, 0.42), transparent 62%),
    radial-gradient(44rem 26rem at 6% 108%, rgba(34, 211, 238, 0.17), transparent 60%),
    radial-gradient(38rem 22rem at 38% 42%, rgba(79, 70, 229, 0.35), transparent 65%),
    linear-gradient(160deg, #0b1029 0%, #171e4b 58%, #232c6e 100%);
  color: var(--hero-ink); padding: 5.25rem 0 5.5rem; position: relative; overflow: hidden;
}
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.5;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(58rem 30rem at 55% 20%, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(58rem 30rem at 55% 20%, #000 30%, transparent 75%);
}
.hero::after {
  content: ""; position: absolute; pointer-events: none;
  width: 520px; height: 520px; right: -140px; top: -180px; border-radius: 50%;
  background: conic-gradient(from 130deg, rgba(139, 92, 246, 0.35), rgba(34, 211, 238, 0.18), rgba(79, 70, 229, 0.35), rgba(139, 92, 246, 0.35));
  filter: blur(70px); opacity: 0.7;
}
.hero .container { position: relative; z-index: 1; }
.hero h1 {
  color: #fff; font-size: clamp(2rem, 4.6vw, 3.3rem); max-width: 860px; font-weight: 800; letter-spacing: -0.035em;
}
.hero h1 .grad, .text-gradient { background: linear-gradient(110deg, #a5b4fc, #d8b4fe 55%, #67e8f9); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero .hero-sub { font-size: var(--fs-md); color: #b6c2e4; max-width: 680px; margin-bottom: 2rem; }
.hero .eyebrow { background: linear-gradient(110deg, #a5b4fc, #67e8f9); -webkit-background-clip: text; background-clip: text; color: transparent; }

.searchbar {
  display: flex; max-width: 700px;
  background: rgba(255, 255, 255, 0.97); border-radius: 999px;
  box-shadow: 0 22px 55px rgba(4, 8, 30, 0.5), 0 0 0 6px rgba(255, 255, 255, 0.07);
  overflow: hidden; padding: 0.35rem;
}
.searchbar input {
  flex: 1; border: 0; padding: 0.8rem 1.35rem; font-size: var(--fs-md); font-family: inherit; color: #0f172a; min-width: 0; background: transparent;
}
.searchbar input:focus { outline: none; box-shadow: none; }
/* THE SITE'S PRIMARY SEARCH FIELD HAD ZERO FOCUS INDICATOR.
   The rule above removes both, and .searchbar:focus-within (:1360) paints the SAME
   ring whether focus is on the input or on the Search button beside it, so the two
   adjacent tab stops were visually identical. The rings are inset because
   .searchbar sets overflow:hidden, which clips an outward ring to nothing.
   The bar is rgba(255,255,255,.97) in BOTH themes, so these are fixed colours
   rather than tokens: #4f46e5 on white is 6.29:1, #fff on the button's gradient
   is 6.29:1 at the indigo end and 5.38:1 at the purple end. */
.searchbar input:focus-visible { outline: 2px solid transparent; box-shadow: inset 0 0 0 3px #4f46e5; border-radius: 999px; }
.searchbar button:focus-visible { outline: 2px solid transparent; box-shadow: inset 0 0 0 3px #fff; }
.searchbar button {
  border: 0; background: var(--grad-brand); color: #fff; padding: 0 1.8rem;
  font-size: var(--fs-base); font-weight: 700; cursor: pointer; font-family: inherit;
  border-radius: 999px; transition: filter 0.16s;
}
.searchbar button:hover { filter: brightness(1.1); }
.hero-quicklinks { margin-top: 1.1rem; font-size: var(--fs-sm); color: #8d9cc4; }
.hero-quicklinks a { color: #c3cdf2; text-decoration: underline; text-underline-offset: 3px; }
.hero-quicklinks a:hover { color: #fff; }

/* ---------- Stat tiles ---------- */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; }
.stat-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.2rem 1.35rem; box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden;
}
.stat-tile::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--grad-brand); opacity: 0.85; }
.stat-tile .stat-value {
  font-size: 2rem; font-weight: 800; line-height: 1.1; letter-spacing: -0.03em;
  background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.stat-tile .stat-label { font-size: var(--fs-sm); color: var(--ink-2); margin-top: 0.3rem; }
.stat-tile .stat-delta { font-size: var(--fs-xs); font-weight: 700; color: var(--good-text); margin-top: 0.35rem; }
.hero .stat-tile { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.12); box-shadow: none; backdrop-filter: blur(6px); }
.hero .stat-tile::before { opacity: 1; background: linear-gradient(180deg, #818cf8, #22d3ee); }
.hero .stat-tile .stat-value { background: linear-gradient(110deg, #e0e7ff, #a5f3fc); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero .stat-tile .stat-label { color: #9fb0d8; }

/* EIGHT TILES INSTEAD OF FIVE, so they are smaller and each one is a link.
   A modifier rather than a change to .stat-row, because that class is also the stat
   row on authors.html, journals.html and the profile pages, and shrinking the type
   there would be a change nobody asked for made invisibly to five other pages.
   auto-fit does the wrapping: eight fit on one row at desktop width and fall to two
   rows when they cannot, without a breakpoint deciding it for them.
   tabular-nums keeps 6,866,068 and 126,410 the same width per digit, so the tiles
   stop jittering while the counters animate up to their values. */
/* FOUR AND FOUR, stated rather than discovered. auto-fit was here first and it fitted
   all eight on one row at 126px each -- but once the numbers had to be large, auto-fit
   started answering 5, or 6, and a row of five above a row of three looks like a
   mistake. An explicit column count is the only way to promise even rows, so the
   breakpoints say what they mean: four across on desktop, two on anything narrow.
   The tile stays SHORT even though it is now wide: the request was smaller tiles and
   then bigger numbers, and the way to have both is to spend the space on the digits
   and none of it on padding. */
.stat-row-compact { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.7rem; }
.stat-row-compact .stat-tile { padding: 0.7rem 0.8rem 0.75rem 1rem; }
.stat-row-compact .stat-tile .stat-value {
  /* Filled to the tile, and measured properly the second time. The first measurement
     compared scrollWidth against clientWidth, which on a block element are equal
     whenever the text fits -- it reports overflow, it does not report how wide the
     text is, and reading it as "exactly at the limit" made the number SMALLER on
     evidence that said nothing.
     Measured with a Range over the text node instead: at 41px the widest value,
     "6,866,068", is 187px inside a 250px box. 3.1rem puts it near 226px and leaves
     about 24px, which survives the article count gaining a digit.
     The FLOOR matters as much as the cap. At 2rem the two seven-digit values
     overflowed their box by 16px on a 375px phone, where the two-column tile leaves
     130px and 32px type needs 146px. 1.7rem needs about 124px and fits, and the vw
     term takes over the moment there is room for it.
     Then scaled down 20% on request, all three terms together so the reduction is the
     same at every width rather than only where the cap bites: 3.1 -> 2.48rem,
     3.9 -> 3.12vw, 1.7 -> 1.36rem. The floor had 6px of headroom at 375px and only
     gains by shrinking. */
  font-size: clamp(1.36rem, 3.12vw, 2.48rem);
  /* PROPORTIONAL once the counting stops, and this is a correction: the tile used
     tabular-nums in every state, and the owner read the result off the live page --
     104,664,791 did not start where "Articles" underneath it started, while
     30,780,981 did. Measured in the owner's own browser, where Inter is installed
     and the feature therefore applies: tabular figures give every digit the width of
     the widest, 26.82px at 40px, and a "1" is 19.23px of ink inside it. The 7.6px of
     padding falls on both sides, so a value beginning with 1 hangs about 4px in from
     the tile's left edge and a value beginning with 3 or 6 does not. Nothing is
     wrong with the CSS box: the text-align is the same in both tiles, and only the
     glyph moved.
     The equal widths are still worth having WHILE the number counts up, which is
     what they were added for -- eight digits changing at 60fps otherwise breathe.
     So app.js puts .counting on the node for those 900ms and takes it off at the
     end, and the number settles flush against the left edge of its tile. */
  font-variant-numeric: proportional-nums;
  line-height: 1.05;
}
.stat-row-compact .stat-tile .stat-value.counting { font-variant-numeric: tabular-nums; }
.stat-row-compact .stat-tile .stat-label { font-size: var(--fs-xs); margin-top: 0.1rem; line-height: 1.3; }

@media (max-width: 980px) { .stat-row-compact { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* The whole tile is the hit area, not the number inside it. A 126px card whose only
   clickable part is nine characters of text is a link people miss. */
a.stat-tile { display: block; text-decoration: none; color: inherit; }
a.stat-tile:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

/* HOVER COLOUR. The palette is not a new one: #818cf8 -> #22d3ee is the same indigo
   and cyan the tile's own left bar is painted with, so hovering brightens the accent
   the tile already has rather than introducing a colour the page has never used.
   On the hero the tiles sit on a dark gradient at 6% white, so the hover lifts that to
   a tinted 16% and pulls the label from grey-blue to near-white -- enough to read as
   "this is a link" at a glance, not enough to strobe when the cursor crosses a row of
   eight. The bar goes 3px -> 5px in the same motion, which is what makes it feel like
   one gesture instead of three separate effects. */
a.stat-tile { transition: background 0.18s ease, border-color 0.18s ease, transform 0.2s ease, box-shadow 0.2s ease; }
a.stat-tile::before { transition: width 0.18s ease, opacity 0.18s ease; }

.hero a.stat-tile:hover {
  background: rgba(129, 140, 248, 0.16);
  border-color: rgba(129, 140, 248, 0.55);
  box-shadow: 0 10px 26px rgba(34, 211, 238, 0.14);
}
.hero a.stat-tile:hover::before { width: 5px; }
.hero a.stat-tile:hover .stat-label { color: #dbe6ff; }
.hero a.stat-tile:hover .stat-value {
  background: linear-gradient(110deg, #ffffff, #67e8f9);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* The same gesture where the tiles sit on a light surface, e.g. any future stat row
   that is a link outside the hero. */
a.stat-tile:hover { border-color: var(--brand-400); background: var(--brand-50); }

@media (prefers-reduced-motion: reduce) {
  a.stat-tile, a.stat-tile::before { transition: none; }
}

/* ---------- Cards & grids ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.6rem; box-shadow: var(--shadow-sm);
}
.card h3 { margin-bottom: 0.4rem; }
.card-hover { transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; }
.card-hover:hover { box-shadow: var(--shadow-lg); transform: translateY(-4px); border-color: var(--brand-300); }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; }
/* A grid item's default min-width is auto, meaning "at least as wide as my content".
   So a <pre> or a wide table inside a column pushes the COLUMN wider instead of
   scrolling inside its own overflow-x:auto box, and the page gets a horizontal
   scrollbar. Measured on a 375px viewport: for-publishers.html overflowed the body
   by 284px, its badge column sitting at 626px because of the embed snippet.
   min-width: 0 lets the column shrink and hands the overflow back to the child,
   which is where it was already handled. */
.grid-2 > *, .grid-3 > *, .grid-4 > * { min-width: 0; }
@media (max-width: 960px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }
/* Asymmetric main+sidebar split. Set the ratio with --lead (e.g. style="--lead:1.6fr")
   rather than an inline grid-template-columns, which would override the collapse below
   and force two columns on phones. */
.grid-lead { grid-template-columns: var(--lead, 1.6fr) 1fr; align-items: start; }
@media (max-width: 620px) { .grid-lead { grid-template-columns: 1fr; } }

.icon-badge {
  width: 48px; height: 48px; border-radius: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--brand-50), var(--brand-100));
  border: 1px solid var(--brand-200);
  color: var(--brand-500); margin-bottom: 0.9rem; font-size: 1.35rem;
}
.icon-badge svg { width: 22px; height: 22px; }

/* ---------- Badges & chips ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: var(--fs-xs); font-weight: 700; line-height: 1;
  padding: 0.38em 0.8em; border-radius: 999px; white-space: nowrap;
}
/* An index badge that is a link says so: the arrow marks it as leaving the site, and the
   badge keeps its own colour rather than picking up link styling. */
a.badge { text-decoration: none; cursor: pointer; }
a.badge:hover { filter: brightness(1.08); text-decoration: none; }
.idx-out { font-size: 0.85em; opacity: 0.75; margin-left: 0.1em; }
.badge-oa { background: #ffedd5; color: #c2410c; }
html[data-theme="dark"] .badge-oa { background: #3a2410; color: #fdba74; }
/* Scopus. THE TWO ORANGES SWAPPED, 19 Eyl 2026, at the owner's reading of the row:
   the deeper orange goes to Scopus and the lighter one to ERIH PLUS. It reads better
   and it measures better — white on #EA5C0C is 3.48:1, against 3.01:1 on the #ee7023
   this chip carried since the wordmark ground was matched. The chip keeps white ink
   in both themes; only the ground moved, and the dark theme's border moved with it. */
.badge-scopus { background: #EA5C0C; color: #ffffff; border-color: #EA5C0C; font-weight: 700; }
html[data-theme="dark"] .badge-scopus { background: #EA5C0C; color: #ffffff; border-color: #b8490a; }
/* not covered: faint ghost, orange-tinted for recognition */
.idx-off.idx-off-scopus {
  background: rgba(255, 255, 255, 0.6); color: rgba(233, 113, 28, 0.55);
  border: 1px solid rgba(233, 113, 28, 0.22); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-scopus {
  background: rgba(255, 255, 255, 0.07); color: rgba(255, 170, 110, 0.5);
  border-color: rgba(255, 170, 110, 0.2);
}
/* Web of Science brand purple. Previously this badge reused .badge-seal — the
   CiteLink seal — which both misread the brand and implied CiteLink's own mark. */
.badge-wos { background: #582c83; color: #ffffff; border-color: #582c83; font-weight: 700; }
html[data-theme="dark"] .badge-wos { background: #582c83; color: #ffffff; border-color: #7c4bb0; }
/* not covered: faint ghost, purple-tinted for recognition */
.idx-off.idx-off-wos {
  background: rgba(255, 255, 255, 0.6); color: rgba(88, 44, 131, 0.55);
  border: 1px solid rgba(88, 44, 131, 0.22); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-wos {
  background: rgba(255, 255, 255, 0.07); color: rgba(186, 148, 224, 0.5);
  border-color: rgba(186, 148, 224, 0.2);
}
/* DOAJ brand: white wordmark on the charcoal ground of doaj.org */
.badge-doaj { background: #282422; color: #ffffff; border: 1.5px solid #282422; font-weight: 700; }
html[data-theme="dark"] .badge-doaj { background: #282422; color: #ffffff; border-color: #4a4442; }
/* not covered: faint white ghost of the DOAJ badge */
.idx-off.idx-off-doaj {
  background: rgba(255, 255, 255, 0.6); color: rgba(40, 36, 34, 0.42);
  border: 1px solid rgba(40, 36, 34, 0.14); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-doaj {
  background: rgba(255, 255, 255, 0.07); color: rgba(255, 255, 255, 0.45);
  border-color: rgba(255, 255, 255, 0.16);
}
.idx-off-doaj::before { opacity: 0.35; filter: grayscale(55%); }

/* DOAJ leaf mark (inline data-URI recreation of the three-petal logo) */
.idx-off-doaj::before,
.badge-doaj::before {
  content: ''; display: inline-block; width: 0.92em; height: 0.92em; flex: none;
  margin-right: 0.34em; vertical-align: -0.1em;
  background: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2092%2092'%3E%3Cpath%20fill='%23F5A08E'%20d='M2%2090V28A26%2026%200%200%201%2028%202h6v60A26%2026%200%200%201%208%2090Z'/%3E%3Cpath%20fill='%23EF5533'%20d='M30%2090V28A26%2026%200%200%201%2056%202h6v60A26%2026%200%200%201%2036%2090Z'/%3E%3Cpath%20fill='%239E2F10'%20d='M58%2090V28A26%2026%200%200%201%2084%202h6v60A26%2026%200%200%201%2064%2090Z'/%3E%3C/svg%3E") no-repeat center / contain;
}
/* PubMed brand: white wordmark + open-book mark on NLM navy */
.badge-pubmed { background: #17334f; color: #ffffff; border-color: #17334f; font-weight: 700; }
html[data-theme="dark"] .badge-pubmed { background: #17334f; color: #ffffff; border-color: #2c517a; }
/* the open book sits BEHIND the M of "Med", as in the original wordmark */
.pm-book { position: relative; display: inline-block; z-index: 0; padding: 0 0.04em; }
.pm-book::before {
  content: ''; position: absolute; z-index: -1;
  left: -18%; right: -18%; top: -22%; bottom: -8%;
  background: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2022'%3E%3Cpath%20fill='%23ffffff'%20d='M11%203C8.5%201.4%204.6%201.5%202.4%202.5c-.3.1-.4.3-.4.6v14.6c0%20.4.4.7.8.55%202-.8%205.6-.8%208.2%201V3z'/%3E%3Cpath%20fill='%23c9d3e0'%20d='M13%203c2.5-1.6%206.4-1.5%208.6-.5.3.1.4.3.4.6v14.6c0%20.4-.4.7-.8.55-2-.8-5.6-.8-8.2%201V3z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.badge-pubmed .pm-book { color: #17334f; } /* M reads dark against the white pages */
/* not covered: faint ghost, navy-tinted */
.idx-off.idx-off-pubmed {
  background: rgba(255, 255, 255, 0.6); color: rgba(23, 51, 79, 0.5);
  border: 1px solid rgba(23, 51, 79, 0.2); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-pubmed {
  background: rgba(255, 255, 255, 0.07); color: rgba(160, 190, 220, 0.5);
  border-color: rgba(160, 190, 220, 0.2);
}
.idx-off-pubmed .pm-book::before { opacity: 0.3; filter: grayscale(45%); }
.idx-off-pubmed .pm-book { color: inherit; }
/* PMC brand: navy wordmark + pediment mark on gray ground */
.badge-pmc { background: #e6e8ea; color: #205390; border: 1.5px solid #d0d5da; font-weight: 700; }
html[data-theme="dark"] .badge-pmc { background: #dfe3e7; color: #205390; border-color: #566068; }
.idx-off-pmc::before,
.badge-pmc::before {
  content: ''; display: inline-block; width: 0.92em; height: 0.8em; flex: none;
  margin-right: 0.3em; vertical-align: -0.06em;
  background: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2020'%3E%3Cpath%20fill='%23205390'%20d='M12%200.5%2023%208.5H1z'/%3E%3Crect%20x='1'%20y='10.5'%20width='22'%20height='3.2'%20fill='%23205390'/%3E%3Crect%20x='1'%20y='16'%20width='22'%20height='3.2'%20fill='%23205390'/%3E%3C/svg%3E") no-repeat center / contain;
}
/* not covered: faint ghost */
.idx-off.idx-off-pmc {
  background: rgba(255, 255, 255, 0.6); color: rgba(32, 83, 144, 0.5);
  border: 1px solid rgba(32, 83, 144, 0.18); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-pmc {
  background: rgba(255, 255, 255, 0.07); color: rgba(150, 185, 225, 0.5);
  border-color: rgba(150, 185, 225, 0.2);
}
.idx-off-pmc::before { opacity: 0.32; filter: grayscale(45%); }

/* EBSCO brand: white serif wordmark on their navy, taken from the logo they publish.
   Placed after PMC in the badge order, as asked.
   The badge exists before the data does, deliberately: it renders only when a journal
   carries EBSCO coverage, and nothing does yet, so it simply never shows. What is NOT
   here is an EBSCO filter checkbox. This repository already removed a "has a ROR
   identifier" control that matched 126,409 of 126,410 rows, on the grounds that a
   control which narrows nothing looks like a rigour setting and is not one; the same
   reasoning forbids one that narrows everything to zero. It goes in with the data. */
.badge-ebsco {
  background: #3b4a76; color: #ffffff; border-color: #3b4a76;
  font-family: Georgia, "Times New Roman", serif; font-weight: 700; letter-spacing: 0.04em;
}
html[data-theme="dark"] .badge-ebsco { background: #3b4a76; color: #ffffff; border-color: #5f709f; }
/* not covered: faint ghost, the same treatment its neighbours get */
.idx-off.idx-off-ebsco {
  background: rgba(255, 255, 255, 0.6); color: rgba(59, 74, 118, 0.5);
  border: 1px solid rgba(59, 74, 118, 0.2); opacity: 1;
  font-family: Georgia, "Times New Roman", serif; letter-spacing: 0.04em;
}
html[data-theme="dark"] .idx-off.idx-off-ebsco {
  background: rgba(255, 255, 255, 0.07); color: rgba(160, 175, 220, 0.5);
  border-color: rgba(160, 175, 220, 0.2);
}


/* ── TR Dizin and ERIC: the marks are the OWNER'S OWN FILES, not a redrawing ──
   Every other index mark in this stylesheet is a traced SVG, and that works
   because Scopus, WoS and EBSCO are wordmarks a colour reproduces and DOAJ and
   PMC have marks simple enough to draw. These two are neither: TR Dizin is a
   wordmark whose whole character is horizontal striping, and ERIC is a
   tree-and-wordmark lockup. Both were drawn first and neither read as itself.

   THE GROUND IS THE BRAND COLOUR, TINTED, AND THAT IS FORCED. Both logos are
   DARK ink -- ERIC's wordmark is #3F563C, TR Dizin's is #000000 and #E2232A --
   and neither publishes a light-on-dark variant. Set the pill to the solid
   brand colour and the logo disappears into it; recolouring the artwork to
   white would make it no longer their logo, which is the thing being avoided.
   So the pill carries the brand hue at a tint the original ink still reads
   against, with the full-strength colour on the border. .badge-pmc already
   works this way, for the same reason.

   TR DIZIN'S WHITE IS KNOCKED OUT. Its file is opaque white behind the letters
   AND between the stripes; dropped onto a tint unmodified it is a white box.
   The white is transparent here, so the ground shows through the stripes --
   which is how the mark is meant to sit on colour.

   WHY DATA URIs AND NOT FILES. The repository ships no binary assets at all,
   and 20-deploy-site.sh's publish set is an explicit allowlist of three
   directories. An assets/img would need adding there, an nginx cache rule of
   its own, and clearance through the cache-buster gate: three gates, days
   before a cutover, for two badges. Made cheap enough to inline instead --
   36 px tall (2x the 18 px they render at) and quantised to 24 colours, which
   is all flat brand artwork contains. Resampling ALONE made them bigger, since
   it turns three flat colours into thousands of shades; the quantise is what
   does the work. 15.5 kB of PNG becomes 2.2 kB.

   The accessible name comes from an .sr-only span in the markup: an image-only
   badge that announces nothing is not a badge. */
.badge-trdizin { background: #F7CFD1; border: 1.5px solid #E2232A; }
.badge-eric    { background: #D3E2CE; border: 1.5px solid #3F563C; }
html[data-theme="dark"] .badge-trdizin { background: #F3C4C6; border-color: #E2232A; }
html[data-theme="dark"] .badge-eric    { background: #CBDCC5; border-color: #55764F; }

.badge-trdizin::before,
.idx-off-trdizin::before,
.badge-eric::before,
.idx-off-eric::before {
  content: ''; display: inline-block; flex: none; height: 1.15em;
  background-repeat: no-repeat; background-position: center; background-size: contain;
}
/* width = each logo's own aspect ratio, so neither is stretched */
.badge-trdizin::before, .idx-off-trdizin::before { width: 3.07em; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAkCAMAAABBj89wAAAASFBMVEUAAADpJS31GSUfICDjLjTxYGMSDw/oSE61DxsiKCfmMThfXFzyl5nuREv9/PzjPEL3FmdwDAzkPEKuVVVcLzErVFTsO0K2REjTK0HCAAAAGHRSTlMA+AqonxfqZANnaBQQmANaEAakBqsQzrLMTYhfAAACn0lEQVR42u2W23ajMAxFZWFhYwgmSZv5/z8dSb5xS9qslceeh8YYqm3pyAaAP31WhJ5Opu+I9GakeZ4/uK5upSH/DH037J9DoBACHKcxBOKfZxpOAF3X93037iM5Y8wJwBpzAf8mQBAdeC76Ug1AAczoZZh1lzEDbjwc0asX5d7PgD4/4cuzDLAnS2SAa/kcNIo0pAyaLVKkEGMk9psXCuSKZtcEdUTikKTLlohwDVPA2tU+yagiycpupmiuI06oDm9SQEMcN11jtYXX/a2AGVICowIbQCqgVhaAfQ7gEh4AEvKLBduMBFAjcRu6Rx4/NoCc2ONxcelJNt3uANzgYlWEa95marx4wGOK+n8T8nSQ5VdXrYLT5Y3vuozk0k/7DFKJ4JurMwxD8bgHf80BTOTuUwDxMow0/qLRKBXP5l2SkvW0B1ybyasu1QmOO2nhM2CSUNwzc67HFnDRJ+EAgAYYSvh+qBWMaWEVIJK5IDE2gEmT3QMQ7v9YoB6Mrf51C5M20lIBvHBKxuAOMOta8ADIXXSte2KVAKSM4zoDr8OoITYAShf0xGTY7OPngLREA3jIYNI79Mpk2Wx5H4/lKHI7D6i16B6gPWenFyavitRlCzTc1AB3TcmmY3MPSIYddrK2TrmAUQokBLrKTgg5nNd9IGeyTS0qYXhabvt0mJdlHACDaPWOyNIMbD7EEqm0KDcjaJhUlHSYM4BwOgHs3u1Al6J87LDF7iK7yPCcRrBWjxy8lGmXADNB/AkAy91sFTanKazu4PY0ZUBugdcAdbEdmSRO334NSE38CsCEaLOCvG74NQyuzNjJNi2hjBzJLQaIzzzEcjifavNqffuzCn/1kJcu5z/ls2IpMx48NlGZlq8K3z4BEf++hP/0Gf0HoZIaacExzfEAAAAASUVORK5CYII="); }
.badge-eric::before,    .idx-off-eric::before    { width: 3.77em; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAkCAMAAABrPz7fAAAASFBMVEUBAQE+VTtGVTtSZkcpYClhZGFwkmf3+fU9VDo7UjlTMyFPWiyDqHaPtIixy6tBVzxAVjyVuY4A/wBhKCL///9blFu0tLRpml9bKsfdAAAAGHRSTlMA9fv9FQP+/qBc/Bf+/vVqo5IBHwEcA0Y55ZosAAAEx0lEQVR42r1X6XqjMAy0LdnxQYC02/b933Q18oFJ2qT7Z/W1wQcwHt0Yc0ixNjEbthTZePbmv4hPFMjZ5CgESve7xZ+F8cQ0Pl4DMfcrx+UsQi7REkKw8r8EGwunf+F7xp432vu/u01AfbQkEkhACfBE6biJ76SUeQ2z9v5SF2bQkqKFxMTHMfp7RcXBOhcE2mRBF9ZxbBpvz+KsMdEd07hxvVEXHY+3c7KOXBUxIW7zXfeGo6CJioVtcDa7AFiykTssW/cIS32iknBbXZSxr8Q2YE2PObcdR/IxLHIkWgBL8CmxLi6W+e01bF2hDQT2A1aeis7dq4maKjzjjIFUC46AqryVM/+GbV+D+x9sRYeOJprHMEERCb6TrKXgshi1mhfKJoIbQNMd1g2hAavTdhQ/w5rSofp+n1psRyEFtnIBrOpZrovA4wSI4QZb/5oPdQQbxxtBo8NKcFhqKHEr4uBw6L4CVQhDW/VKMC8O4K7BIYbEyDTD+jkeFaHupqqMeMByt4Hbj1CttiYn8fUmyZBgUlfpigKD/l2XehBbcLYKy9/DGpPcbHBl64Za4D7CFkkqwSiskYbkIGbNJBQFNoeQCfp1qmaJXuYXsOzH/oCtZCnOCcIXnAaezEYU7NSxxXUXMWpeQgZidnBv0THzCyWXb2BLV/tdfgYHzWFwKUG8EnKUqDjDmR14ykHIJjbmOVvznZJTdbJyBztyc9KYFc2K0kXRGQFLGsLIF2LeqpTZjWfvgTJ60p1dql7jY2mouLCsWDKrSqtHORxCIwk/y+HJU+DSKV20tHAEUDF6/2P97BLFYzU5ZYLnZriWUhet5+xqpvJPstTIFrBB07z4ar2fzQ/FE1ErTEFY7am4QdOVgIrN5cT+V8mxWn6GPfnCWZKmIfVZ2NYpLCInw7GD6tg/KPkRVlM8d08u/AJW0jWKYoSN3fu7AazQdMbApWpufMq2r0cERoflBlvMn59wUz1SSnWQsynRJlWETSmeAqh08cOMR/VpyWe2bTJPG6PeXXn/LrDm88P496kBeRq3DZ3ZmKnMx+bJP8K2jY82zfm9Dj690ar5CpZ79fEnWGqmeNbreTEBf5nbzXzkvOH6xRX4NdvWPtlyYptGKXwgOV7yKWRv6wWy5twGt48pszyDTQfdA7b1BfeRyyaNfClUb+bSxOU+Mjf+Feyg+8YPFeicHr0m73GSr/UyRFxqjNevGgAvYIvSlRZuYitPqNCuLWr7JJA6397yR6YT6nWGvazyyNscQBI4kCOA1Fmb/5SphdP4Gx1bLzuavKnWz3g9cC7IF9M0pBedo8L6mvjjzNb7vePie4B523oTR1E7x8sTIe0bf06OqE++G1Ka6tE5TuWjtuijUUfnKPmkkl2vi4iOMbpeq+av0b9ii+bDNbpTw8pznzwJ1ZIRFHQJgJJfUWzASGRtatac/MM3kFZj3w3ZvoG06wPy/vhVgE4S7SpAg/YRaJGXdV36OAQBXvXLQNpLN0st8xho58hF94VuXdx6jCSsz2WqJW8b1ivai74B/DER7OuK1lE9/yQRIRhtrEnR6wR067WH5ptUmt2iI67dQES4YcMqSNzjvu/btkkFjCnJQKZ7bfgp/svX9TdzTmmP+t7xffsXSzwwQ64oy0EAAAAASUVORK5CYII="); }

/* NOT COVERED: the logo stays, faded -- the same faint treatment the other
   seven indexes get in the coverage strip, so a reader scanning the row sees
   the same eight marks on every journal and only their strength changes. */
.idx-off.idx-off-trdizin { background: rgba(226, 35, 42, 0.05); border: 1px solid rgba(226, 35, 42, 0.22); opacity: 1; }
.idx-off.idx-off-eric    { background: rgba(63, 86, 60, 0.05);  border: 1px solid rgba(63, 86, 60, 0.22);  opacity: 1; }
html[data-theme="dark"] .idx-off.idx-off-trdizin { background: rgba(226, 35, 42, 0.10); border-color: rgba(226, 35, 42, 0.3); }
html[data-theme="dark"] .idx-off.idx-off-eric    { background: rgba(120, 160, 115, 0.10); border-color: rgba(120, 160, 115, 0.3); }
.idx-off-trdizin::before, .idx-off-eric::before { opacity: 0.32; filter: grayscale(75%); }

/* ERIH PLUS. 1.15em tall like the other two; 1.15 x 139/44 = 3.63em wide, the
   artboard's own ratio, so it is not stretched. The word in the markup is an
   .sr-only span, so the accessible name and a copy-paste both still say
   "ERIH PLUS" while the eye gets the mark.

   @supports is not decoration. Without mask support the ::before would paint a
   solid 3.63em block of currentColor -- a coloured bar where a logo should be,
   which is worse than the word it replaced. So the mark only exists where the
   mask does, and everywhere else .erih-word shows and the chip reads as it did
   before this change. */
@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .badge-erihplus .erih-word,
  .idx-off-erihplus .erih-word {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .badge-erihplus::before,
  .idx-off-erihplus::before {
    content: ''; display: inline-block; flex: none;
    height: 1.15em; width: 3.63em; background-color: currentColor;
    -webkit-mask: var(--erih-mark) no-repeat center / contain;
            mask: var(--erih-mark) no-repeat center / contain;
  }
}

/* Library heart + auth chip */
.lib-btn {
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-3);
  border-radius: 999px; width: 36px; height: 36px; flex: none; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: color 0.15s, border-color 0.15s, transform 0.15s, background 0.15s;
}
.lib-btn .heart-ic { width: 20px; height: 20px; display: block; }
.lib-btn .heart-ic path { fill: none; stroke: currentColor; stroke-width: 2; transition: fill 0.15s, stroke 0.15s; }
.lib-btn:hover { color: #e11d48; border-color: #fda4af; transform: scale(1.12); }
.lib-btn.lib-saved { color: #e11d48; border-color: #fda4af; background: #fff1f2; }
.lib-btn.lib-saved .heart-ic path { fill: #e11d48; stroke: #e11d48; }
/* the heart kept its light-theme #e11d48 on this background: 3.39:1, under the
   3:1 SC 1.4.11 asks of a control that carries state. --critical is #fb7185 in
   dark, which is 5.92:1 on it. */
html[data-theme="dark"] .lib-btn.lib-saved { background: #3a1622; color: var(--critical); }
html[data-theme="dark"] .lib-btn.lib-saved .heart-ic path { fill: var(--critical); stroke: var(--critical); }
/* C1-C4 quartile badges (approved naming — never "Q") */
.q-badge {
  display: inline-block; min-width: 2.4em; text-align: center;
  padding: 0.18em 0.5em; border-radius: 7px; font-weight: 800; font-size: 0.82rem;
  color: #fff; letter-spacing: 0.02em;
}
.q-C1 { background: #15803d; }
.q-C2 { background: #0e7490; }
.q-C3 { background: #b45309; }
.q-C4 { background: #6b7280; }
.q-NA { background: transparent; color: var(--ink-3); border: 1px dashed var(--line-2); }

/* right column of a journal card: metric pill + visit-website link */
.jc-right { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; flex: none; }
.jc-visit { font-size: var(--fs-xs); white-space: nowrap; color: var(--brand-600); text-decoration: none; }
.jc-visit:hover { text-decoration: underline; }

/* compact heart for table rows (organizations list) */
.lib-btn.lib-btn-sm { width: 30px; height: 30px; vertical-align: middle; margin-left: 4px; }
.lib-btn.lib-btn-sm .heart-ic { width: 17px; height: 17px; }
.auth-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--grad-brand); color: #fff; font-weight: 800; font-size: 0.9rem;
}
.auth-chip { padding: 0.3rem !important; border-radius: 50% !important; }
.badge-brand { background: var(--brand-100); color: var(--brand-700); }
.badge-neutral { background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line); }
.badge-seal { background: linear-gradient(135deg, #171e4b, #3730a3); color: #fde68a; box-shadow: 0 3px 10px rgba(23, 30, 75, 0.3); }
.badge-good { background: var(--good-bg); color: var(--good-text); }
.badge-warn { background: var(--warn-bg); color: #b45309; }
.badge-crit { background: var(--critical-bg); color: var(--critical); }
html[data-theme="dark"] .badge-warn { color: #fbbf24; }
/* Chips and badges sit side by side all over this site and used to render at different
   heights -- 29px against 23px in the profile header. The cause was not the padding, which
   was nearly identical, but a missing line-height: .badge sets it to 1 and .chip inherited
   the body's 1.6, so the text box inside the chip was half a line taller. line-height: 1
   here, with the vertical padding nudged to absorb the chip's 1px border, makes the two
   the same height wherever they meet. */
.chip {
  display: inline-flex; align-items: center; font-size: var(--fs-xs); font-weight: 600;
  line-height: 1;
  background: var(--brand-50); color: var(--brand-700);
  border: 1px solid var(--brand-100); border-radius: 999px; padding: 0.32em 0.8em; white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
a.chip:hover { background: var(--brand-100); border-color: var(--brand-300); text-decoration: none; }

/* ---------- Journal cards / list ---------- */
.journal-card { display: flex; flex-direction: column; gap: 0.5rem; }
[data-card-href] { cursor: pointer; }
.journal-card .jc-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.9rem; }
.journal-card h3 { font-size: var(--fs-md); margin: 0; }
.journal-card .jc-title { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.journal-card h3 a {
  color: var(--ink);
  background-image: linear-gradient(90deg, #7c3aed, #22d3ee);
  background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 2.5px;
  transition: color 0.18s ease, background-size 0.25s ease;
  padding-bottom: 2px;
}
.journal-card h3 a:hover { color: #7c3aed; text-decoration: none; background-size: 100% 2.5px; }
html[data-theme="dark"] .journal-card h3 a:hover { color: #a78bfa; }
.journal-card .jc-meta { font-size: var(--fs-sm); color: var(--ink-2); }
.journal-card .jc-meta strong { color: var(--ink); font-weight: 600; }
.journal-card .jc-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.2rem; }
/* Profile header: each badge row is its own flex line, so a break never moves a badge
   between groups that mean different things. See journal.html for why. */
.jc-chips .jc-chip-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.jc-chips .jc-chip-row + .jc-chip-row { margin-top: 0.35rem; }
.clv-pill {
  flex: none; text-align: center;
  background: linear-gradient(135deg, var(--brand-50), var(--brand-100));
  border: 1px solid var(--brand-200);
  border-radius: 12px; padding: 0.4rem 0.75rem; min-width: 78px;
}
.clv-pill .clv-num {
  display: block; font-size: 1.2rem; font-weight: 800; line-height: 1.1;
  background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.clv-pill .clv-cap { display: block; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.07em; color: var(--ink-3); text-transform: uppercase; }

/* ---------- Filters layout (browse pages) ---------- */
.browse-layout { display: grid; grid-template-columns: 272px 1fr; gap: 2rem; align-items: start; }
/* A GRID ITEM WILL NOT SHRINK BELOW ITS CONTENT WITHOUT THIS.

   min-width: auto is the default for a grid item, so the 1fr track was floored at the
   min-content width of the widest card. Measured on journals.html at 375x812:
   clientWidth 375, scrollWidth 446 -- 71 px of sideways scroll, with the Per-page
   control and all 97 facet counts off the right edge. The floor was a single .chip
   with white-space: nowrap reading "Biochemistry, Genetics and Molecular Biology 39%
   of its output" at 370 px, inside a 423 px card.

   min-width: 0 lets the track shrink; the chip is allowed to wrap on narrow screens
   rather than setting the width of the page. Both are needed -- either alone leaves
   the overflow. */
.browse-layout > * { min-width: 0; }
@media (max-width: 900px) { .browse-layout { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .chip { white-space: normal; } }
/* THE FOOTER WAS PAINTING OVER THE FILTER COLUMN, and nothing in either rule said so.
   .filters is sticky and .site-footer is relative, and NEITHER declared a z-index --
   two positioned elements at the same level paint in DOM order, so the footer, being
   later in the document, won every overlap. It shows up when the sidebar outruns the
   results column, which is exactly when there are few results and the reader is most
   likely to be reaching for the sort control at the bottom of it.

   10 is deliberate on both sides: above the footer band and the CTA band, which sit at
   the default 0, and below the site header at 50 -- a sticky sidebar that could slide
   over the header while scrolling would be a worse bug than the one being fixed.

   This does not govern an open <select> list. That popup is drawn by the browser above
   the page and no stylesheet can reorder it; what this fixes is the card it belongs
   to, and everything else in the column, including the .fh-pop hint panels. */
.filters { position: sticky; top: calc(var(--header-h) + 1rem); z-index: 10; }
.filter-group { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.05rem 1.15rem; margin-bottom: 1rem; box-shadow: var(--shadow-sm); }

/* THE FILTER COLUMN, ON A PHONE ─ 19 Eyl 2026 ────────────────────────────────
   Below 900px .browse-layout is one column and the aside comes first, so the
   filters ARE the page: measured at 375px on journals.html, the column is
   4,772px tall and the first result card starts at y=5,474. The sticky
   positioning above was written for a sidebar beside a list; in one column it
   made the same block ride over the results as well. So below 900px the column
   stops being sticky, and everything after the first group — the search box —
   folds behind the button app.js inserts after it.
   The button is display:none above 900px: on a desktop the column is a column,
   the collapsed class hides nothing, and the markup is identical. */
.filters-more {
  display: none; width: 100%; justify-content: center; gap: 0.4rem;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  border-radius: var(--radius); padding: 0.7rem 1rem; margin: -0.35rem 0 1rem;
  font: inherit; font-size: var(--fs-sm); font-weight: 700; cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.filters-more:hover { border-color: var(--brand-400); color: var(--brand-600); }
.filters-more:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
@media (max-width: 900px) {
  .filters { position: static; z-index: auto; }
  .filters-more { display: flex; }
  .filters.fl-collapsed > .filter-group ~ .filter-group,
  .filters.fl-collapsed > .btn { display: none; }
}
.filter-group h4 { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.09em; color: var(--ink-3); margin-bottom: 0.65rem; position: relative; }

/* FILTER HINTS — the explanation moved out from under the control and behind the
   heading. Six of these panels carried a paragraph of prose below their input; the
   discipline filter alone ran to eleven lines in a 270px column, so the sidebar read
   as an essay with inputs buried in it and the controls below it were pushed off the
   screen. What those paragraphs say is not decoration -- a coverage percentage, a
   known timeout, a caveat about names being text and not people -- so none of it is
   deleted. It moves behind a marker on the heading and comes back on hover.

   Hidden with opacity rather than visibility or display, deliberately.
   visibility:hidden removes an element from the accessibility tree, and these panels
   ARE the text the marker points at with aria-describedby; hiding them that way would
   leave a screen reader announcing a control whose description resolves to nothing.
   Nothing inside is focusable, so keeping them in the tree costs no tab stop, and
   pointer-events:none stops an invisible box from eating clicks meant for the card.

   :focus-within is what makes this work without a mouse. Tab reaches the marker and
   the panel opens; Escape is not needed because moving focus away closes it. On touch
   a tap focuses the button, which is the same state -- so this is not hover-only. */
/* The marker rides INSIDE the heading text as an inline box; it does not turn the
   heading into a flex container. journals.html already makes its own facet headings
   flex to push an "exclude" switch to the right, and `.filter-group h4` outranks
   `.facet-head` on specificity -- a display rule here would have quietly reflowed
   every facet heading on that page while looking like it only touched this one. */
.fh { display: inline-flex; margin-left: 0.35rem; vertical-align: -1px; }
.fh-btn {
  width: 15px; height: 15px; padding: 0; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-3);
  font: italic 700 10px/1 Georgia, serif; letter-spacing: 0; cursor: help;
  text-transform: none;   /* the heading is uppercased; the marker must stay a lowercase i */
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.fh-btn::before { content: "i"; }
.fh:hover .fh-btn, .fh-btn:focus-visible { border-color: var(--brand-600); color: var(--brand-600); }
/* Anchored to the HEADING, not to the marker. Anchoring it to the marker and giving
   it a fixed width put its right edge at 529px on a 375px viewport -- measured, not
   guessed -- because a marker sitting near the right of the card has no room to its
   right and `max-width` cannot move a box, only shrink one. The heading spans the
   card, so a panel stretched left:0 right:0 across it is the card's width by
   construction and cannot leave the screen at any viewport. */
.fh-pop {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 40;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.7rem 0.8rem;
  font: 400 var(--fs-xs)/1.5 var(--font);
  text-transform: none; letter-spacing: normal; text-align: left;
  opacity: 0; pointer-events: none; transition: opacity 0.12s ease;
}
.fh-pop strong { font-weight: 600; color: var(--ink); }
.fh:hover .fh-pop, .fh:focus-within .fh-pop { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .fh-pop { transition: none; } }
.filter-option { display: flex; align-items: center; gap: 0.55rem; padding: 0.24rem 0; font-size: var(--fs-sm); color: var(--ink-2); cursor: pointer; border-radius: 6px; }
.filter-option:hover { color: var(--ink); }
.filter-option input { accent-color: var(--brand-500); width: 15px; height: 15px; flex: none; }
.filter-option .count { margin-left: auto; color: var(--ink-3); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.browse-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-bottom: 1.2rem; }
.browse-toolbar .result-count { font-size: var(--fs-sm); color: var(--ink-2); margin-right: auto; }
.browse-toolbar select, .input, select.input {
  font-family: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding: 0.55rem 0.8rem; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.browse-toolbar select:focus, .input:focus { border-color: var(--brand-400); box-shadow: 0 0 0 3px var(--ring); outline: none; }
.journal-list { display: flex; flex-direction: column; gap: 0.9rem; }

input[type="range"] { accent-color: var(--brand-500); }

/* ---------- Pagination ---------- */
.pagination { display: flex; gap: 0.35rem; justify-content: center; margin-top: 1.9rem; flex-wrap: wrap; }
.pagination button {
  min-width: 40px; padding: 0.5rem 0.65rem; border: 1px solid var(--line); background: var(--surface);
  border-radius: 10px; font-family: inherit; font-size: var(--fs-sm); font-weight: 600; color: var(--ink-2); cursor: pointer;
  transition: border-color 0.14s, color 0.14s, transform 0.14s;
}
.pagination button:hover { border-color: var(--brand-400); color: var(--brand-500); transform: translateY(-1px); }
.pagination button.current { background: var(--grad-brand); border-color: transparent; color: #fff; box-shadow: var(--glow); }
.pagination button[disabled] { opacity: 0.4; cursor: default; transform: none; }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
/* The wrapper scrolls, but only if it is allowed to be narrower than its table.
   Inside any grid or flex parent it is not, unless min-width is pinned to 0 --
   the default of `auto` means "at least as wide as my content", which is the
   table. rankings.html overflowed the body by 4px for exactly this reason. */
.table-wrap { min-width: 0; max-width: 100%; }
table.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td { padding: 0.75rem 0.95rem; text-align: left; border-bottom: 1px solid var(--line); }
.table th { background: var(--surface-2); color: var(--ink-3); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap; position: sticky; top: 0; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background 0.12s; }
.table tbody tr:hover { background: var(--brand-50); }
.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.table th.sortable { cursor: pointer; user-select: none; }
.table th.sortable:hover { color: var(--brand-500); }
.table th.sortable::after { content: " ↕"; opacity: 0.45; }
/* THE SORT CONTROLS WERE NOT CONTROLS. Three of the eight headers on
   rankings.html re-sorted the table on click and were reachable by mouse only:
   no tabindex, no button, no link, and aria-sort null before and after sorting.
   They carry a real <button> now; these rules make it occupy the cell and inherit
   everything the <th> was painting, so the header looks exactly as it did. The
   affordance glyph moves onto the button so it stays on the same line. */
.table th.sortable:has(> .th-sort)::after { content: none; }
/* the cell's padding moves onto the button so the whole header stays the click
   target it was before -- otherwise the mouse target shrinks from 78x44 to 47x20 */
.table th.sortable:has(> .th-sort) { padding: 0; }
.table th.sortable > .th-sort {
  display: block; width: 100%;
  font: inherit; color: inherit; text-align: inherit;
  letter-spacing: inherit; text-transform: inherit; white-space: inherit;
  background: none; border: 0; margin: 0; cursor: pointer;
  padding: 0.75rem 0.95rem;
}
.table th.sortable > .th-sort::after { content: " ↕"; opacity: 0.45; }
.table th.sortable[aria-sort="ascending"] > .th-sort::after,
.table th.sortable[aria-sort="descending"] > .th-sort::after { content: none; }
.table th.sorted-asc::after { content: " ↑"; opacity: 1; }
.table th.sorted-desc::after { content: " ↓"; opacity: 1; }
.rank-cell {
  font-weight: 800; font-variant-numeric: tabular-nums;
  background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- Journal profile ---------- */
.profile-head { background: var(--surface); border-bottom: 1px solid var(--line); padding: 2.4rem 0 0; position: relative; overflow: hidden; }
.profile-head::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.6;
  background: radial-gradient(40rem 14rem at 85% -30%, rgba(124, 58, 237, 0.12), transparent 70%);
}
.profile-title-row { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; position: relative; }
.profile-title-row h1 { font-size: clamp(1.5rem, 3vw, 2.15rem); margin-bottom: 0.35rem; flex: 1; min-width: 260px; }
.profile-sub { color: var(--ink-2); font-size: var(--fs-sm); display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; }
.profile-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; position: relative; }
.clv-dial {
  text-align: center;
  background: linear-gradient(135deg, var(--brand-50), var(--brand-100));
  border: 1px solid var(--brand-200); border-radius: var(--radius-lg); padding: 0.95rem 1.5rem;
  box-shadow: var(--shadow-sm);
}
.clv-dial .clv-num {
  font-size: 2.15rem; font-weight: 800; line-height: 1.05;
  background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.clv-dial .clv-cap { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; }
.tabs { display: flex; gap: 0.25rem; margin-top: 1.6rem; overflow-x: auto; position: relative; }
.tabs button {
  border: 0; background: none; font-family: inherit; font-size: var(--fs-sm); font-weight: 700;
  color: var(--ink-2); padding: 0.75rem 1.05rem; cursor: pointer; border-bottom: 3px solid transparent; white-space: nowrap;
  transition: color 0.15s;
}
.tabs button:hover { color: var(--brand-500); }
.tabs button.active { color: var(--brand-500); border-image: var(--grad-brand) 1; border-bottom: 3px solid; }
.tab-panel { display: none; padding: 2.2rem 0; }
.tab-panel.active { display: block; animation: fadeUp 0.35s ease; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.meta-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 0.95rem 1.5rem; }

/* THE RECORD CARD, 19 Eyl 2026. It used .meta-grid, which is an auto-fill grid of
   230px columns -- right for a wide page, wrong inside the narrow right-hand column
   of the article page, where it collapses to ONE column and gives every <dt> and
   every <dd> a row of its own. Seven facts became fourteen rows with 0.95rem
   between them, and the card ran 460px past the metric card beside it while its
   own right half stayed empty. Label and value belong on one line here: the labels
   are short, the values are short, and the pair is what the reader is scanning.
   max-content for the label column, so it is as wide as the longest label and not a
   pixel more. */
.rec-rows {
  display: grid; grid-template-columns: max-content 1fr;
  gap: 0.45rem 1rem; align-items: baseline; margin: 0;
}
/* One size for the whole card, and it is the size of the prose in the card beside
   it (--fs-sm, the .text-small the metric card's explanation uses). The label is
   separated from the value by weight and colour rather than by being smaller:
   shrinking it was what made the pair read as two rows in the first place. */
.rec-rows dt { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3); white-space: nowrap; }
.rec-rows dd { margin: 0; font-size: var(--fs-sm); color: var(--ink); font-weight: 500; overflow-wrap: anywhere; }
@media (max-width: 420px) {
  /* Under ~420px "Research field" plus a value no longer fit on one line, and a
     max-content column would push the value into a two-character ribbon. Stack. */
  .rec-rows { grid-template-columns: 1fr; gap: 0.15rem; }
  .rec-rows dd { margin-bottom: 0.5rem; }
}
.meta-item { border-left: 3px solid; border-image: linear-gradient(180deg, var(--brand-400), var(--violet-500)) 1; padding-left: 0.9rem; }
.meta-item dt { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); }
.meta-item dd { margin: 0.12rem 0 0; font-size: var(--fs-sm); color: var(--ink); font-weight: 500; overflow-wrap: anywhere; }

.checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.55rem; }
.checklist li { display: flex; gap: 0.6rem; align-items: flex-start; font-size: var(--fs-sm); color: var(--ink-2); }
.checklist .ok, .checklist .no { flex: none; width: 21px; height: 21px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 0.7rem; font-weight: 800; margin-top: 1px; }
.checklist .ok { background: var(--good-bg); color: var(--good-text); }
.checklist .no { background: var(--critical-bg); color: var(--critical); }

/* The share beside a field chip. It is deliberately quiet at high values and
   deliberately not quiet at low ones: a journal whose field assignment rests on
   34% of its output is making a weaker claim than one at 96%, and the design
   should not flatten that difference into the same grey. */
.chip-share { margin-left: 0.4em; opacity: 0.75; font-variant-numeric: tabular-nums; }
.chip-share-low { opacity: 1; color: #8f6620; font-weight: 600; }
/* #8f6620 is 4.59:1 on the light --brand-50 and 3.08:1 on the dark one — the rule
   had no dark counterpart at all. Same amber family, lifted: 3.08 -> 6.51. */
html[data-theme="dark"] .chip-share-low { color: #d99a3d; }

.score-bars { display: grid; gap: 0.85rem; }
.score-bar-row { display: grid; grid-template-columns: 210px 1fr 54px; gap: 0.95rem; align-items: center; font-size: var(--fs-sm); }
@media (max-width: 620px) { .score-bar-row { grid-template-columns: 1fr; gap: 0.25rem; } }
.score-bar-row .sb-label { color: var(--ink-2); font-weight: 600; }
.score-track { height: 10px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.score-fill { height: 100%; background: var(--grad-brand); border-radius: 999px; transition: width 0.6s cubic-bezier(0.2, 0.7, 0.3, 1); }
.score-bar-row .sb-val { text-align: right; font-weight: 700; color: var(--brand-600); font-variant-numeric: tabular-nums; }

/* ---------- Timeline / process steps ---------- */
.steps { counter-reset: step; display: grid; gap: 0; position: relative; }
.step { position: relative; padding: 0 0 2rem 3.55rem; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--grad-brand); color: #fff; font-weight: 800; font-size: var(--fs-md);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--glow);
}
.step::after { content: ""; position: absolute; left: 20.5px; top: 46px; bottom: 4px; width: 2px; background: linear-gradient(180deg, var(--brand-200), transparent); }
.step:last-child { padding-bottom: 0; }
.step:last-child::after { display: none; }
.step h3 { font-size: var(--fs-md); margin-bottom: 0.25rem; }
.step p { color: var(--ink-2); font-size: var(--fs-sm); margin-bottom: 0; }
.step .step-note { font-size: var(--fs-xs); color: var(--brand-500); font-weight: 700; }

/* ---------- Forms & wizard ---------- */
.form-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 2.2rem; box-shadow: var(--shadow); }
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.05rem 1.3rem; }
.form-grid .full { grid-column: 1 / -1; }
@media (max-width: 620px) { .form-grid { grid-template-columns: 1fr; } }
.field label { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--ink); margin-bottom: 0.32rem; }
.field label .req { color: var(--critical); }
.field .hint { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 0.28rem; }
/* type="search" was missing from this list, so a search box inside a .field got
   none of it: no border, no padding, no width -- it fell back to the browser's
   default size attribute, 20 characters, and sat there at 203px while its own
   placeholder needed 383px to be read. Five inputs were affected (faq.html,
   rankings.html, three in panel.html); the rest of the site had been working
   around it with an inline style="width:100%" on every single search input,
   which is what a missing rule looks like from the outside. */
.field input[type="text"], .field input[type="url"], .field input[type="email"], .field input[type="number"], .field input[type="date"], .field input[type="search"],
.field select, .field textarea {
  width: 100%; font-family: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding: 0.65rem 0.85rem; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.field textarea { resize: vertical; min-height: 100px; }
/* The FAQ search box at twice the width it had, per the owner. Full card width
   (880px) would be four times it and would look like a form field rather than a
   search box; 26rem clears the 383px the placeholder needs with room to spare,
   and the width:100% above still lets it shrink on a narrow screen. */
#faq-search { max-width: 26rem; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--brand-400); box-shadow: 0 0 0 3px var(--ring); outline: none; }
.field.invalid input, .field.invalid select, .field.invalid textarea { border-color: var(--critical); }
.field .error-msg { display: none; font-size: var(--fs-xs); color: var(--critical); font-weight: 600; margin-top: 0.28rem; }
.field.invalid .error-msg { display: block; }
.check-row { display: flex; gap: 0.6rem; align-items: flex-start; font-size: var(--fs-sm); color: var(--ink-2); padding: 0.32rem 0; }
.check-row input { accent-color: var(--brand-500); width: 16px; height: 16px; margin-top: 3px; flex: none; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 1.15rem 1.3rem 1.3rem; margin: 0 0 1.3rem; }
legend { font-weight: 700; font-size: var(--fs-sm); color: var(--brand-600); padding: 0 0.5rem; }

.wizard-progress { display: flex; gap: 0; margin-bottom: 2.2rem; overflow-x: auto; }
.wizard-progress .wp-step { flex: 1; min-width: 112px; text-align: center; position: relative; padding-top: 32px; font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); }
.wizard-progress .wp-step::before {
  content: attr(data-n); position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 26px; height: 26px; border-radius: 50%; background: var(--surface-2); color: var(--ink-3);
  border: 1px solid var(--line);
  font-size: var(--fs-xs); display: flex; align-items: center; justify-content: center; z-index: 1;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
}
.wizard-progress .wp-step::after { content: ""; position: absolute; top: 12px; left: calc(-50% + 13px); right: calc(50% + 13px); height: 2px; background: var(--line); }
.wizard-progress .wp-step:first-child::after { display: none; }
.wizard-progress .wp-step.done::before { background: var(--accent-500); border-color: transparent; color: #fff; content: "✓"; }
.wizard-progress .wp-step.done { color: var(--accent-600); }
.wizard-progress .wp-step.current::before { background: var(--grad-brand); border-color: transparent; color: #fff; box-shadow: var(--glow); }
.wizard-progress .wp-step.current { color: var(--brand-500); }
.wizard-progress .wp-step.done::after, .wizard-progress .wp-step.current::after { background: var(--brand-300); }
.wizard-step { display: none; }
.wizard-step.active { display: block; animation: fadeUp 0.3s ease; }
.wizard-nav { display: flex; justify-content: space-between; margin-top: 1.9rem; gap: 1rem; }

.notice { border-radius: var(--radius); padding: 0.95rem 1.15rem; font-size: var(--fs-sm); margin-bottom: 1.3rem; border: 1px solid; }
.notice-info { background: var(--brand-50); border-color: var(--brand-100); color: var(--ink-2); }
.notice-info strong, .notice-info a { color: var(--brand-600); }
.notice-good { background: var(--good-bg); border-color: transparent; color: var(--good-text); }
.notice-warn { background: var(--warn-bg); border-color: transparent; color: #92610a; }
.notice-crit { background: var(--critical-bg); border-color: transparent; color: var(--critical); }
html[data-theme="dark"] .notice-warn { color: #fcd34d; }

/* ---------- Accordion (FAQ) ---------- */
.accordion { border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden; box-shadow: var(--shadow-sm); }
.accordion details { border-bottom: 1px solid var(--line); }
.accordion details:last-child { border-bottom: 0; }
.accordion summary {
  cursor: pointer; padding: 1.05rem 1.35rem; font-weight: 700; color: var(--ink); font-size: var(--fs-base);
  list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  transition: background 0.14s, color 0.14s;
}
.accordion summary:hover { background: var(--brand-50); }
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after { content: "+"; font-size: 1.35rem; color: var(--brand-400); font-weight: 400; flex: none; transition: transform 0.2s; }
.accordion details[open] summary::after { content: "+"; transform: rotate(45deg); }
.accordion details[open] summary { color: var(--brand-500); }
.accordion .acc-body { padding: 0 1.35rem 1.2rem; color: var(--ink-2); font-size: var(--fs-sm); }

/* ---------- Breadcrumbs ---------- */
.breadcrumbs { font-size: var(--fs-xs); color: var(--ink-3); margin: 1.35rem 0; }
.breadcrumbs a { color: var(--ink-3); }
.breadcrumbs a:hover { color: var(--brand-500); }
.breadcrumbs .sep { margin: 0 0.45rem; opacity: 0.6; }

/* ---------- Page hero (inner pages) ---------- */
.page-hero {
  background:
    radial-gradient(42rem 18rem at 82% -20%, rgba(124, 58, 237, 0.4), transparent 62%),
    radial-gradient(30rem 16rem at 12% 130%, rgba(34, 211, 238, 0.15), transparent 60%),
    linear-gradient(155deg, #0b1029 0%, #171e4b 65%, #232c6e 100%);
  color: var(--hero-ink); padding: 3.1rem 0; position: relative; overflow: hidden;
}
.page-hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.4;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 40px 40px;
  mask-image: radial-gradient(50rem 20rem at 60% 0%, #000 25%, transparent 75%);
  -webkit-mask-image: radial-gradient(50rem 20rem at 60% 0%, #000 25%, transparent 75%);
}
.page-hero .container { position: relative; }
.page-hero h1 { color: #fff; font-size: clamp(1.65rem, 3.4vw, 2.4rem); margin-bottom: 0.45rem; letter-spacing: -0.03em; }
.page-hero p { color: #b6c2e4; max-width: 740px; margin: 0; font-size: var(--fs-md); }

/* ---------- CTA band ---------- */
.cta-band {
  background:
    radial-gradient(30rem 16rem at 88% -30%, rgba(255, 255, 255, 0.16), transparent 60%),
    var(--grad-brand);
  border-radius: 24px; color: #fff; padding: 3rem 2.75rem;
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem;
  box-shadow: 0 24px 60px rgba(79, 70, 229, 0.35);
  position: relative; overflow: hidden;
}
.cta-band h2 { color: #fff; margin: 0 0 0.3rem; }
.cta-band p { color: #ddd9fb; margin: 0; }
.cta-band .cta-text { flex: 1; min-width: 260px; }

/* ---------- Charts (dataviz chrome — validated palette, both modes) ---------- */
.viz-root {
  color-scheme: light;
  --surface-1: #fcfcfb;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  /* was #898781 = 3.50:1 on this chart surface. It carries .viz-sub, the caption
     under each of the six chart titles on statistics.html — body text, so 4.5:1.
     Same warm grey, darker: 3.50 -> 5.03. The dark theme's copy of this token
     measures 4.85 and is left where it is. */
  --text-muted: #6f6d68;
  --gridline: #e1e0d9;
  --baseline: #c3c2b7;
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  background: var(--surface-1);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.35rem 1.5rem; box-shadow: var(--shadow-sm);
}
html[data-theme="dark"] .viz-root {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --text-muted: #898781;
  --gridline: #2c2c2a;
  --baseline: #383835;
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
}
/* The six chart titles on statistics.html were <p class="viz-title"> — 15.2px,
   weight 700, role none — so the page's whole heading structure was one <h1> plus
   the three injected footer <h4>s. They are <h2> now; line-height and
   letter-spacing are pinned to the values they inherited as paragraphs (style.css
   :176 and :188) so promoting the tag changes nothing on screen. */
.viz-root .viz-title { font-size: var(--fs-base); font-weight: 700; color: var(--text-primary); margin: 0 0 0.15rem; line-height: 1.65; letter-spacing: normal; }
.viz-root .viz-sub { font-size: var(--fs-xs); color: var(--text-muted); margin: 0 0 1rem; }
.viz-legend { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; font-size: var(--fs-xs); color: var(--text-secondary); margin-top: 0.8rem; }
.viz-legend .lg-item { display: inline-flex; align-items: center; gap: 0.4rem; }
.viz-legend .lg-swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.viz-tooltip {
  position: fixed; z-index: 90; pointer-events: none; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow-lg); padding: 0.55rem 0.8rem;
  font-size: var(--fs-xs); color: var(--ink); opacity: 0; transition: opacity 0.1s;
}
.viz-tooltip.show { opacity: 1; }
.viz-tooltip .tt-title { font-weight: 700; margin-bottom: 0.15rem; }
.viz-tooltip .tt-row { display: flex; align-items: center; gap: 0.4rem; color: var(--ink-2); }

/* ---------- Footer ---------- */
.site-footer { background: var(--footer-bg); color: #93a1c4; margin-top: 4.5rem; position: relative; }
.site-footer::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.5), transparent); }
.footer-main { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2rem; padding: 3.25rem 0 2.4rem; }
@media (max-width: 900px) { .footer-main { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-main { grid-template-columns: 1fr; } }
.site-footer h4 { color: #e4e9f7; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 1rem; }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: 0.55rem; }
.site-footer a { color: #93a1c4; font-size: var(--fs-sm); }
.site-footer a:hover { color: #fff; }
.site-footer .footer-about { font-size: var(--fs-sm); line-height: 1.7; }
.site-footer .logo { color: #fff; margin-bottom: 1rem; }
.site-footer .logo .logo-cite { color: #fff; }
.site-footer .logo .logo-tld { color: #6b7590; }
.footer-bottom { border-top: 1px solid rgba(255, 255, 255, 0.08); padding: 1.2rem 0; font-size: var(--fs-xs); display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; justify-content: space-between; }
.footer-bottom a { font-size: var(--fs-xs); }

/* ---------- Reveal animation ---------- */
.js-reveal { opacity: 0; transform: translateY(16px); transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1); }
.js-reveal.revealed { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js-reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
  .btn, .card-hover, .pagination button { transition: none; }
}

/* ---------- Utilities ---------- */
.text-center { text-align: center; }
.text-muted { color: var(--ink-2); }
.text-small { font-size: var(--fs-sm); }
.text-xs { font-size: var(--fs-xs); color: var(--ink-3); }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: 0.5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; } .mt-4 { margin-top: 2rem; } .mt-5 { margin-top: 3rem; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: 0.5rem; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; } .mb-4 { margin-bottom: 2rem; }
.flex { display: flex; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .justify-between { justify-content: space-between; } .gap-1 { gap: 0.5rem; } .gap-2 { gap: 1rem; }
.hidden { display: none !important; }
.divider-v { width: 1px; align-self: stretch; background: var(--line); }

/* ============================================================
   v3 "Aurora Live" enrichment — motion, glass, gradient borders
   ============================================================ */

/* -- Searchable select (combobox) — upgrades every <select> site-wide -- */
.cl-combo { position: relative; }
/* clip-path over opacity: an opacity-0 element is still laid out, still focusable and
   still a real box -- these selects carry inline width:100%, which beats the width:0
   here, so each was a 384x26 invisible box over its own button. clip-path removes it
   from view without pretending it is gone; tabindex="-1" in app.js removes it from
   the tab order, which opacity never did. */
.cl-combo > select {
  position: absolute; opacity: 0; pointer-events: none;
  width: 1px !important; height: 1px; clip-path: inset(50%); overflow: hidden;
}
.cl-combo-btn {
  width: 100%; text-align: left; font-family: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding: 0.75rem 2.4rem 0.75rem 0.95rem; border: 1px solid var(--line-2); border-radius: 12px;
  background: var(--surface); cursor: pointer; position: relative;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.cl-combo-btn::after {
  content: ""; position: absolute; right: 0.95rem; top: 50%; width: 8px; height: 8px;
  border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: translateY(-70%) rotate(45deg); border-radius: 1px;
}
.cl-combo-btn:hover { border-color: var(--line-2); }
.cl-combo.open .cl-combo-btn { border-color: var(--brand-400); box-shadow: 0 0 0 3px var(--ring); }
.cl-combo-panel {
  position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 6px);
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-lg); padding: 0.45rem; display: none;
  min-width: 240px;
}
.cl-combo.open .cl-combo-panel { display: block; animation: fadeUp 0.16s ease; }
.cl-combo-search {
  width: 100%; font-family: inherit; font-size: var(--fs-sm); color: var(--ink);
  padding: 0.55rem 0.7rem; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface-2); margin-bottom: 0.4rem;
}
.cl-combo-search:focus { outline: none; border-color: var(--brand-400); }
.cl-combo-list { max-height: 260px; overflow-y: auto; }
.cl-combo-opt {
  padding: 0.5rem 0.7rem; border-radius: 8px; font-size: var(--fs-sm); color: var(--ink-2);
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cl-combo-opt:hover, .cl-combo-opt.active { background: var(--brand-50); color: var(--brand-700); }
/* colour the sort-direction arrows: ↓ = high→low (warm), ↑ = low→high (cool) */
/* was a hardcoded #e11d48 with no dark override: 4.63:1 in light, 3.82:1 in dark.
   The token already carries a per-theme value, so it does the work: 5.05 / 6.66. */
.cl-combo-btn .sort-dn, .cl-combo-opt .sort-dn { color: var(--critical); font-weight: 800; }
.cl-combo-btn .sort-up, .cl-combo-opt .sort-up { color: #0d9488; font-weight: 800; }
.cl-combo-btn .sort-az, .cl-combo-opt .sort-az { color: var(--brand-500); font-weight: 800; }
.cl-combo-opt.selected { font-weight: 700; color: var(--brand-600); }
.cl-combo-empty { padding: 0.7rem; font-size: var(--fs-xs); color: var(--ink-3); text-align: center; }

/* -- Login-required toast -- */
.cl-toast {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 80; display: flex; align-items: center; gap: 1.1rem; max-width: 92vw;
  background: var(--surface); border: 1px solid var(--brand-300); border-radius: 16px;
  padding: 0.9rem 1.1rem; box-shadow: var(--shadow-lg); animation: fadeUp 0.22s ease;
}
@media (max-width: 560px) { .cl-toast { flex-direction: column; align-items: stretch; text-align: center; } }

/* -- Small scholar avatar (journal profile, author lists) -- */
.sch-avatar-sm {
  flex: none; width: 42px; height: 42px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--grad-brand); color: #fff; font-weight: 800; font-size: 0.95rem;
}

/* -- Organization / scholar logo cell -- */
.org-logo {
  width: 52px; height: 44px; border-radius: 10px; flex: none;
  /* contain, not cover — never crop a logo or crest */
  object-fit: contain; padding: 3px;
  background: #fff; border: 1px solid var(--line);
}
html[data-theme="dark"] .org-logo { background: #f5f6fa; }
.org-mono {
  width: 44px; height: 44px; border-radius: 10px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--brand-50), var(--brand-100));
  border: 1px solid var(--brand-200); color: var(--brand-600);
  font-weight: 800; font-size: 0.95rem; letter-spacing: -0.02em;
}
.org-cell { display: flex; gap: 0.75rem; align-items: center; }

/* -- Journal compare (rankings) -- */
.cmp-bar {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
  z-index: 55; display: flex; align-items: center; gap: 0.9rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 0.55rem 0.7rem 0.55rem 1.2rem; box-shadow: var(--shadow-lg);
  animation: fadeUp 0.25s ease;
}
.cmp-bar .cmp-count { font-size: var(--fs-sm); font-weight: 700; color: var(--ink); white-space: nowrap; }
.cmp-check { accent-color: var(--brand-500); width: 16px; height: 16px; cursor: pointer; }
.cmp-panel-table th { position: sticky; left: 0; background: var(--surface-2); min-width: 170px; z-index: 1; }
.cmp-panel-table td { min-width: 190px; vertical-align: top; }
.cmp-best { font-weight: 800; color: var(--good-text); }

/* -- Scroll progress bar (element injected by app.js) -- */
.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0;
  background: linear-gradient(90deg, #4f46e5, #8b5cf6, #22d3ee);
  z-index: 60; border-radius: 0 3px 3px 0;
  box-shadow: 0 0 12px rgba(124, 58, 237, 0.55);
  transition: width 0.08s linear;
}

/* -- Header elevates & tightens on scroll -- */
.site-header { transition: box-shadow 0.25s ease, background 0.25s ease; }
.site-header.scrolled { box-shadow: 0 8px 30px rgba(15, 23, 42, 0.1); }
html[data-theme="dark"] .site-header.scrolled { box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55); }

/* -- Living hero: drifting aurora blobs + grain -- */
@keyframes cl-drift-a {
  0% { transform: translate(0, 0) scale(1) rotate(0deg); }
  50% { transform: translate(-70px, 45px) scale(1.15) rotate(40deg); }
  100% { transform: translate(0, 0) scale(1) rotate(0deg); }
}
@keyframes cl-drift-b {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(60px, -30px) scale(1.12); }
  100% { transform: translate(0, 0) scale(1); }
}
.hero::after { animation: cl-drift-a 26s ease-in-out infinite; }
.hero .container::before {
  content: ""; position: absolute; pointer-events: none; z-index: -1;
  width: 420px; height: 420px; left: -160px; bottom: -220px; border-radius: 50%;
  background: radial-gradient(circle at 40% 40%, rgba(34, 211, 238, 0.3), rgba(79, 70, 229, 0.18) 55%, transparent 75%);
  filter: blur(60px); animation: cl-drift-b 32s ease-in-out infinite;
}
.hero, .page-hero { isolation: isolate; }
.hero > .container, .page-hero > .container { position: relative; z-index: 1; }
.hero .hero-grain, .page-hero .hero-grain {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.05; z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
}

/* -- Animated gradient text in hero headline -- */
@keyframes cl-grad-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
.hero h1 .grad, .text-gradient { background-size: 220% 220%; animation: cl-grad-shift 7s ease-in-out infinite; }
.eyebrow { background-size: 200% 200%; animation: cl-grad-shift 9s ease-in-out infinite; }

/* -- Gradient-border glow cards -- */
.card-hover { position: relative; }
.card-hover::before {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1.5px;
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.85), rgba(139, 92, 246, 0.55) 45%, rgba(34, 211, 238, 0.7));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity 0.25s ease; pointer-events: none;
}
.card-hover:hover::before { opacity: 1; }
.card-hover:hover { border-color: transparent; }
.card-hover:hover .icon-badge { transform: scale(1.08) rotate(-4deg); }
.icon-badge { transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.3, 1.4); }

/* -- Stat tiles: hover lift + glow accent -- */
.stat-tile { transition: transform 0.2s ease, box-shadow 0.2s ease; }
.stat-tile:hover { transform: translateY(-3px); box-shadow: 0 12px 30px rgba(79, 70, 229, 0.14); }

/* -- Primary button shine sweep -- */
.btn-primary, .btn-accent { position: relative; overflow: hidden; }
.btn-primary::after, .btn-accent::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 44%; left: -60%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-18deg); transition: left 0.5s ease;
}
.btn-primary:hover::after, .btn-accent:hover::after { left: 130%; }

/* -- Section heading gradient underline -- */
.section-head h2 { position: relative; padding-bottom: 0.75rem; }
.section-head h2::after {
  content: ""; position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 64px; height: 4px; border-radius: 4px;
  background: linear-gradient(90deg, #4f46e5, #8b5cf6, #22d3ee);
}

/* -- Tables: accent bar on row hover -- */
.table tbody tr { position: relative; }
.table tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--brand-400); }

/* -- Dark mode: glass cards & deep glows -- */
html[data-theme="dark"] .card,
html[data-theme="dark"] .filter-group,
html[data-theme="dark"] .stat-tile,
html[data-theme="dark"] .form-card,
html[data-theme="dark"] .accordion {
  background: rgba(19, 26, 48, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
html[data-theme="dark"] body {
  background:
    radial-gradient(50rem 30rem at 85% -10%, rgba(76, 60, 200, 0.14), transparent 60%),
    radial-gradient(40rem 26rem at 0% 110%, rgba(20, 140, 160, 0.09), transparent 60%),
    var(--page);
  background-attachment: fixed;
}
html[data-theme="dark"] .stat-tile:hover { box-shadow: 0 12px 32px rgba(109, 124, 250, 0.25); }

/* -- Searchbar focus glow -- */
.searchbar:focus-within { box-shadow: 0 22px 55px rgba(4, 8, 30, 0.5), 0 0 0 6px rgba(139, 92, 246, 0.35); transition: box-shadow 0.25s ease; }

/* -- CLV / metric pill shimmer on hover -- */
.clv-pill, .clv-dial { transition: transform 0.2s ease, box-shadow 0.2s ease; }
.clv-pill:hover, .clv-dial:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 10px 26px rgba(79, 70, 229, 0.22); }

/* -- Accordion open animation -- */
.accordion .acc-body { animation: fadeUp 0.28s ease; }

/* -- Footer top glow line already present; add soft radial -- */
.site-footer::after {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 60%; height: 120px; pointer-events: none;
  background: radial-gradient(50% 100% at 50% 0%, rgba(129, 140, 248, 0.12), transparent 75%);
}

/* ============================================================
   v4 polish — modern controls, auth stage, index coverage strip
   ============================================================ */

/* -- Bigger, softer form controls everywhere -- */
.field input[type="text"], .field input[type="url"], .field input[type="email"],
.field input[type="password"], .field input[type="number"], .field input[type="date"],
.field input[type="search"], .field select, .field textarea,
.browse-toolbar select, .input, select.input {
  padding: 0.75rem 0.95rem; border-radius: 12px;
}
.field select, .browse-toolbar select, select.input {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%238b96ab' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.9rem center;
  padding-right: 2.4rem;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--line-2); }

/* -- Index coverage strip on journal cards: ALL indexes, on/off -- */
.idx-strip { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.15rem; }
.idx {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em; line-height: 1;
  padding: 0.36em 0.65em; border-radius: 999px; white-space: nowrap;
}

.idx-off { background: transparent; color: var(--ink-3); border: 1px dashed var(--line-2); opacity: 0.65; }

/* -- Auth stage (login/register) -- */
.auth-stage {
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  border-radius: 24px; overflow: hidden; box-shadow: var(--shadow-lg);
  border: 1px solid var(--line); background: var(--surface);
  min-height: 560px; margin: 2.5rem 0 3rem;
}
@media (max-width: 860px) { .auth-stage { grid-template-columns: 1fr; } .auth-side { display: none; } }
.auth-side {
  position: relative; padding: 2.75rem 2.5rem; color: #dfe6f8; isolation: isolate;
  background:
    radial-gradient(34rem 20rem at 90% -10%, rgba(124, 58, 237, 0.5), transparent 62%),
    radial-gradient(26rem 18rem at -10% 110%, rgba(34, 211, 238, 0.22), transparent 60%),
    linear-gradient(160deg, #0b1029 0%, #171e4b 60%, #232c6e 100%);
  display: flex; flex-direction: column; justify-content: space-between;
}
.auth-side::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.45; z-index: -1;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 38px 38px;
  mask-image: radial-gradient(40rem 26rem at 50% 20%, #000 25%, transparent 78%);
  -webkit-mask-image: radial-gradient(40rem 26rem at 50% 20%, #000 25%, transparent 78%);
}
.auth-side h2 { color: #fff; font-size: 1.7rem; letter-spacing: -0.03em; }
.auth-side .auth-points { list-style: none; padding: 0; margin: 1.5rem 0 0; display: grid; gap: 0.9rem; }
.auth-side .auth-points li { display: flex; gap: 0.7rem; align-items: flex-start; font-size: var(--fs-sm); color: #b9c5e6; }
.auth-side .auth-points .pt-ic {
  flex: none; width: 30px; height: 30px; border-radius: 9px; font-size: 0.95rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.09); border: 1px solid rgba(255, 255, 255, 0.14);
}
.auth-side .auth-quote { font-size: var(--fs-xs); color: #8d9cc4; border-left: 2px solid rgba(129, 140, 248, 0.5); padding-left: 0.9rem; }
.auth-form { padding: 2.75rem 2.75rem 2.25rem; display: flex; flex-direction: column; }
@media (max-width: 560px) { .auth-form { padding: 1.75rem 1.4rem; } }

/* -- Segmented pill tabs -- */
.tabs-seg {
  display: flex; gap: 4px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px; margin-bottom: 1.75rem;
  overflow: visible;
}
.tabs-seg button {
  flex: 1; border: 0; background: none; font-family: inherit; cursor: pointer;
  font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2);
  padding: 0.6rem 1rem; border-radius: 999px; transition: background 0.18s, color 0.18s, box-shadow 0.18s;
  border-bottom: none !important;
}
.tabs-seg button:hover { color: var(--ink); }
.tabs-seg button.active { background: var(--surface); color: var(--brand-500); box-shadow: var(--shadow); border-image: none; }

/* -- Role tiles (account type) -- */
.role-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin: 0.25rem 0 1rem; }
@media (max-width: 560px) { .role-tiles { grid-template-columns: 1fr; } }
.role-tile { position: relative; cursor: pointer; }
.role-tile input { position: absolute; opacity: 0; pointer-events: none; }
.role-tile .rt-body {
  border: 1.5px solid var(--line); border-radius: 14px; padding: 0.9rem 1rem;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s; height: 100%;
}
.role-tile .rt-ic { font-size: 1.25rem; }
.role-tile .rt-title { font-weight: 800; font-size: var(--fs-sm); color: var(--ink); margin-top: 0.3rem; }
.role-tile .rt-desc { font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.45; margin-top: 0.15rem; }
.role-tile:has(input:checked) .rt-body {
  border-color: var(--brand-400); background: var(--brand-50);
  box-shadow: 0 0 0 3px var(--ring);
}
.role-tile:has(input:checked) .rt-title { color: var(--brand-600); }

/* -- Input with leading icon -- */
.input-ic { position: relative; }
.input-ic .ic {
  position: absolute; left: 0.95rem; top: 50%; transform: translateY(-50%);
  font-size: 0.95rem; opacity: 0.55; pointer-events: none;
}
.input-ic input { padding-left: 2.55rem !important; }
.btn-block { width: 100%; justify-content: center; padding: 0.85rem 1.5rem; font-size: var(--fs-base); }

@media (prefers-reduced-motion: reduce) {
  .hero::after, .hero .container::before, .hero h1 .grad, .text-gradient, .eyebrow { animation: none; }
  .btn-primary::after, .btn-accent::after { display: none; }
  .scroll-progress { transition: none; }
  .card-hover:hover .icon-badge, .stat-tile:hover, .clv-pill:hover, .clv-dial:hover { transform: none; }
}

/* ---------- article lists (journal top articles) ---------- */
.art-list { list-style: none; margin: 0; padding: 0; counter-reset: art; }
.art {
  counter-increment: art;
  display: grid; grid-template-columns: 2.1rem 1fr auto; gap: 0 0.9rem;
  align-items: start; padding: 0.95rem 0;
  border-bottom: 1px solid var(--line);
}
.art:last-child { border-bottom: 0; }
.art::before {
  content: counter(art);
  font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3);
  text-align: right; padding-top: 0.15rem; font-variant-numeric: tabular-nums;
}
.art-main { min-width: 0; }
.art-title { font-size: var(--fs-base); font-weight: 650; line-height: 1.35; margin: 0 0 0.28rem; }
.art-title a { color: var(--ink); text-decoration: none; }
.art-title a:hover { color: var(--brand-600); text-decoration: underline; }
.art-auth {
  font-size: var(--fs-sm); color: var(--ink-2); margin: 0 0 0.3rem;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.art-meta { display: flex; flex-wrap: wrap; gap: 0.34rem 0.7rem; align-items: center; font-size: var(--fs-xs); color: var(--ink-3); margin: 0; }
.art-type { text-transform: capitalize; }
.art-doi { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; }
.art-nums { display: flex; gap: 1.15rem; align-items: flex-start; padding-top: 0.1rem; }
.art-nums > div { text-align: right; line-height: 1.15; }
.art-nums strong { display: block; font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.art-nums span { display: block; font-size: var(--fs-xs); color: var(--ink-3); }
.art-cni strong { color: var(--brand-600); }

@media (max-width: 680px) {
  .art { grid-template-columns: 1.7rem 1fr; }
  .art-nums { grid-column: 2; padding-top: 0.5rem; gap: 1.4rem; }
  .art-nums > div { text-align: left; }
}

@media print {
  .site-header, .site-footer, .header-cta, .btn, .pagination, .filters, .theme-toggle, .scroll-progress { display: none !important; }
  body { background: #fff; }
}

/* Article result card: the DOI badge sits in the card's top-right corner, kept
   clear of the title so the two links are never confused for each other — the
   title stays on CiteLink, the badge leaves for the publisher. */
.art { position: relative; }
.art-doi-chip {
  position: absolute; top: 0.75rem; right: 0.85rem;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card-bg);
  text-decoration: none; opacity: 0.8; transition: opacity .15s, border-color .15s;
}
.art-doi-chip:hover { opacity: 1; border-color: var(--brand-500); }
.art-list .art-main { padding-right: 2.4rem; }

/* ============================================================
   Pricing components (pricing.html) — the proposal strip, the three truths,
   tinted tier columns with a coloured top edge, marks-only feature table,
   the institutional band table and offer card, discount tiles.
   Written 5 Sep 2026 when the page was redesigned on the Editage compare-plans
   pattern (tinted full-height columns, one badge overlapping the edge, feature
   names on the left, a tick or a cross per cell and nothing else). Every colour
   is a site token or one of the five tier triples on :root. Not prefixed cmp-*:
   that prefix belongs to the journal compare tray.
   ============================================================ */

/* Visually hidden, still read aloud. The feature table's cells carry a mark and
   nothing visible beside it; this keeps "Included" / "Not included" / "Planned"
   in the accessibility tree without printing them, so the table still reads
   aloud exactly as it did when the word was printed. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* One class maps a tier's triple onto --tint / --edge / --tone, so a column, a
   table cell and an offer card colour themselves with the same three words. */
.t-reader  { --tint: var(--tint-reader);  --edge: var(--edge-reader);  --tone: var(--tone-reader); }
.t-member  { --tint: var(--tint-member);  --edge: var(--edge-member);  --tone: var(--tone-member); }
.t-premium { --tint: var(--tint-premium); --edge: var(--edge-premium); --tone: var(--tone-premium); }
.t-team    { --tint: var(--tint-team);    --edge: var(--edge-team);    --tone: var(--tone-team); }
.t-inst    { --tint: var(--tint-inst);    --edge: var(--edge-inst);    --tone: var(--tone-inst); }
/* Pill ground: the tone in light mode, the edge in dark (see the tokens). */
.t-reader, .t-member, .t-premium, .t-team, .t-inst { --pill-bg: var(--tone); }
html[data-theme="dark"] :is(.t-reader, .t-member, .t-premium, .t-team, .t-inst) { --pill-bg: var(--edge); }
/* On a tint the lighter grey slips under 4.5:1 and so does the dark link colour;
   inside any tinted or amber block muted text is --ink-2 and dark links take
   --brand-600 (4.79:1 on the darkest of them, 5.07:1 on the tints). */
.tinted .text-xs, .tinted .text-muted, .tinted .tier-note { color: var(--ink-2); }
html[data-theme="dark"] :is(.tinted, .proposal, .notice) a:not(.btn) { color: var(--brand-600); }

/* ---- The proposal strip: the one sentence a librarian must not miss ---- */
.proposal {
  display: flex; gap: 0.9rem; align-items: flex-start;
  background: var(--warn-bg); border: 1px solid transparent; border-left: 6px solid var(--warning);
  border-radius: var(--radius); padding: 1.1rem 1.35rem; margin: 0 0 1.75rem;
  color: var(--ink); font-size: var(--fs-base);
}
.proposal .p-ic { flex: none; width: 34px; height: 34px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.06); font-size: 1.05rem; margin-top: 0.05rem; }
html[data-theme="dark"] .proposal .p-ic { background: rgba(255, 255, 255, 0.08); }
.proposal p { margin: 0; }
.proposal strong { font-weight: 800; }
.proposal a { color: var(--brand-600); font-weight: 600; }

/* ---- The three truths: one line each, above every price ---- */
.truths { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.truth { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.15rem 1rem 1.35rem; box-shadow: var(--shadow-sm); overflow: hidden; }
.truth::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--edge-reader); }
.truth strong { display: block; font-size: var(--fs-md); color: var(--ink); margin-bottom: 0.2rem; letter-spacing: -0.01em; }
.truth p { margin: 0; font-size: var(--fs-sm); color: var(--ink-2); }
@media (max-width: 860px) { .truths { grid-template-columns: 1fr; } }

/* ---- Tier columns: tinted the whole height, a 5px coloured top edge ---- */
.tiers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.1rem; align-items: stretch; margin-top: 1.9rem; }
@media (max-width: 1080px) { .tiers { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 1.9rem; } }
@media (max-width: 600px)  { .tiers { grid-template-columns: 1fr; row-gap: 1.9rem; } }
.tier {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  background: var(--tint); border: 1px solid var(--line); border-top: 5px solid var(--edge);
  border-radius: var(--radius-lg); padding: 1.7rem 1.35rem 1.35rem; box-shadow: var(--shadow-sm);
}
/* The flag sits ON the top edge, overlapping it, the way Editage's "popular"
   badge does -- except that each one here says something we can stand behind:
   "everything, free" on Reader, "proposed price" on anything that costs money. */
.tier-flag, .edge-chip {
  position: absolute; top: -5px; transform: translate(-50%, -50%);
  background: var(--pill-bg, var(--ink-2)); color: var(--pill-ink);
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.09em; text-transform: uppercase;
  padding: 0.42em 0.95em; border-radius: 999px; white-space: nowrap; box-shadow: var(--shadow); z-index: 2;
}
.tier-flag { left: 50%; }
.edge-chip { left: 1.5rem; transform: translate(0, -50%); }
.tier-flag-free { background: var(--brand-500); color: #fff; box-shadow: var(--glow); }
html[data-theme="dark"] .tier-flag-free { background: var(--brand-600); color: #0b1029; }
.tier-name { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--tone); margin: 0 0 0.55rem; }
.tier-who { font-size: var(--fs-sm); color: var(--ink-2); margin: 0 0 0.9rem; min-height: 2.6em; }
.tier-price { display: flex; align-items: baseline; gap: 0.35rem; flex-wrap: wrap; line-height: 1; margin: 0; }
.tier-price .amt { font-size: clamp(2.3rem, 2.9vw, 2.9rem); font-weight: 800; letter-spacing: -0.035em; color: var(--ink); font-variant-numeric: tabular-nums; }
.tier-price .amt-sm { font-size: clamp(1.75rem, 2.3vw, 2.25rem); }
.tier-price .per { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); }
.tier-alt { font-size: var(--fs-sm); color: var(--ink-2); margin: 0.55rem 0 0; }
.tier-state { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0.9rem 0 1rem; font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--tone); }
.tier-state::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--edge); flex: none; }
.tier-list { list-style: none; margin: 0 0 1.3rem; padding: 0; display: grid; gap: 0.5rem; }
.tier-list li { position: relative; padding-left: 1.9rem; font-size: var(--fs-sm); color: var(--ink); line-height: 1.5; }
.tier-list li > .mk { position: absolute; left: 0; top: 0.05rem; }
.tier-list li strong { font-weight: 700; }
.tier .sub-h { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--tone); margin: 0.2rem 0 0.6rem; }
.tier .btn { margin-top: auto; }
.tier .btn-outline { background: var(--surface); }
.tier-note { font-size: var(--fs-xs); color: var(--ink-2); margin: 0.85rem 0 0; }
.two-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem 1.5rem; margin: 0 0 1.3rem; }
.two-lists .tier-list { margin: 0; }
@media (max-width: 620px) { .two-lists { grid-template-columns: 1fr; } }

/* ---- Marks: filled tick (today), dashed ring (planned), grey cross (not in
   this tier), red cross (never sold, at any tier). Icons, not text. ---- */
.mk { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; flex: none; vertical-align: middle; box-sizing: border-box; }
.mk svg { width: 13px; height: 13px; display: block; }
.mk-yes   { background: var(--good-bg); color: var(--good-text); }
.mk-soon  { background: transparent; color: var(--brand-600); border: 1.6px dashed var(--brand-600); }
html[data-theme="dark"] .mk-soon { color: var(--brand-700); border-color: var(--brand-700); }
.mk-no    { background: var(--surface-2); color: var(--ink-3); border: 1px solid var(--line); }
.mk-never { background: var(--critical-bg); color: var(--critical); }
.mark-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem 1.4rem; font-size: var(--fs-sm); color: var(--ink-2); margin: 1.4rem 0 0; }
.mark-legend span { display: inline-flex; align-items: center; gap: 0.45rem; }

/* ---- Feature table: names down the left, marks only in the cells, each tier
   column tinted from the head cell to the last row. .table th is written for a
   column label (uppercase, xs, nowrap, sticky top); the row and rowgroup headers
   go back into body type, and the column heads lose the sticky top because they
   carry a price and a tint rather than a one-line label. ---- */
.feature-table th[scope="row"], .feature-table th[scope="rowgroup"] { position: static; text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); color: var(--ink); white-space: normal; }
.feature-table th[scope="row"] { background: var(--surface); font-weight: 600; min-width: clamp(10rem, 44vw, 19rem); }
.feature-table th[scope="rowgroup"] { background: var(--surface-2); color: var(--ink-2); font-weight: 800; }
.feature-table thead th { position: static; text-align: center; vertical-align: bottom; }
.feature-table thead th:first-child { text-align: left; }
.feature-table thead th.tcol { background: var(--tint); border-top: 4px solid var(--edge); }
.feature-table .tn { display: block; font-size: var(--fs-sm); font-weight: 800; text-transform: none; letter-spacing: 0; color: var(--tone); }
.feature-table .tp { display: block; font-size: var(--fs-xs); font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--ink-2); margin-top: 0.15rem; white-space: normal; }
.feature-table td { text-align: center; width: 5.2rem; padding-left: 0.4rem; padding-right: 0.4rem; }
.feature-table td.tcol { background: var(--tint); }
.feature-table tbody tr:hover td { filter: brightness(0.97); }
html[data-theme="dark"] .feature-table tbody tr:hover td { filter: brightness(1.15); }
.feature-table .planned { margin-left: 0.4rem; vertical-align: 1px; }
/* On a phone the feature column stays put while the marks scroll, and the four
   mark cells narrow so that the whole row fits the 328px wrapper a 375px viewport
   leaves: 7rem (112px) for the names, and a mark cell of 3.2rem that the head
   cell's own word can still widen -- "Premium" at 0.7rem bold is 54px with its
   padding -- so the table measures 318px and no column hides off-screen. A first
   cut at 7.5rem and 0.75rem heads measured 339px, eleven over. */
@media (max-width: 620px) {
  .feature-table th[scope="row"] { position: sticky; left: 0; z-index: 1; box-shadow: inset -1px 0 0 var(--line); min-width: 7rem; width: 7rem; padding: 0.6rem 0.5rem; font-size: var(--fs-xs); }
  .feature-table thead th:first-child { position: sticky; left: 0; z-index: 2; }
  .feature-table td, .feature-table thead th.tcol { width: 3.2rem; min-width: 3.2rem; padding: 0.55rem 0.2rem; }
  .feature-table .tn { font-size: 0.7rem; }
  .feature-table .tp { font-size: 0.62rem; }
  .feature-table .planned { display: block; margin: 0.25rem 0 0; width: fit-content; }
}
.table-wrap:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.acc-body code, .notice code, .tier code { overflow-wrap: anywhere; }

/* ---- Institutional offer: the band table beside the offer card ---- */
.inst-grid { display: grid; grid-template-columns: 1.55fr 1fr; gap: 1.5rem; align-items: start; }
.inst-grid > * { min-width: 0; }   /* a grid item will not shrink below its content without this; the band table would widen the column instead of scrolling */
@media (max-width: 960px) { .inst-grid { grid-template-columns: 1fr; } }
.band-block { position: relative; }
.band-wrap { border-top: 5px solid var(--edge-inst); border-radius: var(--radius-lg); }
.band-table th[scope="row"] { position: static; text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); color: var(--ink); background: transparent; font-weight: 700; white-space: normal; }
.band-table th[scope="col"] { white-space: normal; }
.band-table th, .band-table td { vertical-align: top; }
.band-table tbody td, .band-table tbody th { background: var(--tint-inst); }
.band-table tbody tr:hover td, .band-table tbody tr:hover th { filter: brightness(0.97); }
html[data-theme="dark"] .band-table tbody tr:hover td, html[data-theme="dark"] .band-table tbody tr:hover th { filter: brightness(1.15); }
.band-table td.num { font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.band-table td.try { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink-2); font-weight: 600; }
.band-chip { display: inline-flex; align-items: center; justify-content: center; min-width: 2.3rem; padding: 0.2em 0.55em; border-radius: 999px; background: var(--tone-inst); color: #fff; font-weight: 800; font-size: var(--fs-xs); letter-spacing: 0.04em; }
html[data-theme="dark"] .band-chip { background: var(--edge-inst); color: #0a0e1f; }
.band-table td.rule { white-space: normal; font-size: var(--fs-xs); color: var(--ink-2); padding-top: 0; }
.band-table tr.note td { border-top: 0; }
.band-table tr:has(+ tr.note) td, .band-table tr:has(+ tr.note) th { border-bottom: 0; padding-bottom: 0.35rem; }
/* Phone rules AFTER the desktop rules on purpose: at equal specificity the later
   declaration wins, and with the lira figure allowed to wrap and the padding
   down the whole schedule fits a 375px phone without a sideways scroll. */
@media (max-width: 620px) {
  .band-table th, .band-table td { padding: 0.6rem 0.45rem; }
  .band-table td.num, .band-table td.try { white-space: normal; font-size: var(--fs-sm); }
  .band-table th[scope="row"] { font-size: var(--fs-xs); }
  .band-table caption { padding-left: 0.6rem !important; padding-right: 0.6rem !important; }
}

/* ---- Discount tiles: four facts a librarian scans, not a paragraph ---- */
.discount-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.9rem; margin-top: 1.5rem; }
@media (max-width: 1000px) { .discount-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .discount-tiles { grid-template-columns: 1fr; } }
.discount-tiles > div { background: var(--surface); border: 1px solid var(--line); border-top: 4px solid var(--edge-inst); border-radius: var(--radius); padding: 0.95rem 1.05rem; font-size: var(--fs-sm); color: var(--ink-2); box-shadow: var(--shadow-sm); line-height: 1.5; }
.discount-tiles .big { display: block; font-size: var(--fs-2xl); font-weight: 800; color: var(--tone-inst); line-height: 1; letter-spacing: -0.03em; margin-bottom: 0.35rem; font-variant-numeric: tabular-nums; }
/* A lira figure carries four more glyphs than a dollar one and overflows a
   quarter-width tile between 1000px and 1200px. One step down fits it. */
.discount-tiles .big.big-long { font-size: var(--fs-xl); }
.discount-tiles b { display: block; color: var(--ink); font-size: var(--fs-base); margin-bottom: 0.15rem; }

/* ---- Reasoning disclosures: the site's accordion, with tables inside ---- */
.reasoning .acc-body p { font-size: var(--fs-sm); }
.reasoning .acc-body .table-wrap { margin: 0.8rem 0 1rem; }
.reasoning .acc-body ul.plain { padding-left: 1.2em; font-size: var(--fs-sm); color: var(--ink-2); }
.reasoning .acc-body ul.plain li { margin-bottom: 0.4rem; }
/* .checklist li is display:flex site-wide, which makes a link inside a sentence
   its own flex item and lets it break away from its line. Block layout here. */
.reasoning .checklist li { display: block; position: relative; padding-left: calc(21px + 0.6rem); }
.reasoning .checklist li > .ok, .reasoning .checklist li > .no { position: absolute; left: 0; top: 0; }

/* ---- The one paid object, kept visibly apart from the tiers ---- */
.object-card { position: relative; border-top: 5px solid var(--line-2); }
.object-prices { display: flex; gap: 1.6rem; flex-wrap: wrap; margin: 0.7rem 0 0.9rem; }
.object-prices b { display: block; font-size: var(--fs-xl); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.object-prices span { font-size: var(--fs-xs); color: var(--ink-2); }

/* ── KCI (한국학술지인용색인) ────────────────────────────────────────────────
   Korea Citation Index, National Research Foundation of Korea. A text badge for
   now: TR Dizin and ERIC carry their operators' own logo files, and KCI's has
   not been supplied yet. Colour is the NRF blue. The grade rides in the label
   rather than only in the tooltip, because 등재후보 (candidate) is a different
   claim from 등재 (accredited) and a flat "KCI" would say the stronger one.

   There is deliberately NO faded variant. KCI accredits Korean journals; a
   faded KCI on a Brazilian one would not report an absence, it would report a
   question nobody asked. Same for the three below. tests/index-flags.test.js
   holds that line in both directions -- the chip must not draw a no, and the
   rule that would style one must not exist. */

/* ── ERIH PLUS, SciELO, KCI, AJOL ─────────────────────────────────
   FOUR TEXT BADGES, each in the colour measured from that operator's own logo
   file. These four shipped on 6 September in colours that had been GUESSED,
   under a comment claiming each carried "its operator's own colour". Three of
   the four guesses were wrong:

     SciELO     guessed #cf5c1f orange   is #da202c red     (logo PNG)
     AJOL       guessed #1c7a3e green    is #2e7a57 green   (logo PNG)
     KCI        guessed #0b4da2 blue     is #1f3a6e navy    (logo PNG)
     ERIH PLUS  guessed #0f5e6e teal     is #ea5c0c orange  (inline SVG, header)

   NONE OF THE FOUR CARRIES A MARK, and ERIH PLUS is the one that had to be
   taken back. On 7 September it got the real wordmark, 2,663 bytes of inline
   SVG, on the grounds that it appears on more journals than the others. That
   was tested at four times size, where it is perfectly legible, and shipped.
   It is not legible at the size it actually renders.

   Rasterised at the 15-16 px the chip gives it and magnified with nearest
   neighbour, the reason is plain: "e", "i" and "h" are SOLID glyphs and survive,
   but "r" and "+" are OUTLINE glyphs whose strokes fall to roughly 0.4 px. They
   come out as pale ghosts. A reader at normal zoom sees a solid e, a smudge,
   a solid ih, and another smudge. The live logo on erihplus.hkdir.no does
   exactly the same thing at that size -- this is the mark's design meeting a
   15 px box, not an encoding fault.

   The other three were refused on 7 September by the right test and ERIH PLUS
   was let through by the wrong one. SciELO was rejected after being enlarged
   four times and still reading as a grey smudge; the question that mattered was
   never "is it legible enlarged" but "is it legible at 15 px".

   AND ON 11 SEPTEMBER THE 15 px ANSWER WAS MEASURED RATHER THAN ASSERTED, AND
   IT IS NOT THE ONE WRITTEN ABOVE. The owner asked for the mark back. Drawn
   into a canvas at exactly one device pixel per CSS pixel and magnified with
   nearest neighbour -- the only honest way to look at this -- the thin parts of
   "r" and "+" come out as a continuous line at about 40% coverage. Pale, a
   stroke lighter than the solid glyphs, and perfectly readable as "erih+". The
   words "smudge" and "ghost" above are harsher than the pixels. What made the
   7 September verdict wrong twice over was judging both times at the wrong
   size: first magnified 4x, where everything passes, then in a 2x screenshot
   of a 2x display, where everything passes again.

   So ERIH PLUS carries its mark. SciELO, KCI, AJOL and CSCD stay words, and the
   reason has not changed for them: none of the four is a clean vector and KCI's
   label is not even constant -- it carries the grade, so a mark saying only
   "KCI" would state the strongest of three for all of them.

   THE GROUND IS NOT THE BRAND COLOUR HERE, AND THAT IS THE RULE ABOVE APPLIED
   RATHER THAN BROKEN. .badge-trdizin and .badge-eric tint the ground with the
   brand hue because their ink is DARK and needs a light ground to sit on.
   ERIH PLUS's ink IS the brand orange, so tinting the ground orange destroys
   exactly the contrast that rule exists to protect -- and an orange chip is
   what the owner rejected. #EEF2F7 is a pale cool ground: the complement side
   of orange, so the 40%-coverage pixels of "r" and "+" separate from it by hue
   as well as by value, which is measurably better than any warm ground tried.
   Four other candidates were drawn and dropped: #14283C ink and #2B2018
   espresso both collide with chips standing next to them in the same row
   (.badge-pubmed #17334f and .badge-doaj #282422), and on both the thin parts
   go muddy; #FFF6F0 and #F4EFE6 read as washed-out next to seven saturated
   neighbours.

   ONE COPY OF THE GEOMETRY, RECOLOURED BY CSS. The mark is a MASK, not a
   background-image, so `color` drives it: lit, faded and dark theme are three
   values of one property over one 2.4 kB data URI, where background-image
   would need three copies. Outside @supports the chip falls back to the word.
   TR Dizin and ERIC cannot do this -- they are multi-colour raster lockups, and
   a mask would flatten them to one colour.

   KCI additionally could never have taken a mark: its label is not constant. It
   carries the grade -- 등재 accredited, 등재후보 candidate, 우수등재 outstanding --
   and a wordmark saying only "KCI" would state the strongest of the three for
   all of them. See journal.html, which draws it from kci_tier. */
.badge-erihplus {
  --erih-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 139 44' fill='%23000'%3E%3Cpath d='M29.1261 31.33H7.81121C8.55149 34.7506 11.0786 37.2012 16.3116 37.2012C21.5447 37.2012 22.7699 36.3333 26.9053 34.4698V41.311C25.5268 42.3832 21.1362 43.8892 16.1585 43.8892C5.71801 43.8892 0 37.1502 0 28.7518C0 20.3535 5.82012 13.5634 14.9587 13.5634C24.0973 13.5634 29.3303 18.0561 29.3303 27.986C29.3303 37.916 29.2282 30.3345 29.1261 31.3045V31.33ZM21.5447 25.7141C21.3404 23.3146 19.2983 20.2003 14.8566 20.2003C10.4149 20.2003 8.80676 22.4977 7.96437 25.7141H21.5447Z'/%3E%3Cpath d='M58.7373 4.85871C58.7373 2.02523 61.2389 0.110718 63.7661 0.110718C66.2932 0.110718 68.7438 2.02523 68.7438 4.85871C68.7438 7.69219 66.2422 9.73433 63.7661 9.73433C61.29 9.73433 58.7373 7.81982 58.7373 4.85871Z'/%3E%3Cpath d='M67.6466 14.3802H59.9375V43.2H67.6466V14.3802Z'/%3E%3Cpath d='M76.1211 43.2V0.621216H83.7536V8.76428C83.7536 11.7509 83.7026 14.8652 83.5494 17.6476C84.6215 16.1415 87.1742 13.6399 91.9477 13.6399C96.7213 13.6399 102.261 16.8563 102.261 25.5609V43.2H94.628V25.8162C94.628 22.4467 92.4838 20.6853 89.9822 20.6853C87.4805 20.6853 83.8302 23.0338 83.8302 28.5476V43.2H76.1211Z'/%3E%3Cpath d='M127.634 14.3291H119.925V25.3822H127.634V14.3291Z'/%3E%3Cpath d='M138.177 24.8972H127.608V32.6063H138.177V24.8972Z'/%3E%3Cpath d='M126.332 26.1736V41.8726H121.176V33.4742C121.176 32.2745 120.205 31.3045 119.006 31.3045H110.607V26.148H126.306M127.583 24.8717H110.352C109.791 24.8717 109.331 25.3312 109.331 25.8928V31.6874C109.331 32.1724 109.739 32.5808 110.224 32.5808H119.006C119.491 32.5808 119.899 32.9892 119.899 33.4742V42.2555C119.899 42.7405 120.308 43.1489 120.793 43.1489H126.715C127.2 43.1489 127.608 42.7405 127.608 42.2555V24.8972L127.583 24.8717Z'/%3E%3Cpath d='M52.8661 15.6566V20.813H44.4678C43.268 20.813 42.298 21.783 42.298 22.9828V41.8727H37.1416V15.6566H52.8406M53.2235 14.3803H35.8652V42.1279C35.8652 42.6895 36.3247 43.149 36.8863 43.149H42.6809C43.1659 43.149 43.5743 42.7406 43.5743 42.2556V22.9573C43.5743 22.4723 43.9828 22.0638 44.4678 22.0638H53.249C53.734 22.0638 54.1425 21.6554 54.1425 21.1704V15.2482C54.1425 14.7632 53.734 14.3547 53.249 14.3547L53.2235 14.3803Z'/%3E%3C/svg%3E");
  /* FILLED, 19 Eyl 2026, at the owner's reading: on the pale ground above the chip
     did not read as an index the journal is IN. Every other covered index on that
     row is a filled chip; ERIH PLUS was the one outline among them, and an outline
     in a row of solids reads as "not covered" whatever the tooltip says.
     The objection that kept it pale is still true and is answered rather than
     ignored: ERIH PLUS's ink is orange, so orange ink on an orange ground has no
     contrast. The mark is a MASK painted with currentColor, so inverting it costs
     one property -- a mark in something other than orange.

     THE GROUND SWAPPED WITH SCOPUS, 19 Eyl 2026, at the owner's reading: this chip
     takes Scopus's orange a tone lighter and Scopus takes the deeper #EA5C0C. The
     lighter ground brings the dark ink with it, because white cannot survive there:
     measured, white on #F2843C is 2.58:1, under the 3:1 a graphic needs in order to
     be read, while the page's own near-black on it is 6.66:1. So the light theme now
     carries the arrangement the dark theme has had since this chip was filled -- a
     light orange ground with a dark wordmark.
     It also fixes the weakest part of the first version. The two chips used to be
     separated by the wordmark alone; now one is deep and one is light, which is a
     difference the eye takes in across a row without reading anything. */
  background: #F2843C; border: 1.5px solid #F2843C; color: #1B1B1F;
}
.badge-scielo   { background: #DA202C; color: #ffffff; border-color: #DA202C; font-weight: 700; }
.badge-kci      { background: #1F3A6E; color: #ffffff; border-color: #1F3A6E; font-weight: 700; }
/* CSCD, 11 Sep 2026. #042c81 is the dominant colour of the mark on
   sciencechina.cn's own logo file, not the #1677ff that covers their pages —
   that one is Ant Design's default primary and belongs to the framework, not
   the index. It sits close to KCI's navy, which is a real risk in a row of
   chips; both carry their name in text, so the label separates them. */
.badge-cscd     { background: #042C81; color: #ffffff; border-color: #042C81; font-weight: 700; }
.badge-ajol     { background: #2E7A57; color: #ffffff; border-color: #2E7A57; font-weight: 700; }
html[data-theme="dark"] .badge-erihplus {
  /* Filled here too, 19 Eyl 2026. The ground is lifted to #F2884A because the dark
     theme's other filled chips are lightened the same way, and the mark goes to the
     page's dark ink rather than white: white on #F2884A is 2.3:1, #1B1B1F on it is
     9.4:1. */
  background: #F2884A; border-color: #F2884A; color: #1B1B1F;
}
html[data-theme="dark"] .badge-scielo   { border-color: #EE5A63; }
html[data-theme="dark"] .badge-kci      { border-color: #5A7CB8; }
html[data-theme="dark"] .badge-cscd     { border-color: #4A6FC8; }

/* ── FADED VARIANTS FOR THE FIVE THAT HAD NONE ─ 11 Eyl 2026 ───────────────
   These five drew nothing when a journal was not in them. The reasoning, written
   on 7 September, was that a faded SciELO on a Turkish journal answers a
   question nobody asked — SciELO indexes Latin America, so "not in SciELO" is a
   category, not a finding. On 11 September the owner asked for the opposite:
   show every index, faded where the journal is not in it.

   That is the better call for a reason the original argument missed. A reader
   looking at a journal page cannot tell the difference between "we checked and
   it is not there" and "we never checked" when the chip is simply absent, and
   this catalogue holds twelve indexes whose coverage a reader has no way to
   enumerate. Drawing all of them says what was asked.

   What the original argument got right is kept in the TOOLTIP: every faded
   regional chip names what that index covers, so "not in SciELO" reads as
   SciELO's scope rather than as a judgement about the journal. */
.idx-off.idx-off-kci {
  background: rgba(255, 255, 255, 0.6); color: rgba(31, 58, 110, 0.5);
  border: 1px solid rgba(31, 58, 110, 0.22); opacity: 1;
}
.idx-off.idx-off-cscd {
  background: rgba(255, 255, 255, 0.6); color: rgba(4, 44, 129, 0.5);
  border: 1px solid rgba(4, 44, 129, 0.22); opacity: 1;
}
/* NOT IN IT: the mark stays and loses its strength, which is what the other
   twelve chips do. A faded chip that swapped the mark for the word would be the
   only one in the row changing shape between its two states. */
.idx-off.idx-off-erihplus {
  --erih-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 139 44' fill='%23000'%3E%3Cpath d='M29.1261 31.33H7.81121C8.55149 34.7506 11.0786 37.2012 16.3116 37.2012C21.5447 37.2012 22.7699 36.3333 26.9053 34.4698V41.311C25.5268 42.3832 21.1362 43.8892 16.1585 43.8892C5.71801 43.8892 0 37.1502 0 28.7518C0 20.3535 5.82012 13.5634 14.9587 13.5634C24.0973 13.5634 29.3303 18.0561 29.3303 27.986C29.3303 37.916 29.2282 30.3345 29.1261 31.3045V31.33ZM21.5447 25.7141C21.3404 23.3146 19.2983 20.2003 14.8566 20.2003C10.4149 20.2003 8.80676 22.4977 7.96437 25.7141H21.5447Z'/%3E%3Cpath d='M58.7373 4.85871C58.7373 2.02523 61.2389 0.110718 63.7661 0.110718C66.2932 0.110718 68.7438 2.02523 68.7438 4.85871C68.7438 7.69219 66.2422 9.73433 63.7661 9.73433C61.29 9.73433 58.7373 7.81982 58.7373 4.85871Z'/%3E%3Cpath d='M67.6466 14.3802H59.9375V43.2H67.6466V14.3802Z'/%3E%3Cpath d='M76.1211 43.2V0.621216H83.7536V8.76428C83.7536 11.7509 83.7026 14.8652 83.5494 17.6476C84.6215 16.1415 87.1742 13.6399 91.9477 13.6399C96.7213 13.6399 102.261 16.8563 102.261 25.5609V43.2H94.628V25.8162C94.628 22.4467 92.4838 20.6853 89.9822 20.6853C87.4805 20.6853 83.8302 23.0338 83.8302 28.5476V43.2H76.1211Z'/%3E%3Cpath d='M127.634 14.3291H119.925V25.3822H127.634V14.3291Z'/%3E%3Cpath d='M138.177 24.8972H127.608V32.6063H138.177V24.8972Z'/%3E%3Cpath d='M126.332 26.1736V41.8726H121.176V33.4742C121.176 32.2745 120.205 31.3045 119.006 31.3045H110.607V26.148H126.306M127.583 24.8717H110.352C109.791 24.8717 109.331 25.3312 109.331 25.8928V31.6874C109.331 32.1724 109.739 32.5808 110.224 32.5808H119.006C119.491 32.5808 119.899 32.9892 119.899 33.4742V42.2555C119.899 42.7405 120.308 43.1489 120.793 43.1489H126.715C127.2 43.1489 127.608 42.7405 127.608 42.2555V24.8972L127.583 24.8717Z'/%3E%3Cpath d='M52.8661 15.6566V20.813H44.4678C43.268 20.813 42.298 21.783 42.298 22.9828V41.8727H37.1416V15.6566H52.8406M53.2235 14.3803H35.8652V42.1279C35.8652 42.6895 36.3247 43.149 36.8863 43.149H42.6809C43.1659 43.149 43.5743 42.7406 43.5743 42.2556V22.9573C43.5743 22.4723 43.9828 22.0638 44.4678 22.0638H53.249C53.734 22.0638 54.1425 21.6554 54.1425 21.1704V15.2482C54.1425 14.7632 53.734 14.3547 53.249 14.3547L53.2235 14.3803Z'/%3E%3C/svg%3E");
  /* 0.70, and the number was measured rather than picked. The thin parts of
     "r" and "+" are filled paths 1.27 units wide in a 44-unit box, so at a 15 px
     chip they cover about 43% of a pixel BEFORE any fade is applied. At the 0.45
     this rule first carried, that compounds to ~19% and the "r" disappears
     entirely -- the faded chip read "e ih+". Rasterised at 1x and magnified, the
     mark comes back at 0.62 and is comfortable at 0.75. 0.70 sits inside that
     with margin. The lit/faded distinction does not depend on this number
     anyway: it is carried by the border (1.5px solid vs 1px at 22%) and the
     ground, exactly as it is for .idx-off-trdizin and .idx-off-eric. */
  background: rgba(234, 92, 12, 0.05); color: rgba(210, 83, 11, 0.70);
  border: 1px solid rgba(234, 92, 12, 0.22); opacity: 1;
}
.idx-off.idx-off-scielo {
  background: rgba(255, 255, 255, 0.6); color: rgba(218, 32, 44, 0.5);
  border: 1px solid rgba(218, 32, 44, 0.22); opacity: 1;
}
.idx-off.idx-off-ajol {
  background: rgba(255, 255, 255, 0.6); color: rgba(46, 122, 87, 0.55);
  border: 1px solid rgba(46, 122, 87, 0.22); opacity: 1;
}
html[data-theme="dark"] .idx-off.idx-off-kci,
html[data-theme="dark"] .idx-off.idx-off-cscd,
html[data-theme="dark"] .idx-off.idx-off-erihplus,
html[data-theme="dark"] .idx-off.idx-off-scielo,
html[data-theme="dark"] .idx-off.idx-off-ajol {
  background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.18);
}
html[data-theme="dark"] .idx-off.idx-off-kci      { color: rgba(140, 175, 225, 0.5); }
html[data-theme="dark"] .idx-off.idx-off-cscd     { color: rgba(130, 160, 235, 0.5); }
html[data-theme="dark"] .idx-off.idx-off-erihplus { color: rgba(242, 136, 74, 0.68); }
html[data-theme="dark"] .idx-off.idx-off-scielo   { color: rgba(238, 90, 99, 0.5); }
html[data-theme="dark"] .idx-off.idx-off-ajol     { color: rgba(78, 158, 120, 0.5); }

/* ═══ ONE SIZE FOR THE THIRTEEN INDEX CHIPS ═══ asked for on 11 Sep 2026.
   Chips whose width tracked their label length made a ragged block that reads
   as noise; on a common floor they line up and the eye compares strength
   instead of size.

   A FLOOR, NOT A FIXED SIZE. min-width, so the two labels that genuinely do not
   fit -- "CSCD (extended)" and a four-edition "WoS SCIE/SSCI/AHCI/ESCI" -- grow
   past it rather than truncating, and "Indexed in Scopus ✓" stays the one
   deliberately long chip. That is the "mumkun oldugunca" in the request:
   everything that can be one size is, and nothing is clipped to get there.
   Measured after: nine of the thirteen land on exactly the same width, and the
   four that do not each carry either the ↗ of an outbound link or a label that
   is longer on purpose.

   HEIGHT TOO, because a row was running 21.1 / 23.1 / 24.0 / 24.9 px -- .badge
   pads 0.38em with a 1px border, the three logo chips padded 0.3em with 1.5px,
   and the faded ones have their own 1px. Four heights in one row is more
   visible than four widths. box-sizing: border-box so a 1.5px border no longer
   makes a chip taller than its 1px neighbour, one padding for all thirteen, and
   a min-height the tallest content (the 1.15em logo marks) already clears.

   THIS RULE OWNS THE PADDING NOW. It sits after every .badge-* above on
   purpose: same specificity, later wins. The 0.3em 0.7em that .badge-trdizin,
   .badge-eric and .badge-erihplus used to carry has been removed from them
   rather than left to be silently overridden here.

   In em, so it holds at both chip sizes -- .badge is --fs-xs, .idx is 0.68rem --
   and follows the reader's text size rather than fixing a pixel count. */
.badge-scopus, .badge-wos, .badge-doaj, .badge-pubmed, .badge-pmc, .badge-ebsco,
.badge-trdizin, .badge-eric, .badge-kci, .badge-cscd, .badge-erihplus,
.badge-scielo, .badge-ajol,
.idx-off-scopus, .idx-off-wos, .idx-off-doaj, .idx-off-pubmed, .idx-off-pmc,
.idx-off-ebsco, .idx-off-trdizin, .idx-off-eric, .idx-off-kci, .idx-off-cscd,
.idx-off-erihplus, .idx-off-scielo, .idx-off-ajol {
  box-sizing: border-box;
  min-width: 6.4em; min-height: 2.05em;
  padding: 0.34em 0.72em;
  justify-content: center;
}
html[data-theme="dark"] .badge-ajol     { border-color: #4E9E78; }
