/*
  Evidence palette. Sampled from assets/evidence-logo.png: the mark is four
  leaves (cyan, green, orange, magenta) turning around a navy ground, so the
  navy carries the page and the leaves are the accents. Every colour below is
  defined once here; nothing else in this file names a hex value, so
  rebranding again means editing this block alone.
*/
:root {
  --ev-bg:          #394459;  /* navy ground */
  --ev-bg-deep:     #303C54;  /* the logo's own navy, for recessed areas */
  --ev-surface:     #424E66;  /* cards, bars, raised panels */
  --ev-surface-2:   #4A5670;  /* hover, borders, muted fills */
  --ev-text:        #E8ECF2;  /* primary text */
  --ev-text-muted:  #A8B2C4;  /* secondary text */

  --ev-accent:      #00B4D8;  /* cyan leaf: primary action / selection */
  --ev-accent-soft: #1B5E72;  /* cyan at low intensity, for fills */
  --ev-green:       #84B460;
  --ev-orange:      #F09048;
  --ev-magenta:     #D86CB4;

  /* The six series colours, for charts that draw the six indicators at once.
     Separate from the accents above because they answer a different
     question: these have to be told apart from each other, not just seen
     against the page. Stepped for this surface (#394459) rather than flipped
     from the light set, and checked with the dataviz validator: every one
     clears 3:1 on the surface, the worst adjacent pair separates by 18.7 in
     normal vision, and the green-to-orange pair sits at 6.0 under
     deuteranopia, which is why the stack carries 2px gaps and every segment
     is named in both the legend and the hover. */
  --ev-cat-1:       #00A3CB;
  --ev-cat-2:       #CE7D38;
  --ev-cat-3:       #4FA866;
  --ev-cat-4:       #9684DC;
  --ev-cat-5:       #00ABA4;
  --ev-cat-6:       #D8706F;
  /* For a bar that is present but not the thing being pointed at. Light
     enough to read against the ground, at 3.17:1, which --ev-surface-2 is
     not: that measures 1.33:1 and disappears. */
  --ev-cat-dim:     #8A93A6;

  --ev-radius:      10px;
  --ev-shadow:      0 2px 10px rgba(0, 0, 0, 0.28);
}

/* The page itself, so panels read as raised against a consistent ground. */
body, .dash-app-content {
  background-color: var(--ev-bg) !important;
  color: var(--ev-text);
}

/*
ORIGINAL CSS FILE FOR SLATE: https://cdn.jsdelivr.net/npm/bootswatch@5.2.3/dist/slate/bootstrap.min.css

COLOUR LIST
darkAccent1 = 'var(--ev-bg)' # dark gray, bgc (bar plot background)
darkAccent2 = 'var(--ev-surface-2)' # pale gray
darkAccent3 = 'var(--ev-text)' # almost white
lightAccent1 = 'var(--ev-accent)' # ocre
highlight1 = 'lightsteelblue'
highlight2 = 'cornflowerblue'

### TO-DO: incorporate dcc.Loading
*[data-dash-is-loading="true"]{
  visibility: hidden;
}
*[data-dash-is-loading="true"]::before{
  content: "Loading...";
  display: inline-block;
  color: var(--ev-accent);
  visibility: visible;
}

/* ====== Custom tabs ====== 
.custom-tabs2 .nav-link {
  height: 95px;
  white-space: normal;
} */

.custom-label{
  background-color:var(--ev-bg);
  border: 3px solid var(--ev-text);
}
.custom-tabs .nav-link {
  white-space: normal; /* allow the text to wrap */
  text-align: center;
}
.custom-tabs .nav-link span {
  display: inline-block; /* make sure the text doesn't overflow the tab */
}
.tab-content {
  border-radius: 8 px;
  border: 2px solid var(--ev-accent);
}

/* ====== Dropdown ====== */
.Select-control{
  background-color: var(--ev-text);
  border-radius: 4px;
  border: 2px solid var(--ev-accent);
  color: var(--ev-bg);
  display: table;
  border-spacing: 0;
  border-collapse: separate;
  height: 36px;
  overflow: hidden;
  text-align: center;
}

.is-open>.Select-control{
  background: var(--ev-text);
  border: 1px solid var(--ev-accent);
}

.Select-menu-outer{
  background-color: var(--ev-text);
  color: var(--ev-bg);
  border: 2px solid var(--ev-accent);
  text-align: left;
}

.Select-value-label{
  color: var(--ev-bg);
}

.Select-placeholder{
  color: black!important;
}

.is-focused .Select-input > input {
  cursor: text;
  color: var(--ev-accent)!important;
}

.Select--multi .Select-value {
  background-color: var(--ev-text);
  border-radius: 2px;
  border: 1px solid var(--ev-bg);
  color: var(--ev-accent);
  display: inline-block;
  font-size: .9em;
  line-height: 1.4;
  margin-left: 5px;
  margin-top: 5px;
  vertical-align: top;
}

.has-value.Select--single>.Select-control .Select-value .Select-value-label{
color: var(--ev-bg);
}

/* ====== Headers ====== */
.header2 {
  background-color:var(--ev-bg);
  height: 60px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.header-title2 {
  color: var(--ev-accent);
  font-size: 30px;
  font-weight: bold;
  text-align: center;
  margin: 0 auto;
}

.header-logo {
    margin: 0 auto;
    text-align: center;
    max-width: 40px;
}

.header-title {
    color: var(--ev-accent);
    font-size: 48px;
    font-weight: bold;
    text-align: center;
    margin: 0 auto;
}

.header-description {
    color: var(--ev-text);
    margin: 4px auto;
    text-align: center;
    max-width: 600px;
}

/* ====== Radio groups ====== */
.radio-group .form-check {
    padding-left: 0;
}

.btn-group .btn.active {
  background-color: var(--ev-accent);
}

.radio-group .btn-group > .form-check:not(:last-child) > .btn {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
  
.radio-group .btn-group > .form-check:not(:first-child) > .btn {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-left: -1px;
}

/* The year rows were laid out when the data stopped at 2021, so five
   buttons. The editions table now runs to 2024, which is eight, and at the
   old padding that bar is wider than the columns it sits in. Tightening the
   buttons keeps all eight on one line at the widths these layouts actually
   use; wrapping is the fallback for a genuinely narrow viewport, where a
   second row is better than a bar running off the edge. */
.radio-group .btn-group {
  flex-wrap: wrap;
  row-gap: 4px;
}

.radio-group .btn-group > .form-check > .btn {
  padding: 0.25rem 0.5rem;
  font-size: 0.8125rem;
  white-space: nowrap;
}

.danger {
  background-color: var(--ev-accent-soft);
  color: black;
  border-radius: 5px;
  padding-left: 5px;
}

/* ====== Main tab bar ======
   These four tabs are the dashboard's primary navigation, and people were
   missing them: they did not read as something you could click. Two reasons.
   The active rule below set background-color and color to the same var(--ev-accent),
   so the selected tab's own label was invisible against its own background.
   And the inactive tabs had no rule at all, so they rendered as bare text on
   the page with no edge, no hover and no pointer cursor: nothing that says
   "toggle". Both are fixed here. */

.nav-tabs {
  border-bottom: 2px solid var(--ev-accent);
  gap: 4px;
}

/* Inactive: reads as a real, unselected tab sitting below the active one. */
.nav-tabs .nav-link {
  cursor: pointer;
  color: var(--ev-text);
  background-color: var(--ev-bg);
  border: 1px solid var(--ev-surface-2);
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  padding: 8px 16px;
  font-weight: 500;
  transition: background-color 120ms ease, color 120ms ease;
}

.nav-tabs .nav-link:hover:not(.active) {
  background-color: var(--ev-surface-2);
  color: var(--ev-accent);
  border-color: var(--ev-accent);
}

.nav-tabs .nav-link:focus-visible {
  outline: 2px solid var(--ev-accent);
  outline-offset: 2px;
}

/* Active: ocre ground with dark text on it, so the label is legible, and
   joined to the panel below by hiding the bar underneath it. */
.nav-tabs .nav-link.active {
  background-color: var(--ev-accent) !important;
  color: var(--ev-bg) !important;
  font-weight: 700;
  border-color: var(--ev-accent);
  box-shadow: 0 -2px 6px rgba(0, 180, 216, 0.35);
}

.accordion-button {
  /* Was an accent-filled bar with white xx-large text. The section headers
     are navigation, not banners. */
  background-color: var(--ev-surface);
  color: var(--ev-text);
}

.accordion-button:not(.collapsed) {
  font-size: xx-large;
}

/* ====== Top bar ======
   The bar used to carry margin-right: 40% on .navbar .container, which is why
   it looked cut off at the sides: the container was being squeezed to 60% of
   the window while the bar's own background ran the full width. The container
   is a container-fluid now (the Navbar is built with fluid=True), it spans the
   window, and the only horizontal inset is symmetric padding. */
.navbar {
  background-color: var(--ev-bg-deep) !important;
  border-bottom: 1px solid var(--ev-surface-2);
  padding: 10px 0;
}

.navbar > .container,
.navbar > .container-fluid {
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding-left: 28px;
  padding-right: 28px;
  gap: 16px;
}

.navbar-brand{
  margin-right: 0;
  border-right: 0px;
  color: var(--ev-accent) !important;
  font-weight: 600;
  letter-spacing: 0.2px;
  font-size: 1.15rem;
}

/* ====== Top bar: brand lockup and actions ====== */
.ev-brand {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}

.ev-wordmark {
  color: var(--ev-text);
  font-size: 1.2rem;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: 0.2px;
}

.ev-attrib {
  color: var(--ev-text-muted);
  font-size: 0.76rem;
  line-height: 1.15;
}

.ev-attrib-link {
  color: var(--ev-accent);
  text-decoration: none;
  font-weight: 600;
}
.ev-attrib-link:hover { text-decoration: underline; }

.ev-nav-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Section jump buttons. Quiet by default so they do not compete with the
   content, but clearly buttons: border, hover, pointer. */
.ev-nav-btn {
  background-color: transparent;
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text);
  border-radius: var(--ev-radius);
  padding: 6px 14px;
  font-size: 0.88rem;
  font-weight: 550;
}
.ev-nav-btn:hover {
  background-color: var(--ev-surface);
  border-color: var(--ev-accent);
  color: var(--ev-accent);
}

/* The search button carries the shortcut, because a shortcut nobody can see
   is a shortcut nobody uses. */
.ev-nav-search {
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text-muted);
  border-radius: var(--ev-radius);
  padding: 6px 14px;
  font-size: 0.88rem;
  min-width: 190px;
  text-align: left;
}
.ev-nav-search:hover {
  border-color: var(--ev-accent);
  color: var(--ev-text);
  background-color: var(--ev-surface-2);
}

/* ====== Spotlight overlay ====== */
/* Sits high on the screen rather than centred: a command palette is something
   you type into immediately, so it should not move the eye to the middle of
   the page and back. */
#spotlight .modal-dialog {
  margin-top: 12vh;
}

.ev-spotlight {
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
}

.ev-spotlight-body { padding: 16px 18px; }

.ev-spotlight-hint {
  color: var(--ev-text-muted);
  font-size: 0.78rem;
  margin-top: 10px;
}

/* ====== Accordion section headers ====== */
/* These are the way into the two main sections, so they have to read as
   controls. The old rule set xx-large ocre text with no edge, which looked
   like a heading rather than something you open. */
.accordion-item {
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-radius: var(--ev-radius) !important;
  margin-bottom: 12px;
  overflow: hidden;
}

.accordion-button,
.accordion-button:not(.collapsed),
.accordion-item:last-of-type .accordion-button.collapsed {
  background-color: var(--ev-surface);
  color: var(--ev-text);
  font-size: 1.15rem;
  font-weight: 620;
  box-shadow: none;
}

.accordion-button:not(.collapsed) {
  color: var(--ev-accent);
  border-bottom: 1px solid var(--ev-surface-2);
}

.accordion-button:hover { background-color: var(--ev-surface-2); }

.accordion-button::after { filter: brightness(2.2); }

.accordion-body { background-color: var(--ev-bg); }

/* ====== Light theme ======
   Only the tokens are redefined. Every rule in this file already reads them,
   so the whole dashboard switches without a second set of rules to maintain.
   The leaf accents are darkened rather than reused: cyan #00B4D8 on white is
   too low-contrast to carry text. */
:root[data-theme="light"] {
  --ev-bg:          #F4F6FA;
  --ev-bg-deep:     #E7EBF2;
  --ev-surface:     #FFFFFF;
  --ev-surface-2:   #D9E0EB;
  --ev-text:        #1F2733;
  --ev-text-muted:  #5B6678;

  --ev-accent:      #0086A8;
  --ev-accent-soft: #CDEDF5;
  --ev-green:       #5E8F3C;
  --ev-orange:      #C4671F;
  --ev-magenta:     #A83C82;

  /* The same six hues, re-stepped for a light surface rather than reused.
     All six pass every check against #F4F6FA. */
  --ev-cat-1:       #008AB1;
  --ev-cat-2:       #984C00;
  --ev-cat-3:       #348F4F;
  --ev-cat-4:       #6652A6;
  --ev-cat-5:       #00918B;
  --ev-cat-6:       #A03F40;
  --ev-cat-dim:     #6B7488;

  --ev-shadow:      0 2px 10px rgba(31, 39, 51, 0.12);
}

.ev-theme-toggle {
  background-color: transparent;
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text);
  border-radius: var(--ev-radius);
  width: 38px;
  height: 34px;
  padding: 0;
  font-size: 1rem;
  line-height: 1;
}
.ev-theme-toggle:hover {
  border-color: var(--ev-accent);
  color: var(--ev-accent);
  background-color: var(--ev-surface);
}

/* ====== Comparison tabs, rebuilt ======
   The Bootstrap tab strip was the problem: four long sentences in a row of
   folder tabs, all the same colour, no indication of which was live until you
   read the text. These are cards instead. Each mode owns one leaf colour from
   the mark, carried on its top edge, so the four are told apart by colour and
   position before the label is read, and the selected one is filled rather
   than merely underlined. */
.nav-tabs {
  border-bottom: none;
  gap: 10px;
  display: flex;
  flex-wrap: wrap;
  padding: 4px 0 14px;
}

.nav-tabs .nav-link {
  flex: 1 1 190px;
  cursor: pointer;
  color: var(--ev-text-muted);
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-top: 3px solid var(--tab-accent, var(--ev-surface-2));
  border-radius: var(--ev-radius);
  padding: 12px 16px;
  text-align: left;
  font-size: 0.94rem;
  font-weight: 560;
  line-height: 1.3;
  box-shadow: var(--ev-shadow);
  transition: transform 120ms ease, background-color 120ms ease,
              color 120ms ease, border-color 120ms ease;
}

/* One leaf per mode, in the order they appear. */
.nav-tabs .nav-item:nth-child(1) .nav-link { --tab-accent: var(--ev-accent); }
.nav-tabs .nav-item:nth-child(2) .nav-link { --tab-accent: var(--ev-green); }
.nav-tabs .nav-item:nth-child(3) .nav-link { --tab-accent: var(--ev-orange); }
.nav-tabs .nav-item:nth-child(4) .nav-link { --tab-accent: var(--ev-magenta); }

.nav-tabs .nav-link:hover:not(.active) {
  color: var(--ev-text);
  border-color: var(--tab-accent);
  border-top-color: var(--tab-accent);
  transform: translateY(-2px);
}

/* Selected: filled with its own leaf colour, so which one is live is legible
   from across the room. */
.nav-tabs .nav-link.active {
  background-color: var(--tab-accent) !important;
  color: #10151D !important;
  border-color: var(--tab-accent);
  font-weight: 700;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--tab-accent) 40%, transparent);
}

/* ====== Spreading the other accents ======
   The dashboard was cyan-on-navy and nothing else, which made every control
   look equally important. The remaining three leaves are put to work here on
   things that are genuinely different kinds of thing. */

/* Each section gets a leaf, matching its navbar button.

   Keyed off the section's own class rather than its position. These were
   :nth-of-type(1..3), so adding Top 10 as the second section gave Trends the
   colour of Compare and left Compare with none, while the navbar buttons
   below kept theirs: the two halves of the same cue disagreed. There are
   four sections now and the logo has four leaves. */
.ev-section-explore .accordion-button:not(.collapsed) {
  color: var(--ev-accent);
  box-shadow: none;
}
.ev-section-top10 .accordion-button:not(.collapsed) {
  color: var(--ev-magenta);
  box-shadow: none;
}
.ev-section-trends .accordion-button:not(.collapsed) {
  color: var(--ev-green);
  box-shadow: none;
}
.ev-section-compare .accordion-button:not(.collapsed) {
  color: var(--ev-orange);
  box-shadow: none;
}

#jump-explore:hover { border-color: var(--ev-accent); color: var(--ev-accent); }
#jump-top10:hover   { border-color: var(--ev-magenta); color: var(--ev-magenta); }
#jump-trends:hover  { border-color: var(--ev-green);  color: var(--ev-green); }
#jump-compare:hover { border-color: var(--ev-orange); color: var(--ev-orange); }

/* Career vs single-year is a binary choice, so it gets orange to separate it
   from the year picker's cyan sitting next to it. */
#careerORSingleYrRadio_home .btn.active,
[id^="careerORSingleYr"] .btn.active {
  background-color: var(--ev-orange) !important;
  border-color: var(--ev-orange) !important;
  color: #10151D !important;
}

/* The year picker keeps cyan: it is the primary selection on the page. */
.year-picker .btn-group > .form-check > .btn.active {
  background-color: var(--ev-accent) !important;
  border-color: var(--ev-accent) !important;
  color: #10151D !important;
}

/* The info/summary callout uses magenta, the one leaf not yet spoken for. */
.danger {
  background-color: var(--ev-surface);
  color: var(--ev-text);
  border-radius: var(--ev-radius);
  padding: 10px 14px;
  box-shadow: var(--ev-shadow);
}

/* ====== Rendered formula ======
   Was a fixed 1000px PNG that overflowed narrow columns and could not be
   selected, searched or re-themed. MathJax renders it as text now, so it
   scales and takes the theme's foreground colour. */
.ev-formula {
  color: var(--ev-text);
  overflow-x: auto;
  padding: 10px 4px;
  font-size: 1.02rem;
}
.ev-formula mjx-container { color: var(--ev-text) !important; }

/* ====== Page ground ======
   This used to be an inline backgroundColor on the container, which beat the
   stylesheet and made the light theme impossible. It is a class now, so the
   ground follows the tokens like everything else. */
.ev-page {
  background-color: var(--ev-bg);
  color: var(--ev-text);
}

/* ====== More info ======
   Was an emoji-prefixed button in a bare class, sitting on a different
   baseline from the centred controls beside it. Same height and radius as the
   navbar buttons, vertically centred in its column by the row. */
.ev-info-btn {
  background-color: transparent;
  border: 1px solid var(--ev-orange);
  color: var(--ev-orange);
  border-radius: var(--ev-radius);
  padding: 6px 16px;
  height: 36px;
  font-size: 0.88rem;
  font-weight: 600;
  white-space: nowrap;
}
.ev-info-btn:hover {
  background-color: var(--ev-orange);
  border-color: var(--ev-orange);
  color: #10151D;
}

/* ====== Spotlight, Apple-style ======
   One borderless line of large text, a short result list under it, and no
   visible form chrome. */
#spotlight .modal-dialog { margin-top: 14vh; max-width: 640px; }

.ev-spotlight {
  background-color: color-mix(in srgb, var(--ev-surface) 92%, transparent);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid var(--ev-surface-2);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}

.ev-spotlight-body { padding: 6px 10px 10px; }

.ev-spotlight-input {
  width: 100%;
  background: transparent;
  border: none;
  outline: none;
  box-shadow: none;
  color: var(--ev-text);
  font-size: 1.6rem;
  font-weight: 400;
  padding: 14px 10px;
  line-height: 1.3;
}
.ev-spotlight-input::placeholder { color: var(--ev-text-muted); opacity: 0.8; }
.ev-spotlight-input:focus { outline: none; box-shadow: none; }

/* A search field with no magnifier reads as a text box that happens to be
   large. Same glyph and the same idiom as the in-tab author search, scaled to
   this field's type size. */
.ev-spotlight-input {
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' \
fill='none' stroke='%23A8B2C4' stroke-width='2' stroke-linecap='round' \
stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>");
  background-repeat: no-repeat;
  background-position: 14px center;
  background-size: 22px 22px;
  padding-left: 48px;
}

.ev-spotlight-results {
  max-height: 46vh;
  overflow-y: auto;
  margin-top: 2px;
}
.ev-spotlight-results:not(:empty) {
  border-top: 1px solid var(--ev-surface-2);
  padding-top: 6px;
}

/* Results are buttons so they are reachable by keyboard and announced as
   controls, but drawn as plain rows. */
.ev-spotlight-hit {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--ev-text);
  padding: 10px 12px;
  font-size: 0.98rem;
  cursor: pointer;
}
.ev-spotlight-hit:hover,
.ev-spotlight-hit:focus-visible {
  background-color: var(--ev-accent);
  color: #10151D;
  outline: none;
}

.ev-spotlight-empty,
.ev-spotlight-hint {
  color: var(--ev-text-muted);
  font-size: 0.78rem;
  padding: 8px 12px 2px;
  display: flex;
  justify-content: space-between;
}

.ev-spotlight-esc {
  border: 1px solid var(--ev-surface-2);
  border-radius: 5px;
  padding: 0 6px;
  font-size: 0.72rem;
}

/* ====== Formula ======
   MathJax lays the six terms out on one line, which is wider than the column
   on most screens. Letting it shrink to fit beats a horizontal scrollbar on a
   single equation. */
.ev-formula {
  color: var(--ev-text);
  padding: 12px 4px;
  text-align: center;
}
.ev-formula mjx-container {
  color: var(--ev-text) !important;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
}
.ev-formula mjx-container[display] { margin: 0 !important; }

/* Below roughly a tablet the equation cannot fit at full size, so scale it
   down rather than clip it. */

/* ==========================================================================
   Rebuilt top bar and control toolbar.
   These override the earlier blocks above by coming later in the file; the
   markup they target was rewritten, so the old rules no longer match
   anything that exists.
   ========================================================================== */

/* ====== Top bar ======
   One row, three groups, one height. Everything is 36px so it shares a
   baseline, and the bar spans the window with symmetric padding rather than
   the margin-right:40% that made it look clipped at the sides. */
.navbar {
  background-color: var(--ev-bg-deep) !important;
  border-bottom: 1px solid var(--ev-surface-2);
  padding: 0;
  min-height: 64px;
}

.ev-navbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0 28px;
  min-height: 64px;
}

.ev-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  flex: 0 0 auto;
}

.ev-mark { height: 34px; width: 34px; display: block; }

.ev-brand-text { display: flex; flex-direction: column; line-height: 1.18; }

.ev-wordmark {
  color: var(--ev-text);
  font-size: 1.12rem;
  font-weight: 650;
  letter-spacing: 0.1px;
}

.ev-tagline {
  color: var(--ev-text-muted);
  font-size: 0.72rem;
  letter-spacing: 0.2px;
}

.ev-nav-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

/* A hairline between groups, so the right side reads as three things rather
   than one run of buttons. */
.ev-nav-sep {
  width: 1px;
  height: 22px;
  background-color: var(--ev-surface-2);
  margin: 0 4px;
}

.ev-nav-btn,
.ev-nav-search,
.ev-theme-toggle {
  height: 36px;
  display: inline-flex;
  align-items: center;
  border-radius: 9px;
  font-size: 0.86rem;
  font-weight: 550;
  line-height: 1;
}

.ev-nav-btn {
  background-color: transparent;
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text);
  padding: 0 14px;
}
.ev-nav-btn:hover {
  background-color: var(--ev-surface);
  border-color: var(--ev-accent);
  color: var(--ev-accent);
}

/* The search reads as a field rather than a button, because a field is what
   it opens. */
.ev-nav-search {
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text-muted);
  padding: 0 10px 0 14px;
  gap: 14px;
  min-width: 230px;
  justify-content: space-between;
}
.ev-nav-search:hover {
  background-color: var(--ev-surface-2);
  border-color: var(--ev-accent);
  color: var(--ev-text);
}
.ev-search-label { font-weight: 500; }

.ev-kbd {
  border: 1px solid var(--ev-surface-2);
  background: transparent;
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 0.72rem;
  color: inherit;
}

.ev-theme-toggle {
  background-color: transparent;
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text);
  width: 36px;
  justify-content: center;
  padding: 0;
  font-size: 1rem;
}
.ev-theme-toggle:hover {
  border-color: var(--ev-accent);
  color: var(--ev-accent);
  background-color: var(--ev-surface);
}


@media (max-width: 980px) {
  .ev-navbar-inner { flex-wrap: wrap; padding: 10px 16px; gap: 10px; }
  .ev-nav-search { min-width: 0; }
  .ev-search-label, .ev-nav-sep { display: none; }
}

/* ====== Control toolbar ======
   Four bare widgets centred side by side with no labels and no gaps is why
   this read as jammed. One card, generous gaps, and a caption over each
   control so it says what it is. */
.ev-stage { padding: 18px 24px 0; }

.ev-toolbar {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 22px;
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-radius: 14px;
  padding: 14px 18px;
  margin-bottom: 16px;
  box-shadow: var(--ev-shadow);
}

.ev-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.ev-field-grow { flex: 0 1 auto; }   /* was 1 1 320px: it stretched the
                                        year row and pushed the statistic
                                        control to the far edge */

.ev-field-label {
  color: var(--ev-text-muted);
  font-size: 0.68rem;
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  margin: 0;
}

.ev-toolbar-end { margin-left: auto; align-self: flex-end; }
.ev-field #stats2 { min-width: 210px; }

/* ====== Panes ====== */
.ev-panes { margin: 0; }

.ev-card {
  background-color: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-radius: 14px;
  padding: 14px;
  box-shadow: var(--ev-shadow);
  height: 100%;
}


/* ====== Charts follow the theme ======
   Plotly bakes colours into the figure server-side, so a chart cannot follow
   a switch that happens in the browser, and regenerating every figure on
   toggle would mean threading a theme input through every callback in every
   layout module. But Plotly renders SVG, and SVG text takes a CSS fill, so
   the chrome of a chart is restyled here instead. Backgrounds are already
   transparent, so the page shows through. Data colours are deliberately left
   alone: those carry meaning, and a bar that changed colour with the theme
   would be telling a different story. */
.js-plotly-plot .xtick text,
.js-plotly-plot .ytick text,
.js-plotly-plot .gtitle,
.js-plotly-plot .g-xtitle text,
.js-plotly-plot .g-ytitle text,
.js-plotly-plot .xtitle,
.js-plotly-plot .ytitle,
.js-plotly-plot .infolayer .legend text,
.js-plotly-plot .annotation-text,
.js-plotly-plot .cbaxis text,
.js-plotly-plot .colorbar text {
  fill: var(--ev-text) !important;
}

.js-plotly-plot .annotation .annotation-text { font-weight: 600; }

.js-plotly-plot .xgrid,
.js-plotly-plot .ygrid,
.js-plotly-plot .gridlayer path {
  stroke: var(--ev-surface-2) !important;
  stroke-opacity: 0.55 !important;
}

.js-plotly-plot .xaxislayer-above path,
.js-plotly-plot .yaxislayer-above path,
.js-plotly-plot .zerolinelayer path {
  stroke: var(--ev-surface-2) !important;
}

.js-plotly-plot .legend .bg,
.js-plotly-plot .hoverlayer .hovertext rect {
  fill: var(--ev-surface) !important;
  stroke: var(--ev-surface-2) !important;
}
.js-plotly-plot .hoverlayer .hovertext text,
.js-plotly-plot .hoverlayer .hovertext .name {
  fill: var(--ev-text) !important;
}

.js-plotly-plot .modebar-btn path { fill: var(--ev-text-muted) !important; }
.js-plotly-plot .modebar-btn:hover path { fill: var(--ev-accent) !important; }
.js-plotly-plot .modebar-group { background: transparent !important; }

.js-plotly-plot .geo .bg { fill: transparent !important; }

/* ==========================================================================
   Full-bleed shell.
   The page is a dbc.Container(fluid=True), which is a Bootstrap
   container-fluid and carries a horizontal gutter. That gutter is why the top
   bar could not reach the window edges however its own padding was set: the
   bar was already inset by its parent. The shell is zero-padding now and each
   section supplies its own inset instead.
   ========================================================================== */
.ev-shell {
  padding-left: 0 !important;
  padding-right: 0 !important;
  max-width: 100% !important;
  /* No overflow here. position:sticky is cancelled by an overflow value on
     any ancestor, and overflow-x: hidden on this element is what stopped the
     top bar sticking. Wide content is handled where it occurs instead. */
}

/* The bar spans the shell edge to edge; only its inner row is inset. */
.navbar { width: 100%; }

/* Sections that used to inherit the container's gutter now ask for it. */
.ev-shell > .ev-stage { padding: 18px 24px 0; }
.ev-shell > hr,
.ev-shell > .row { margin-left: 24px; margin-right: 24px; }
.ev-shell > footer { padding: 0 24px; }

/* ====== Brand ======
   Wordmark with the attribution beneath it, which is where it belongs: it
   says who made the thing named directly above it. */
.ev-brand { align-items: center; }

.ev-wordmark {
  color: var(--ev-text);
  text-decoration: none;
  font-size: 1.12rem;
  font-weight: 650;
  letter-spacing: 0.1px;
}
.ev-wordmark:hover { color: var(--ev-accent); }

.ev-tagline {
  color: var(--ev-text-muted);
  font-size: 0.72rem;
  letter-spacing: 0.1px;
}

.ev-attrib-link {
  color: var(--ev-accent);
  text-decoration: none;
  font-weight: 600;
}
.ev-attrib-link:hover { text-decoration: underline; }

/* ====== Panes ======
   The summary column is long-form prose, not a widget, so it is left to flow
   at its natural height. Boxing it at a fixed height clipped the text and
   forced it to match the map, which is what broke this layout. */
.ev-panes { margin: 0; }
.ev-panes > [class*="col"] { padding-left: 0; padding-right: 14px; }
.ev-panes > [class*="col"]:last-child { padding-right: 0; padding-left: 14px; }

/* ==========================================================================
   Controls, rebuilt.
   The dropdowns were a near-white box with a 2px cyan border, centred text
   and a black placeholder: a light-theme control dropped into a dark page,
   which is why they read as dated.

   The important constraint, learned the hard way: dcc.Dropdown is
   react-select v1, whose control is a display:table with an absolutely
   positioned value/placeholder and a table-cell arrow zone. Forcing
   display:flex on it makes the value and placeholder paint on top of each
   other and drops the chevron entirely. So this restyles surfaces, borders,
   radius and colour only, and leaves react-select's own box model alone.
   ========================================================================== */

.Select-control {
  background-color: var(--ev-bg-deep) !important;
  border: 1px solid var(--ev-surface-2) !important;
  border-radius: 10px !important;
  color: var(--ev-text) !important;
  height: 44px !important;
  text-align: left !important;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.Select-control:hover { border-color: var(--ev-text-muted) !important; }

/* Focus is the only place the accent appears, as a soft ring rather than a
   heavier border, so the control does not change weight when clicked. */
.is-focused:not(.is-open) > .Select-control,
.is-open > .Select-control {
  background-color: var(--ev-bg-deep) !important;
  border-color: var(--ev-accent) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ev-accent) 22%, transparent) !important;
}

/* Value and placeholder are absolutely positioned by react-select; only the
   line-height needs to follow the taller control so the text sits centred. */
.Select-placeholder,
.Select--single > .Select-control .Select-value {
  line-height: 42px !important;
  padding-left: 14px !important;
  padding-right: 34px !important;
  text-align: left;
}

.Select-placeholder { color: var(--ev-text-muted) !important; }

.Select-value-label,
.has-value.Select--single > .Select-control .Select-value .Select-value-label {
  color: var(--ev-text) !important;
  font-weight: 500;
}

/* react-select renders one of these at a time, but a stale placeholder behind
   a chosen value is exactly the double-text artefact above. Belt and braces. */
.has-value > .Select-control .Select-placeholder { display: none !important; }

.Select-input { height: 42px; padding-left: 14px; }
.Select-input > input {
  color: var(--ev-text) !important;
  line-height: 24px;
  padding: 9px 0;
}
.is-focused .Select-input > input { color: var(--ev-text) !important; }

/* Left as a table-cell, which is what makes the chevron appear at all. */
.Select-arrow-zone { padding-right: 12px; }
.Select-arrow {
  border-color: var(--ev-text-muted) transparent transparent;
  border-width: 6px 5px 0;
}
.is-open .Select-arrow { border-color: transparent transparent var(--ev-accent); }

.Select-clear-zone { color: var(--ev-text-muted); }
.Select-clear-zone:hover { color: var(--ev-magenta); }

/* The menu is a floating panel, so it gets the panel treatment. */
.Select-menu-outer {
  background-color: var(--ev-surface) !important;
  color: var(--ev-text) !important;
  border: 1px solid var(--ev-surface-2) !important;
  border-radius: 12px !important;
  margin-top: 6px;
  padding: 6px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.38);
  text-align: left;
  overflow: hidden;
}

.Select-menu { max-height: 300px; }

.Select-option {
  background-color: transparent !important;
  color: var(--ev-text) !important;
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 0.94rem;
}
.Select-option.is-focused {
  background-color: var(--ev-surface-2) !important;
  color: var(--ev-text) !important;
}
.Select-option.is-selected {
  background-color: var(--ev-accent) !important;
  color: #10151D !important;
  font-weight: 600;
}
.Select-noresults { color: var(--ev-text-muted) !important; padding: 10px 12px; }

.Select--multi .Select-value {
  background-color: color-mix(in srgb, var(--ev-accent) 18%, transparent) !important;
  border: 1px solid var(--ev-accent) !important;
  border-radius: 7px !important;
  color: var(--ev-text) !important;
  font-size: 0.86em;
  line-height: 1.6 !important;
  margin: 6px 4px 0 0;
}
.Select--multi .Select-value-icon {
  border-right: 1px solid var(--ev-accent) !important;
  color: var(--ev-text);
}
.Select--multi .Select-value-icon:hover {
  background-color: var(--ev-magenta) !important;
  color: #10151D;
}

/* ==========================================================================
   Breathing room.
   The complaint was density, and density here came from controls sitting
   directly against each other and against the panel edges. These are the
   gaps, not new structure.
   ========================================================================== */
.ev-shell > .ev-stage { padding: 24px 32px 0; }

.ev-toolbar {
  gap: 28px;
  padding: 18px 22px;
  margin-bottom: 22px;
}

.ev-field { gap: 9px; }
.ev-field-label { font-size: 0.7rem; letter-spacing: 0.1em; }

.ev-panes > [class*="col"] { padding-right: 22px; }
.ev-panes > [class*="col"]:last-child { padding-left: 22px; padding-right: 0; }

/* The summary column is prose; it was set at the body default and ran tight. */
#cntrylabel, #worldtitle { line-height: 1.62; font-size: 0.95rem; }
#worldtitle h3, #worldtitle h4 { margin-top: 1.1em; margin-bottom: 0.5em; }
#worldtitle p { margin-bottom: 0.9em; }

.ev-shell > hr {
  margin-top: 28px;
  margin-bottom: 28px;
  border-color: var(--ev-surface-2);
  opacity: 1;
}

.accordion-item { margin-bottom: 16px; }
.accordion-button { padding: 18px 22px; }
.accordion-body { padding: 22px; }

.nav-tabs { gap: 12px; padding: 6px 0 18px; }
.nav-tabs .nav-link { padding: 14px 18px; }

/* The year picker sat flush against the labels above and below it. */
.year-picker .btn-group { padding: 4px 0; }
.year-picker .btn-group > .form-check > .btn { padding: 8px 14px; }

/* ==========================================================================
   Fixes from looking at the rendered page rather than at the markup.
   ========================================================================== */

/* The toolbar captions sat at three different heights, because the row was
   bottom-aligned and the three controls are different heights. Align the row
   to the top and give every caption the same block, so the captions line up
   and the controls hang from one baseline. */
.ev-toolbar { align-items: flex-start; }
.ev-field-label {
  height: 14px;
  line-height: 14px;
  display: block;
}
.ev-field { justify-content: flex-start; }
.ev-toolbar-end { align-self: center; padding-top: 18px; }

/* The dataset toggle was a pair of tiny buttons next to a row of much larger
   year buttons, so the two controls read as different systems. */
[id^="careerORSingleYr"] .btn {
  padding: 8px 16px;
  font-size: 0.9rem;
}

/* The active tab was outlined but not filled: the fill rule lost to
   Bootstrap's own .nav-link.active further up the cascade. Raising it here
   also drops the coloured top edge on the selected card, which was reading as
   a second, competing indicator. */
.nav-tabs .nav-link.active,
.nav-tabs .nav-item .nav-link.active {
  background-color: var(--tab-accent) !important;
  border-color: var(--tab-accent) !important;
  color: #10151D !important;
}

/* A 2px accent rectangle drawn around the whole tab body. It fought the cards
   above it and boxed in content that does not need a box. */
.tab-content {
  border: none;
  border-radius: 0;
  padding-top: 18px;
}

/* ====== Plotly's own controls ======
   The play/stop buttons and the animation slider are drawn by Plotly from the
   figure's ocre, which survived the palette change because they are figure
   properties rather than CSS. They are SVG, so they can be restyled here with
   everything else. */
.js-plotly-plot .updatemenu-button rect,
.js-plotly-plot .slider-rail-touch-rect,
.js-plotly-plot .slider-rail-rect {
  fill: var(--ev-surface-2) !important;
  stroke: none !important;
}
.js-plotly-plot .updatemenu-button:hover rect { fill: var(--ev-accent) !important; }
.js-plotly-plot .updatemenu-button text,
.js-plotly-plot .slider-label-text,
.js-plotly-plot .slider-tick-text {
  fill: var(--ev-text) !important;
}
.js-plotly-plot .slider-grip-rect { fill: var(--ev-accent) !important; }
.js-plotly-plot .slider-tick-rect { fill: var(--ev-text-muted) !important; }

/* The colourbar frame and its title were drawn against the old ground. */
.js-plotly-plot .colorbar .cbbg { fill: transparent !important; }
.js-plotly-plot .colorbar .cbtitle text { fill: var(--ev-text) !important; }

/* ==========================================================================
   Comparison tabs, third attempt, from looking at them rendered.
   The card version was wrong: four dark rectangles each capped with a
   different neon edge read as decoration competing with the content, the
   rainbow assigned meaning where there is none (these are four views of the
   same thing, not four categories), and the selected card never actually
   filled, so the one job the styling had went undone.
   A segmented control instead: one track, one accent, the selected segment
   filled. It is the pattern people already read as "pick one of these".
   ========================================================================== */

.nav-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  background-color: var(--ev-bg-deep);
  border: 1px solid var(--ev-surface-2);
  border-bottom: 1px solid var(--ev-surface-2);
  border-radius: 12px;
  padding: 4px;
  margin-bottom: 20px;
}

.nav-tabs .nav-item { display: flex; }

/* Reset everything the card version set, including the per-tab accent. */
.nav-tabs .nav-link,
.nav-tabs .nav-item .nav-link {
  --tab-accent: var(--ev-accent);
  flex: 0 0 auto;
  cursor: pointer;
  background-color: transparent !important;
  border: none !important;
  border-radius: 9px !important;
  color: var(--ev-text-muted) !important;
  padding: 9px 18px !important;
  font-size: 0.92rem;
  font-weight: 560;
  line-height: 1.2;
  text-align: center;
  box-shadow: none !important;
  transform: none !important;
  transition: background-color 120ms ease, color 120ms ease;
}

.nav-tabs .nav-link:hover:not(.active),
.nav-tabs .nav-item .nav-link:hover:not(.active) {
  background-color: var(--ev-surface-2) !important;
  color: var(--ev-text) !important;
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item .nav-link.active {
  background-color: var(--ev-accent) !important;
  color: #10151D !important;
  font-weight: 680;
  box-shadow: none !important;
}

.nav-tabs .nav-link:focus-visible {
  outline: 2px solid var(--ev-accent);
  outline-offset: 2px;
}

@media (max-width: 720px) {
  .nav-tabs { display: flex; width: 100%; }
  .nav-tabs .nav-item, .nav-tabs .nav-link { flex: 1 1 auto; }
}

/* ==========================================================================
   Kill SLATE's gradients.
   This is why the selected tab stayed grey however hard the rule shouted:
   getComputedStyle reported the cyan background-color correctly, but
   Bootstrap SLATE paints a linear-gradient background-IMAGE over buttons,
   nav links, the navbar and accordion headers, and an image covers a colour.
   It is also why the controls looked plasticky and dated in general: every
   one of them carried a 2010-era vertical gradient. Flat everywhere.
   ========================================================================== */
.btn,
.btn:hover,
.btn:focus,
.btn:active,
.btn.active,
.nav-link,
.nav-tabs .nav-link,
.nav-tabs .nav-link.active,
.navbar,
.accordion-button,
.accordion-button:not(.collapsed),
.card,
.modal-content,
.dropdown-menu,
.form-control,
.Select-control,
.Select-menu-outer,
.list-group-item,
.page-link {
  background-image: none !important;
}

/* SLATE also gives buttons an inset highlight and a text shadow, which read
   as embossing. Both go with the gradients. */
.btn, .nav-tabs .nav-link, .accordion-button {
  text-shadow: none !important;
}
.btn:not(.ev-info-btn):not(.ev-nav-btn):not(.ev-nav-search):not(.ev-theme-toggle) {
  box-shadow: none;
}

/* ==========================================================================
   Segmented radio rows (dataset toggle, year picker)
   ========================================================================== */

/* 1. "Career" and "Single year" are different lengths, so the two segments
      came out different widths and the control looked lopsided. A shared
      minimum makes them a matched pair; the longer label still sets the
      width if it needs more. */
[id^="careerORSingleYr"] .btn,
[id^="careerORSingle"] .btn {
  min-width: 104px;
  justify-content: center;
}

/* 2. In light theme these were invisible. The labels are Bootstrap
      .btn-outline-primary, whose colour comes from SLATE and is tuned for a
      dark ground, so on a light background it was near-white on white. Both
      rows take the theme's own foreground now, in both themes, and only the
      selected segment departs from it. */
.year-picker .btn,
[id^="careerORSingleYr"] .btn,
[id^="careerORSingle"] .btn,
[id^="selectYrRadio"] .btn {
  color: var(--ev-text) !important;
  background-color: transparent !important;
  border-color: var(--ev-surface-2) !important;
}

.year-picker .btn:hover:not(.active),
[id^="careerORSingleYr"] .btn:hover:not(.active),
[id^="selectYrRadio"] .btn:hover:not(.active) {
  background-color: var(--ev-surface-2) !important;
  color: var(--ev-text) !important;
}

/* A disabled year (single-year has no 2018) must still read as disabled in
   both themes, not merely faint. */
.year-picker .btn:disabled,
[id^="selectYrRadio"] .btn:disabled {
  color: var(--ev-text-muted) !important;
  opacity: 0.45;
}

/* 3. The control rows sat flush against the search box above them. */
[id^="selectYrRadio"],
.year-picker,
[id^="careerORSingleYr"],
[id^="careerORSingle"] {
  margin-top: 14px;
}

/* ==========================================================================
   4. The author search box
   Centred text with a magnifier in front of it, so it reads as a search
   field rather than as a form control that happens to hold a name.
   Scoped to the author/group pickers by id, so the small statistic dropdown
   in the toolbar keeps its left-aligned label.
   ========================================================================== */
.Select.is-searchable .Select-control {
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' \
fill='none' stroke='%23A8B2C4' stroke-width='2' stroke-linecap='round' \
stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: 16px center !important;
  background-size: 18px 18px !important;
}

/* The icon is a background-image, and the gradient-killer above sets
   background-image: none on .Select-control, so it has to be re-allowed for
   exactly these. The two rules are adjacent on purpose. */

.Select.is-searchable .Select-placeholder,
.Select.is-searchable .Select--single > .Select-control .Select-value,
.is-searchable.Select--single > .Select-control .Select-value {
  text-align: center !important;
  padding-left: 44px !important;
  padding-right: 44px !important;
}

.Select.is-searchable .Select-input {
  padding-left: 44px;
  width: 100%;
}
.Select.is-searchable .Select-input > input { text-align: center; width: 100%; }

/* The menu stays left-aligned: a centred list of names is hard to scan. */
.Select-menu-outer,
.Select-option { text-align: left !important; }

/* The spacing above the selection rows is for the panels, where those rows
   sit directly under a search box. In the toolbar the same controls already
   have a caption above them, and the extra margin pushed the year row out of
   line with the dataset row beside it. */
.ev-field [id^="selectYrRadio"],
.ev-field [id^="careerORSingleYr"],
.ev-field .year-picker,
.ev-field.ev-field { margin-top: 0; }

.ev-toolbar .radio-group { margin-top: 0 !important; }

/* In the panels the dataset toggle and the year row are two Bootstrap columns
   side by side, and they were landing on different baselines because each
   wrapper brought its own spacing. Centre them against each other so the two
   halves of one choice read as one row. */
.ev-panel-controls,
.radio-group { display: flex; align-items: center; }

[id^="careerORSingleYrA"],
[id^="selectYrRadioA"] { margin-top: 14px; }

/* The statistic select in the home toolbar is a short value list, not a
   search, so it keeps a plain left-aligned label and no magnifier. */
#stats2 .Select-control { background-image: none !important; }
#stats2 .Select-placeholder,
#stats2 .Select--single > .Select-control .Select-value {
  text-align: left !important;
  padding-left: 14px !important;
  padding-right: 34px !important;
}
#stats2 .Select-input { padding-left: 14px; }
#stats2 .Select-input > input { text-align: left; }

/* The panel toolbars are the same control group as the home one, but they sit
   inside an already-carded panel, so they carry no second card of their own. */
.ev-panel-toolbar {
  background-color: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 18px 0 6px;
  justify-content: center;
  gap: 28px;
}
.ev-panel-toolbar .radio-group { margin-top: 0 !important; }

/* The two halves of the dataset toggle have labels of different lengths, so a
   shared minimum width still left them unequal whenever one label needed more
   than the minimum. Splitting the track equally makes them the same width
   whatever the labels say. */
[id^="careerORSingleYr"].btn-group,
[id^="careerORSingle"].btn-group {
  display: inline-flex;
  width: auto;
}
[id^="careerORSingleYr"].btn-group > .form-check,
[id^="careerORSingle"].btn-group > .form-check {
  flex: 1 1 0;
  min-width: 118px;
}
[id^="careerORSingleYr"].btn-group > .form-check > .btn,
[id^="careerORSingle"].btn-group > .form-check > .btn {
  width: 100%;
  min-width: 0;
}

/* ====== Intro panel ======
   It is a Bootstrap Offcanvas, which brings its own light-on-dark palette
   from SLATE, so in the light theme its text was invisible. It takes the
   theme's tokens like every other surface now. */
.ev-intro,
.offcanvas {
  background-color: var(--ev-surface) !important;
  color: var(--ev-text) !important;
  border-right: 1px solid var(--ev-surface-2);
}

.ev-intro .offcanvas-header,
.offcanvas-header {
  border-bottom: 1px solid var(--ev-surface-2);
  padding: 18px 22px;
}

.ev-intro .offcanvas-title,
.offcanvas-title {
  color: var(--ev-text) !important;
  font-size: 1.05rem;
  font-weight: 650;
}

.ev-intro .offcanvas-body,
.offcanvas-body {
  color: var(--ev-text) !important;
  padding: 22px;
  line-height: 1.62;
}

.offcanvas-body h4 {
  color: var(--ev-text);
  font-size: 1.25rem;
  font-weight: 650;
  margin-bottom: 6px;
}

.offcanvas-body a { color: var(--ev-accent); }
.offcanvas-body hr { border-color: var(--ev-surface-2); opacity: 1; }

/* Inline code in the panel was bright pink on dark from SLATE. */
.offcanvas-body code {
  background-color: var(--ev-bg-deep);
  color: var(--ev-accent);
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 0.88em;
}

/* The byline was an #### heading, the same size as the panel's own title, so
   three names shouted louder than the section they belong to. */
.ev-byline {
  color: var(--ev-orange);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.1px;
  margin-bottom: 2px;
}

/* Bootstrap's close button is a dark SVG, invisible on a dark panel. */
.offcanvas .btn-close {
  filter: invert(1) grayscale(1) brightness(2);
  opacity: 0.7;
}
.offcanvas .btn-close:hover { opacity: 1; }
:root[data-theme="light"] .offcanvas .btn-close { filter: none; }

/* ==========================================================================
   The dataset/year picker
   One track holding both halves of a single choice: which series on the left,
   which edition of it on the right, divided by a hairline. Previously these
   were two separately captioned controls, which read as unrelated.
   ========================================================================== */
/* ==========================================================================
   The edition picker
   ==========================================================================
   Two questions in one track: which dataset (career or single year), and
   which edition of it. It used to be two rows of bordered buttons that wrapped
   onto a second line, with a solid orange pill on one side and a solid cyan
   one on the other.

   It is a segmented control now. The selected option is marked by ONE pill
   that slides between segments rather than by a background on each button,
   which is the difference between a row of buttons and a control: the motion
   is what tells a reader the two halves are each a single choice. The pill is
   positioned by assets/segmented.js; everything else here is static, so the
   control is still usable and still legible if that script never runs.
   ========================================================================== */
.ev-picker {
  display: inline-flex;
  align-items: stretch;
  gap: 0;
  background-color: color-mix(in srgb, var(--ev-bg-deep) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--ev-surface-2) 55%, transparent);
  border-radius: 10px;
  padding: 3px;
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  max-width: 100%;
  overflow: hidden;
}

/* The wrappers never wrap: a segmented control that reflows onto a second
   line stops reading as one choice. */
.ev-picker-left,
.ev-picker-right {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
}
.ev-picker-right {
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
}
.ev-picker-right::-webkit-scrollbar { display: none; }

.ev-picker-sep {
  width: 1px;
  align-self: stretch;
  margin: 4px 8px;
  background-color: color-mix(in srgb, var(--ev-surface-2) 70%, transparent);
  flex: 0 0 1px;
}

/* ====== The selection pill ======
   A flat filled rectangle, the way a segmented control has always worked:
   the track is recessed, the selected segment is the raised surface, and
   there is no border and no glow. The earlier version had both and looked
   like a toy.

   It is a pseudo-element on the BUTTON GROUP, not on the wrapper. The wrapper
   is the scroll container, so a pill positioned against it stayed put while
   the years scrolled underneath and ended up marking the wrong one. The group
   is the thing that scrolls, so a pill inside it travels with the segment it
   marks. Absolute positioning takes it out of the flex flow, so it adds no
   column of its own.

   Only custom properties are written from script (assets/segmented.js), so
   nothing is inserted into a tree React manages. Until it runs the pill has
   zero width and is invisible, and the checked label's own colour carries the
   selection on its own. */
.ev-picker .btn-group::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  height: 28px;
  width: var(--seg-w, 0px);
  transform: translate(var(--seg-x, 0px), -50%);
  border-radius: 7px;
  pointer-events: none;
  opacity: var(--seg-o, 0);
  background: var(--ev-surface);
  /* One hairline of lift, which is what separates the raised segment from the
     recessed track. Not a shadow effect. */
  box-shadow: 0 1px 2px color-mix(in srgb, #000000 20%, transparent);
  transition: transform .28s cubic-bezier(.32, .72, 0, 1),
              width .28s cubic-bezier(.32, .72, 0, 1),
              opacity .15s ease;
  z-index: 0;
}

.ev-picker .btn-group {
  border-radius: 0;
  flex-wrap: nowrap;
  /* The positioning context for the pill above. */
  position: relative;
  /* Two rules elsewhere put 14px above these radio rows, from when each was
     its own row under the search box. Inside the track that is padding on one
     side only: it made the picker taller than the search box beside it and sat
     the segments low in their own track.

     The 4px of vertical padding here and Bootstrap's 2px under each
     .form-check are the rest of that difference: 36 + 8 + 2 made the inner
     block 46 where the track expects 36. */
  margin: 0 !important;
  padding: 0 !important;
}
.ev-picker .btn-group > .form-check {
  margin: 0 !important;
  min-height: 0;
}
.ev-picker .radio-group { margin: 0 !important; }

.ev-picker .btn,
.ev-picker .btn-group > .form-check > .btn {
  border: none !important;
  border-radius: 7px !important;
  margin: 0 !important;
  /* 36 + 3 + 3 padding + 1 + 1 border = 44, the height of a .Select-control,
     so the picker and the search box beside it are the same object. */
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px !important;
  background-color: transparent !important;
  color: var(--ev-text-muted) !important;
  font-weight: 500;
  font-size: .82rem;
  white-space: nowrap;
  /* Above the pill, which is at z-index 0 on their shared parent. */
  position: relative;
  z-index: 1;
  transition: color .18s ease;
}

.ev-picker .btn:hover:not(.active):not(:disabled) {
  color: var(--ev-text) !important;
}

.ev-picker .btn:disabled {
  color: var(--ev-text-muted) !important;
  opacity: 0.32;
}

/* Every year segment is the same width, so the row reads as a timeline and
   the pill travels a regular distance. The first label carries a "TO"/"IN"
   prefix and is the widest, which sets the measure. */
.ev-picker-right .btn-group > .form-check > .btn { min-width: 52px; }
.ev-picker-left .btn-group > .form-check > .btn { min-width: 76px; }

/* ==========================================================================
   Glass
   Translucent, blurred surfaces over the page rather than flat opaque blocks.
   Applied to the layers that genuinely float above content: the top bar, the
   toolbar, the spotlight, menus and the intro panel. Cards that hold body
   text stay opaque, because text over a blurred background is harder to read
   and this is a reading surface as much as a control surface.
   ========================================================================== */
.navbar {
  background-color: color-mix(in srgb, var(--ev-bg-deep) 7%, transparent) !important;
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}

.ev-toolbar {
  background-color: color-mix(in srgb, var(--ev-surface) 62%, transparent);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}

.Select-menu-outer {
  background-color: color-mix(in srgb, var(--ev-surface) 88%, transparent) !important;
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}

.offcanvas {
  background-color: color-mix(in srgb, var(--ev-surface) 88%, transparent) !important;
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
}

.nav-tabs {
  background-color: color-mix(in srgb, var(--ev-bg-deep) 65%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}

/* The spotlight is the piece this was asked for, so it goes furthest. */
.ev-spotlight {
  background-color: color-mix(in srgb, var(--ev-surface) 58%, transparent);
  backdrop-filter: blur(30px) saturate(180%);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--ev-text) 14%, transparent);
}

/* Dim enough to push the page back, light enough that it is still there to
   be seen through the panel. */
#spotlight .modal-backdrop,
.modal-backdrop.show { backdrop-filter: blur(6px); opacity: 0.3; }

/* Browsers without backdrop-filter would show near-transparent panels with
   text floating over the page, so those fall back to opaque. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .navbar { background-color: var(--ev-bg-deep) !important; }
  .ev-toolbar, .ev-spotlight, .Select-menu-outer, .offcanvas {
    background-color: var(--ev-surface) !important;
  }
  .ev-picker, .nav-tabs { background-color: var(--ev-bg-deep); }
}

/* The selected-segment rules have to out-specify the transparent one above
   them, which is written as .ev-picker .btn-group > .form-check > .btn and so
   carries four classes. A plain .ev-picker-left .btn.active carries three and
   silently lost. These match its shape and add .active on top.

   They set colour and weight only. The surface behind the selected segment is
   the sliding pill, and a solid fill here would sit on top of it and cancel
   the one thing that makes this a control rather than a row of buttons. */
.ev-picker-left .btn-group > .form-check > .btn.active,
.ev-picker-left .btn.active {
  background-color: transparent !important;
  color: var(--ev-orange) !important;
  font-weight: 600;
}

.ev-picker-right .btn-group > .form-check > .btn.active,
.ev-picker-right .btn.active {
  background-color: transparent !important;
  color: var(--ev-accent) !important;
  font-weight: 600;
}

/* The in-panel picker sits under a search box rather than in a toolbar, so it
   centres itself and keeps a little air above. */
.ev-picker-inline {
  margin: 14px auto 0;
  display: flex;
  width: fit-content;
  max-width: 100%;
}

/* ==========================================================================
   Links, shadows, icons
   ========================================================================== */

/* Links in the page body took their colour from SLATE, which is tuned for a
   dark ground, so on the light theme they came out near-white on white. They
   read from the accent token now, in both themes. */
.ev-page a,
#worldtitle a,
#cntrylabel a,
.accordion-body a,
.offcanvas-body a,
.dash-markdown a,
p a, li a, td a {
  color: var(--ev-accent) !important;
  text-decoration: none;
}
.ev-page a:hover,
#worldtitle a:hover,
.accordion-body a:hover { color: var(--ev-accent) !important; opacity: 0.82; }

/* No shadowed text anywhere except the top bar. SLATE puts a text-shadow on
   headings and buttons, which reads as embossing and is the main thing that
   dates the type. */
body, body * {
  text-shadow: none;
}
.navbar, .navbar * {
  text-shadow: revert;
}

/* Drop shadows on panels stay: those are depth, not embossed type. */

/* ====== Lucide icons ======
   Lucide is the icon set asked for. It is loaded as a script from a CDN and
   swaps any <i data-lucide="name"> for an inline SVG, so the icons inherit
   currentColor and follow the theme like text. The magnifier in the search
   boxes stays a background-image, because those inputs have no element to
   hang an icon on. */
[data-lucide] { width: 18px; height: 18px; vertical-align: -3px; }
.ev-nav-btn [data-lucide],
.ev-nav-search [data-lucide],
.ev-theme-toggle [data-lucide] { width: 17px; height: 17px; }
.accordion-button [data-lucide] { width: 19px; height: 19px; margin-right: 10px; }

/* Icon and label need air between them inside a button. */
.ev-nav-btn, .ev-nav-search, .accordion-button > span { gap: 8px; }
.ev-nav-btn { display: inline-flex; align-items: center; }
.accordion-button > span { display: inline-flex; align-items: center; }

/* dbc 1.3.1's AccordionItem renders nothing at all if `title` is given a
   list of components: it type-checks in Python and breaks in React, which
   silently removed the whole accordion. So the titles stay plain strings and
   the icons are the Lucide glyphs drawn as CSS masks. A mask painted with
   currentColor inherits the header's text colour, so they follow the theme.
   Keyed by the section's own class rather than by its position. They were
   :nth-of-type(1..3), so inserting Top 10 as the second section slid every
   icon down one: Top 10 wore the trend line, Trends wore the two people, and
   Compare wore nothing. The navbar buttons carry their icons in markup and
   so kept the right ones, which is the disagreement a reader sees. */
.accordion-button::before {
  content: "";
  width: 19px;
  height: 19px;
  margin-right: 11px;
  flex: 0 0 19px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}


/* lucide "user" */
.ev-section-explore .accordion-button::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/><circle cx='12' cy='7' r='4'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/><circle cx='12' cy='7' r='4'/></svg>");
}

/* lucide "trending-up" */
.ev-section-trends .accordion-button::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='22 7 13.5 15.5 8.5 10.5 2 17'/><polyline points='16 7 22 7 22 13'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='22 7 13.5 15.5 8.5 10.5 2 17'/><polyline points='16 7 22 7 22 13'/></svg>");
}

/* lucide "trophy" */
.ev-section-top10 .accordion-button::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9H4.5a2.5 2.5 0 0 1 0-5H6'/><path d='M18 9h1.5a2.5 2.5 0 0 0 0-5H18'/><path d='M4 22h16'/><path d='M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22'/><path d='M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22'/><path d='M18 2H6v7a6 6 0 0 0 12 0V2Z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9H4.5a2.5 2.5 0 0 1 0-5H6'/><path d='M18 9h1.5a2.5 2.5 0 0 0 0-5H18'/><path d='M4 22h16'/><path d='M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22'/><path d='M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22'/><path d='M18 2H6v7a6 6 0 0 0 12 0V2Z'/></svg>");
}

/* lucide "users" */
.ev-section-compare .accordion-button::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M22 21v-2a4 4 0 0 0-3-3.87'/><path d='M16 3.13a4 4 0 0 1 0 7.75'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M22 21v-2a4 4 0 0 0-3-3.87'/><path d='M16 3.13a4 4 0 0 1 0 7.75'/></svg>");
}

/* Inline code came from SLATE as bright pink, which is loud on dark and
   garish on light. It marks a value the user can pick, so it takes the accent
   on a recessed ground, the same as the code in the intro panel. */
code, .ev-page code, #worldtitle code, #cntrylabel code {
  background-color: var(--ev-bg-deep);
  color: var(--ev-accent);
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 0.88em;
}

/* The brand is a link but should not look like body prose: no underline, and
   the wordmark keeps the text colour rather than the accent. */
.ev-brand a, a.ev-wordmark, .ev-page .ev-brand a {
  text-decoration: none !important;
  color: var(--ev-text) !important;
}
.ev-brand a:hover, a.ev-wordmark:hover { color: var(--ev-accent) !important; }
.ev-attrib-link, .ev-page .ev-attrib-link {
  color: var(--ev-accent) !important;
  text-decoration: none !important;
}
.ev-attrib-link:hover { text-decoration: underline !important; }

/* ==========================================================================
   Footer
   The mark on the left, the links beside it, the wordmark bottom-right, on a
   recessed ground separated by a hairline. It replaces a centred stack of a
   heading, a large raster logo, an email address and a pipe-separated row of
   bare links.
   ========================================================================== */
.ev-footer {
  margin-top: 48px;
  padding: 34px 32px 26px;
  background-color: var(--ev-bg-deep);
  border-top: 1px solid var(--ev-surface-2);
}

.ev-foot-top {
  display: flex;
  align-items: center;
  gap: 34px;
  flex-wrap: wrap;
}

.ev-foot-mark {
  height: 48px;
  width: 48px;
  display: block;
}

.ev-foot-links {
  display: flex;
  align-items: center;
  gap: 26px;
  flex-wrap: wrap;
}

.ev-foot-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ev-text-muted) !important;
  text-decoration: none !important;
  font-size: 0.9rem;
  font-weight: 500;
}
.ev-foot-link:hover { color: var(--ev-accent) !important; }
.ev-foot-link [data-lucide] { width: 17px; height: 17px; }

.ev-foot-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--ev-surface-2);
}

.ev-foot-note {
  color: var(--ev-text-muted);
  font-size: 0.78rem;
}

/* The wordmark is dark artwork, so it needs inverting on the dark theme and
   not on the light one. */
.ev-foot-label { height: 26px; display: block; opacity: 0.9; }
:root:not([data-theme="light"]) .ev-foot-label { filter: invert(1) brightness(1.6); }

@media (max-width: 720px) {
  .ev-foot-top { gap: 20px; }
  .ev-foot-bottom { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
   Disclosures in the summary column
   The class is called "danger" for historical reasons, but these three are
   explanations, not warnings. A thick crimson-reading edge on a navy ground
   says error; they are information, so they take the cyan accent and read as
   something to open.
   ========================================================================== */
.danger {
  background-color: var(--ev-surface);
  color: var(--ev-text);
  border: 1px solid var(--ev-surface-2);
  border-radius: var(--ev-radius);
  padding: 0;
  box-shadow: none;
  margin-bottom: 10px;
  overflow: hidden;
}

.danger details { margin: 0; }

.danger summary {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  padding: 12px 14px;
  color: var(--ev-text);
  font-size: 0.92rem;
  list-style: none;
}
.danger summary::-webkit-details-marker { display: none; }
.danger summary::marker { content: ""; }
.danger summary:hover { background-color: var(--ev-surface-2); }
.danger summary [data-lucide] {
  width: 17px; height: 17px;
  color: var(--ev-accent);
  flex: 0 0 17px;
}

/* A chevron that turns, so the row reads as openable. */
.danger summary::after {
  content: "";
  margin-left: auto;
  width: 15px; height: 15px;
  flex: 0 0 15px;
  background-color: var(--ev-text-muted);
  transition: transform 140ms ease;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
.danger details[open] summary::after { transform: rotate(180deg); }

.danger details > *:not(summary) {
  padding: 0 14px 14px;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--ev-text-muted);
}

/* The global body-link rule uses !important, so the footer links have to be
   at least as specific to keep their muted resting colour; without this they
   all sit at full accent and the row reads as four calls to action. */
.ev-footer .ev-foot-link,
.ev-page .ev-footer .ev-foot-link {
  color: var(--ev-text-muted) !important;
}
.ev-footer .ev-foot-link:hover,
.ev-page .ev-footer .ev-foot-link:hover {
  color: var(--ev-accent) !important;
}

/* ==========================================================================
   Theme toggle icon, drawn by CSS
   The button used to hold a Lucide <i> that a clientside callback replaced by
   hand. Dash owns that subtree, so the swap fought React's re-render and the
   toggle needed several clicks before it took. The glyph is a mask here
   instead, chosen by the theme attribute, so the callback only has to flip
   that attribute and nothing races.
   ========================================================================== */
.ev-theme-toggle::before {
  content: "";
  width: 17px; height: 17px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  /* lucide "moon": shown on the dark theme, meaning "you are in dark" */
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/></svg>");
}

/* lucide "sun" on the light theme */
:root[data-theme="light"] .ev-theme-toggle::before {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='4'/><path d='M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M6.3 17.7l-1.4 1.4M19.1 4.9l-1.4 1.4'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='4'/><path d='M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M6.3 17.7l-1.4 1.4M19.1 4.9l-1.4 1.4'/></svg>");
}

/* ====== Per-theme elements ====== */
.ev-only-light { display: none; }
:root[data-theme="light"] .ev-only-light { display: block; }
:root[data-theme="light"] .ev-only-dark { display: none; }

/* The footer mark sits in its own box so the two variants stack rather than
   pushing each other around, and so it centres against the link row. */
.ev-foot-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.ev-foot-mark { height: 46px; width: 46px; display: block; }

/* ====== The in-panel picker ======
   It was taller than the one above the map, because the buttons inside it
   kept the panel's larger padding. Same height and the same track thickness
   as the toolbar picker now. */
.ev-picker-inline { padding: 3px; border-radius: 10px; }
.ev-picker-inline .ev-picker-sep { margin: 2px 8px; }

/* The matched-pair minimum belongs to the dataset halves, which are two
   labels of different lengths that should look like one control. It used to
   be written for every .form-check in the track, which gave each of the eight
   years a 104px box as well: 832px of segments in a track a panel wide, so
   the strip overflowed and the first and last years were cut off. The years
   take their width from their own text. */
.ev-picker-inline .ev-picker-left .btn-group > .form-check { min-width: 96px; }

/* ==========================================================================
   The animation slider under the map
   Its tick labels are class "slider-label", not the "slider-label-text" the
   earlier rule guessed at, so they kept Plotly's default fill of
   rgb(42,63,95): a near-black navy that is invisible against this page's navy
   and nearly so on light. The rail was drawn in the surface tone, which is
   only a few steps from the ground and read as absent.
   ========================================================================== */
.js-plotly-plot .slider-label,
.js-plotly-plot .slider-currentvalue,
.js-plotly-plot .slider-labels text,
.js-plotly-plot .slider-group text {
  fill: var(--ev-text) !important;
  font-size: 12px;
}

.js-plotly-plot .slider-rail-rect {
  fill: color-mix(in srgb, var(--ev-text) 26%, transparent) !important;
}

.js-plotly-plot .slider-tick-rect {
  fill: color-mix(in srgb, var(--ev-text) 45%, transparent) !important;
}

/* The grip is the thing being dragged, so it keeps the accent and gains an
   outline that works on either ground. */
.js-plotly-plot .slider-grip-rect {
  fill: var(--ev-accent) !important;
  stroke: var(--ev-text) !important;
  stroke-width: 1px !important;
}

/* The play and stop buttons beside it. */
.js-plotly-plot .updatemenu-button rect {
  fill: color-mix(in srgb, var(--ev-text) 14%, transparent) !important;
  stroke: color-mix(in srgb, var(--ev-text) 28%, transparent) !important;
}
.js-plotly-plot .updatemenu-button text { fill: var(--ev-text) !important; }
.js-plotly-plot .updatemenu-button:hover rect {
  fill: var(--ev-accent) !important;
}

/* .ev-foot-mark sets display:block and is declared after .ev-only-light, at
   the same specificity, so the later rule won and both variants of the mark
   rendered side by side. These are specific enough to settle it either way. */
.ev-foot-brand .ev-only-light,
.ev-footer .ev-only-light { display: none !important; }
:root[data-theme="light"] .ev-foot-brand .ev-only-light,
:root[data-theme="light"] .ev-footer .ev-only-light { display: block !important; }
:root[data-theme="light"] .ev-foot-brand .ev-only-dark,
:root[data-theme="light"] .ev-footer .ev-only-dark { display: none !important; }

/* The rail is the line the grip travels along; at 26% of the text colour it
   was still reading as absent against the ground. */
.js-plotly-plot .slider-rail-rect {
  fill: color-mix(in srgb, var(--ev-text) 42%, transparent) !important;
}

/* ==========================================================================
   The statistic control, matched to the picker
   Beside the dataset/year track it was a different species: a separately
   outlined box with its own border weight, sitting next to flat pills in a
   shared track. Same ground, same border, same radius and the same glass as
   the picker, so the row reads as one kind of control repeated rather than
   three unrelated widgets that happen to be adjacent.
   ========================================================================== */
.ev-field #stats2 .Select-control {
  background-color: color-mix(in srgb, var(--ev-bg-deep) 70%, transparent) !important;
  border: 1px solid var(--ev-surface-2) !important;
  border-radius: 12px !important;
  height: 42px !important;
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}
.ev-field #stats2 .Select-placeholder,
.ev-field #stats2 .Select--single > .Select-control .Select-value {
  line-height: 40px !important;
}
.ev-field #stats2 .Select-input { height: 40px; }

/* The picker's own track is 42px too, so the two sit on one baseline. */
.ev-toolbar .ev-picker { min-height: 42px; }

/* More info was a third treatment again; same height and radius as the rest. */
.ev-toolbar .ev-info-btn { height: 42px; border-radius: 12px; }

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ev-field #stats2 .Select-control { background-color: var(--ev-bg-deep) !important; }
}

/* At 42% the rail measured 943x5 in the right place but still did not read on
   the navy. Solid, at the muted text tone, does. */
.js-plotly-plot .slider-rail-rect,
.js-plotly-plot rect.slider-rail-rect {
  fill: var(--ev-text-muted) !important;
  fill-opacity: 1 !important;
}

/* ==========================================================================
   Map hint
   A glass card over the map carrying the one instruction the page needs to
   give: click a country. It used to live at the bottom of the right-hand
   column, where it occupied result space permanently to say something that
   only needs saying once.
   ========================================================================== */
.ev-map-pane { position: relative; }

.ev-hint {
  position: absolute;
  left: 22px;
  bottom: 26px;
  max-width: 430px;
  z-index: 5;
  padding: 16px 18px;
  border-radius: 14px;
  background-color: color-mix(in srgb, var(--ev-surface) 58%, transparent);
  backdrop-filter: blur(26px) saturate(180%);
  -webkit-backdrop-filter: blur(26px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--ev-text) 16%, transparent);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
  transition: opacity 200ms ease, transform 200ms ease;
}

.ev-hint-gone {
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
}

.ev-hint-row { display: flex; gap: 13px; align-items: flex-start; }
.ev-hint-row > [data-lucide] {
  width: 20px; height: 20px;
  color: var(--ev-accent);
  flex: 0 0 20px;
  margin-top: 2px;
}

.ev-hint-title {
  color: var(--ev-text);
  font-weight: 650;
  font-size: 0.98rem;
  margin-bottom: 4px;
}

.ev-hint-body {
  color: var(--ev-text-muted);
  font-size: 0.88rem;
  line-height: 1.55;
}

.ev-hint-jump {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 12px;
  padding: 7px 13px;
  border-radius: 9px;
  border: 1px solid var(--ev-surface-2);
  background-color: transparent;
  color: var(--ev-text);
  font-size: 0.84rem;
  font-weight: 550;
}
.ev-hint-jump:hover {
  border-color: var(--ev-accent);
  color: var(--ev-accent);
  background-color: var(--ev-surface);
}
.ev-hint-jump [data-lucide] { width: 15px; height: 15px; }

.ev-hint-close {
  position: absolute;
  top: 10px; right: 10px;
  width: 26px; height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--ev-text-muted);
  cursor: pointer;
  padding: 0;
}
.ev-hint-close:hover { background-color: var(--ev-surface-2); color: var(--ev-text); }
.ev-hint-close [data-lucide] { width: 15px; height: 15px; }

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ev-hint { background-color: var(--ev-surface); }
}

/* The footer's top row was pinned to the top edge: .ev-footer's padding was
   asymmetric and the row had no vertical centring of its own, so the mark and
   links sat against the boundary instead of within the band. */
.ev-footer { padding: 30px 32px; }

.ev-foot-top {
  align-items: center;
  min-height: 56px;
  padding: 6px 0 2px;
}

.ev-foot-links { align-items: center; }

.ev-foot-bottom {
  align-items: center;
  margin-top: 22px;
  padding-top: 18px;
}

/* .ev-shell > footer, added when the bar was made full-bleed, sets
   padding: 0 24px and carries a child combinator plus an element selector, so
   it out-specifies .ev-footer and zeroed the vertical padding. That is why the
   mark and links sat flush against the top boundary of the band however much
   padding .ev-footer asked for. */
.ev-shell > footer.ev-footer {
  padding: 30px 32px;
}

/* The hint was sitting over the colour scale at the bottom of the map. The
   top-left of a world map in this projection is open ocean, so it costs
   nothing there. */
.ev-hint {
  top: 18px;
  bottom: auto;
  left: 18px;
}

/* The hint sits over the middle of the map rather than in a corner: it is the
   first thing to read on arrival, and the corner made it easy to miss. */
.ev-hint {
  top: 50%;
  left: 50%;
  bottom: auto;
  transform: translate(-50%, -50%);
  max-width: 400px;
  text-align: left;
}
.ev-hint-gone {
  opacity: 0;
  transform: translate(-50%, calc(-50% + 6px));
}

.ev-of-total {
  color: var(--ev-text-muted);
  font-size: 0.82rem;
}

/* ==========================================================================
   The country results table
   Rows are clickable, but nothing said so: the pointer stayed a text caret
   over the cells and there was no hover response, so the table read as a
   printout rather than as a list you can pick from.
   ========================================================================== */
#instnametable .dash-cell,
#instnametable .dash-cell div,
#instnametable .dash-cell .dash-cell-value {
  cursor: pointer !important;
  user-select: none;
}

#instnametable .dash-spreadsheet-container .dash-spreadsheet-inner tr:hover td {
  background-color: var(--ev-surface-2) !important;
  color: var(--ev-text) !important;
}

/* The selected row keeps a mark after the click, so it is clear which
   researcher the panel below is describing. */
#instnametable td.focused,
#instnametable td.cell--selected {
  background-color: color-mix(in srgb, var(--ev-accent) 26%, transparent) !important;
  border: none !important;
  /* Dash's own focus ring for a cell is a thin pink outline. The tint is
     the mark; the ring would be a second one in another colour. */
  box-shadow: none !important;
}

/* Dash draws a text-input outline on the focused cell; these are not editable
   so that outline only suggests they are. */
#instnametable input.dash-cell-value:focus,
#instnametable .dash-cell-value.focused {
  outline: none !important;
  caret-color: transparent;
}

#instnametable .dash-spreadsheet-inner th {
  position: sticky;
  top: 0;
  z-index: 2;
}

/* ==========================================================================
   The composite-score formula
   It was one long line of six fractions, which needed a horizontal scrollbar
   on anything narrower than a wide desktop and was shrunk by breakpoints to
   compensate. It is two aligned lines now, so it fits at full size, and the
   container scales it down only if it still would not.
   ========================================================================== */
.ev-formula {
  display: flex;
  justify-content: center;
  overflow: hidden;
}

.ev-formula mjx-container {
  overflow: visible !important;
  max-width: 100%;
}

/* MathJax reports its own width, so the last resort is a proportional scale
   rather than a scrollbar: the formula gets smaller, never clipped. */
.ev-formula mjx-container[display] {
  margin: 0 !important;
  transform-origin: center center;
}

/* Scale steps set below, from measurement. */

/* ==========================================================================
   The formula, kept on one line
   Breakpoints could not win here: the column is a fraction of the viewport,
   so it shrinks continuously while a step only changes at a threshold, and
   whatever the steps were the width just above each one overflowed. The size
   is tied to the viewport instead, which is the same continuous relationship
   the container has.

   Measured: at 16px the single line renders 998px, so its width is about
   62.4x the font size, and the column is about 0.42 of the viewport. That
   gives font-size <= 0.0067vw; 0.62vw leaves a margin. The clamp stops it
   becoming unreadably small on a phone or absurdly large on a wall display,
   and below the lower bound the container scrolls rather than clipping.
   ========================================================================== */
.ev-formula mjx-container {
  font-size: clamp(5px, 0.62vw, 13px) !important;
}

.ev-formula { overflow-x: auto; }

/* ==========================================================================
   Disabled years
   dbc puts `disabled` on the <input class="btn-check">, while the thing you
   see is the <label class="btn"> next to it. A label can never match
   :disabled, so every rule written as .btn:disabled silently did nothing and
   years an author has no data for looked exactly like years they do. This is
   Bootstrap's own pattern: style the label that follows a disabled input.
   ========================================================================== */
.btn-check:disabled + .btn,
.btn-check[disabled] + .btn,
.ev-picker .btn-check:disabled + .btn,
.year-picker .btn-check:disabled + .btn,
[id^="selectYrRadio"] .btn-check:disabled + .btn {
  color: var(--ev-text-muted) !important;
  background-color: transparent !important;
  opacity: 0.32 !important;
  cursor: not-allowed !important;
  text-decoration: line-through;
  pointer-events: none;
}

/* A disabled year must not pick up the hover treatment either. */
.ev-picker .btn-check:disabled + .btn:hover,
.year-picker .btn-check:disabled + .btn:hover {
  background-color: transparent !important;
  color: var(--ev-text-muted) !important;
}

/* The keyboard-highlighted row in the spotlight. Same treatment as hover, so
   arrowing and pointing look identical; the field keeps focus throughout, so
   typing can continue with a row highlighted. */
.ev-spotlight-hit--active {
  background-color: var(--ev-accent) !important;
  color: #10151D !important;
}

/* The gauge's big number is Plotly's ".number"; it was inheriting the figure
   font colour, which put a cyan value on top of a cyan arc. The value is text,
   so it takes the theme's text colour and the arc keeps the accent. */
.js-plotly-plot .number { fill: var(--ev-text) !important; }
.js-plotly-plot .delta { font-weight: 600; }

/* ==========================================================================
   Fact cards
   These are filled with the green or magenta leaf, so everything on them has
   to be dark to be legible. The global body-link rule carries !important and
   was painting the author link and the h-index links cyan on green, which is
   two mid-tones at the same lightness: the worst possible pairing. Inside
   these cards a link is dark, and underlined so it still reads as a link
   without needing a colour to say so.
   ========================================================================== */
.ev-fact-card,
.ev-fact-card * {
  color: #10151D !important;
}

.ev-fact-card a,
.ev-page .ev-fact-card a,
.ev-fact-card .lel a {
  color: #10151D !important;
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}
.ev-fact-card a:hover { opacity: 0.72; }

/* Inline code on a leaf ground needs the same treatment: the recessed navy
   fill it gets elsewhere is invisible against green. */
.ev-fact-card code {
  background-color: rgba(16, 21, 29, 0.14);
  color: #10151D !important;
}

/*
  Retraction page. The one rule that matters here is that a measured value
  and an estimated one must never look alike: measured is the cyan accent,
  estimated is muted and dashed, and the caveats sit beside the number rather
  than in a footnote.
*/
.ev-title       { color: var(--ev-text); font-weight: 600; }
.ev-subtitle    { color: var(--ev-text); font-weight: 600; margin-top: .25rem; }
.ev-lede        { color: var(--ev-text-muted); max-width: 70ch; }
.ev-hint        { color: var(--ev-text-muted); font-size: .9rem; }
.ev-note        { color: var(--ev-text-muted); font-style: italic; padding: 1rem 0; }

.ev-panel {
  background: var(--ev-surface);
  border-radius: var(--ev-radius);
  box-shadow: var(--ev-shadow);
  padding: 1.1rem 1.25rem;
}
.ev-kicker {
  color: var(--ev-text-muted);
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .72rem;
  margin-bottom: .4rem;
}
.ev-metric       { color: var(--ev-accent); font-size: 2.1rem; font-weight: 700; }
.ev-metric-label { color: var(--ev-text-muted); font-size: .85rem; margin-left: .4rem; }
.ev-caveats      { color: var(--ev-text-muted); font-size: .82rem;
                   margin: .8rem 0 0; padding-left: 1.1rem; }
.ev-caveats li   { margin-bottom: .35rem; }

/* Ranking page: the rank-locator input and its verdict. */
.ev-input {
  background: var(--ev-bg-deep);
  color: var(--ev-text);
  border: 1px solid var(--ev-surface-2);
  border-radius: var(--ev-radius);
  padding: .45rem .7rem;
  width: 100%;
  margin-bottom: .9rem;
}
.ev-input::placeholder { color: var(--ev-text-muted); }
.ev-verdict {
  color: var(--ev-text);
  margin-top: .7rem;
  list-style: none;
}

/*
  Site navigation. Dash registers pages but links to none of them, so two
  pages shipped reachable only by typing their URL. This bar is built from
  dash.page_registry, so a page added later appears without an edit here.
*/
.ev-nav {
  display: flex;
  gap: .4rem;
  align-items: center;
  padding: .55rem 1rem;
  /* Same glass as .navbar directly below it. A solid fill here put an opaque
     strip across the top of a page whose other floating layers are all
     translucent, so the bar read as a different material from the toolbar it
     sits against. */
  background-color: color-mix(in srgb, var(--ev-bg-deep) 7%, transparent);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid var(--ev-surface-2);
  position: sticky;
  top: 0;
  z-index: 500;
}
.ev-nav-link {
  color: var(--ev-text-muted);
  text-decoration: none;
  font-size: .9rem;
  padding: .35rem .8rem;
  border-radius: var(--ev-radius);
}
.ev-nav-link:hover {
  color: var(--ev-text);
  background: var(--ev-surface);
  text-decoration: none;
}

/* ====== Glass overlays ======
   The spotlight and the intro panel sit on top of the dashboard, so they
   should read as a pane of glass over it rather than an opaque card that
   hides it. Three things together make that work, and all three are needed:
   a background that is genuinely translucent, a blur behind it so what shows
   through is suggestion rather than clutter, and a light top edge so the
   pane catches an implied light source and does not look like a hole.

   The translucency is deliberately kept above 70% opaque. Any thinner and
   the text behind starts competing with the text in front, which is the
   usual way this effect turns unreadable.

   backdrop-filter is unsupported in a few engines and degrades to a plain
   translucent panel there, which is why the background colour alone is still
   legible. */
.ev-spotlight,
.ev-intro {
  /* 74% over a backdrop dimmed to 45% black left nothing behind the panel to
     refract, so the blur did no work and it read as a flat grey box. The fill
     is lighter now and the backdrop darker by less; between them the page
     shows through as soft colour, which is the whole effect. */
  background-color: color-mix(in srgb, var(--ev-surface) 55%, transparent);
  backdrop-filter: blur(30px) saturate(190%);
  -webkit-backdrop-filter: blur(30px) saturate(190%);
  border: 1px solid color-mix(in srgb, #ffffff 18%, transparent);
  box-shadow:
    0 24px 64px rgba(0, 0, 0, 0.48),
    inset 0 1px 0 color-mix(in srgb, #ffffff 22%, transparent);
}

.ev-spotlight { border-radius: 18px; }

/* The offcanvas is anchored to an edge, so it keeps square outer corners and
   only rounds the edge that floats over the page. */
.ev-intro {
  border-right: none;
  border-radius: 0 0 0 18px;
}

/* The backdrop is part of the effect: too dark and the blur has nothing to
   work with, since there is nothing left to see through the glass. */
.modal-backdrop.show,
.offcanvas-backdrop.show { opacity: 0.38; }

/* ====== The close control on an overlay ======
   "esc to close" is an instruction, not a control. It leaves anyone using a
   mouse, or a touch screen with no esc key, with no way out. */
.ev-overlay-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ev-text-muted);
  background: color-mix(in srgb, #ffffff 8%, transparent);
  border: 1px solid color-mix(in srgb, #ffffff 12%, transparent);
  border-radius: 50%;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.ev-overlay-close:hover {
  color: var(--ev-text);
  background: color-mix(in srgb, #ffffff 16%, transparent);
}
.ev-overlay-close:focus-visible {
  outline: 2px solid var(--ev-accent);
  outline-offset: 2px;
}

/* The body is positioned so the close control can sit inside it. */
.ev-spotlight-body { position: relative; }

/* The panels on the retraction and ranking pages get the same glass, at a
   lower intensity: they sit in the page rather than over it. */
.ev-panel {
  background: color-mix(in srgb, var(--ev-surface) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid color-mix(in srgb, #ffffff 10%, transparent);
  box-shadow:
    var(--ev-shadow),
    inset 0 1px 0 color-mix(in srgb, #ffffff 12%, transparent);
}

/* ====== Caption text ======
   NOT .ev-hint. That name was already taken by the floating card over the
   world map, which is position:absolute with its own background, so reusing
   it turned every caption on the new pages into a card floating over
   whatever happened to be beneath it. This is plain small text and nothing
   else. */
.ev-caption {
  color: var(--ev-text-muted);
  font-size: .88rem;
  max-width: 78ch;
}
.ev-caption p:last-child { margin-bottom: 0; }

/* The nav links carry a Lucide glyph, so they lay out as icon + label. */
.ev-nav-link { display: inline-flex; align-items: center; gap: .45rem; }
.ev-nav-link svg { width: 16px; height: 16px; }

/* ==========================================================================
   The what-if calculator
   ==========================================================================
   Six number boxes under six gauges, and the two ranks above them. Magenta
   is the calculator's colour throughout: the gauge bars, the rank, the
   focused input. Cyan stays the colour of what the publishers actually
   printed, so a reader can tell at a glance which they are looking at. */

.ev-whatif-note {
  color: var(--ev-text-muted);
  font-size: .82rem;
  max-width: 78ch;
  margin: .6rem auto 0;
}

/* ====== The author card ======
   Identity, the two ranks, the rank strip and two small facts, in one panel.
   This replaced a bare LED number beside a markdown bullet list: the numbers
   and the person they belong to were laid out as though unrelated, and the
   two ranks had no picture to explain why they differ. */
.ev-id-card {
  background: color-mix(in srgb, var(--ev-surface) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid color-mix(in srgb, #ffffff 10%, transparent);
  border-radius: var(--ev-radius);
  box-shadow:
    var(--ev-shadow),
    inset 0 1px 0 color-mix(in srgb, #ffffff 12%, transparent);
  padding: 1.1rem 1.3rem 1rem;
  /* The author section sits inside an html.Center, which computes to
     text-align: -webkit-center. That value centres block children as well as
     text, so the name and the self-citation bar both arrived centred. */
  text-align: left;
}


.ev-id-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .6rem;
}
/* Which edition every number on this card comes from. */
.ev-id-edition {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  flex: 0 0 auto;
  padding: .25rem .6rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ev-bg-deep) 55%, transparent);
  color: var(--ev-text-muted);
  font-size: .74rem;
  white-space: nowrap;
}
.ev-id-edition svg { width: 13px; height: 13px; }
.ev-id-name {
  color: var(--ev-text);
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.2;
}
.ev-id-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1.1rem;
  margin-top: .35rem;
}
.ev-id-meta-item {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  color: var(--ev-text-muted);
  font-size: .86rem;
}
.ev-id-meta-item svg { width: 14px; height: 14px; opacity: .8; }

.ev-id-body {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  flex-wrap: wrap;
}
.ev-id-ranks { flex: 0 0 auto; }
/* The ECharts strip. A fixed height because echarts measures its container,
   and a container sized by its contents measures as zero. */
.ev-rank-chart {
  flex: 1 1 260px;
  min-width: 240px;
  /* Sized to the strip and its two labels and nothing more: echarts fills
     whatever it is given, so a taller box is just dead space under the
     axis. */
  height: 96px;
}

.ev-rank-row { display: flex; gap: 1.6rem; align-items: flex-start; }
.ev-rank-cell { min-width: 112px; }
.ev-rank-value {
  font-size: 2.1rem;
  font-weight: 700;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.ev-rank-label {
  color: var(--ev-text);
  font-size: .82rem;
  font-weight: 600;
}
.ev-rank-detail { color: var(--ev-text-muted); font-size: .74rem; }
.ev-rank-was {
  color: var(--ev-text-muted);
  font-size: .78rem;
  margin-top: .6rem;
}
/* Says the numbers beside it are invented. It appears only in what-if mode,
   which is also the only time they are. */
.ev-id-badge {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  align-self: center;
  padding: .2rem .5rem;
  border-radius: 999px;
  border: 1px solid #D86CB4;
  color: #D86CB4;
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  white-space: nowrap;
}
.ev-id-badge svg { width: 12px; height: 12px; }

/* ====== The two small facts ====== */
.ev-id-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  margin-top: 1rem;
  padding-top: .9rem;
  border-top: 1px solid color-mix(in srgb, var(--ev-surface-2) 60%, transparent);
}
.ev-chip { flex: 1 1 200px; min-width: 190px; }
.ev-chip-head {
  display: flex;
  align-items: center;
  gap: .4rem;
  color: var(--ev-text-muted);
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.ev-chip-head svg { width: 13px; height: 13px; }
.ev-chip-head strong {
  margin-left: auto;
  color: var(--ev-text);
  font-size: .95rem;
  font-variant-numeric: tabular-nums;
}
.ev-chip-body { color: var(--ev-text); font-size: .92rem; margin-top: .35rem; }
/* Self-citation as a share of a whole, because the number alone says
   nothing: 10.59% means one thing next to an empty bar and another next to
   a full one. */
.ev-chip-track {
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ev-surface-2) 70%, transparent);
  margin-top: .45rem;
  overflow: hidden;
}
.ev-chip-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--ev-accent), var(--ev-orange));
}



/* ====== Icons inside content that callbacks replace ======
   These are drawn as CSS masks rather than as <i data-lucide> elements, and
   the reason is a bug rather than a preference.

   lucide.createIcons() REPLACES each <i> with an <svg>, which React knows
   nothing about. The author card's rank row changes length when the what-if
   badge appears and disappears, and on the next render React was patching
   against a virtual DOM that no longer matched the page: the badge survived
   its own removal and accumulated a second stranded <svg>, which is what put
   two flasks where a rank should have been.

   A mask is painted by CSS on an element React created and still owns, so
   nothing mutates the tree behind its back. The accordion headers use the
   same technique for the same reason. Paths are lucide's own, read out of
   the loaded library rather than redrawn. */
.ev-ic {
  display: inline-block;
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.ev-ic-building-2 {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 12h4'></path><path d='M10 8h4'></path><path d='M14 21v-3a2 2 0 0 0-4 0v3'></path><path d='M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2'></path><path d='M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 12h4'></path><path d='M10 8h4'></path><path d='M14 21v-3a2 2 0 0 0-4 0v3'></path><path d='M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2'></path><path d='M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16'></path></svg>");
}
.ev-ic-map-pin {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'></path><circle cx='12' cy='10' r='3'></circle></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'></path><circle cx='12' cy='10' r='3'></circle></svg>");
}
.ev-ic-microscope {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 18h8'></path><path d='M3 22h18'></path><path d='M14 22a7 7 0 1 0 0-14h-1'></path><path d='M9 14h2'></path><path d='M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z'></path><path d='M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 18h8'></path><path d='M3 22h18'></path><path d='M14 22a7 7 0 1 0 0-14h-1'></path><path d='M9 14h2'></path><path d='M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z'></path><path d='M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3'></path></svg>");
}
/* Two lucide glyphs that are used both as icons and as masks on a label,
   so they are named here rather than written out at each use. */
:root {
  --ev-mask-history: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8'/><path d='M3 3v5h5'/><path d='M12 7v5l4 2'/></svg>");
  /* lucide "flask-conical": the what-if calculator, which is a laboratory
     for a researcher's own numbers. */
  --ev-mask-flask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2'/><path d='M8.5 2h7'/><path d='M7 16h10'/></svg>");
  /* lucide "quote": citations, for the switch that takes the researcher's
     own out of them. */
  --ev-mask-quote: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'/><path d='M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'/></svg>");
  /* lucide "trending-up": the switch that redraws an axis on a log scale. */
  --ev-mask-trend: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='22 7 13.5 15.5 8.5 10.5 2 17'/><polyline points='16 7 22 7 22 13'/></svg>");
  --ev-mask-calendar: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2v3'/><path d='M16 2v3'/><rect x='3' y='3' width='18' height='18' rx='2'/><path d='M3 9h18'/></svg>");
}
.ev-ic-calendar {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2v3'></path><path d='M16 2v3'></path><rect x='3' y='3' width='18' height='18' rx='2'></rect><path d='M3 9h18'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2v3'></path><path d='M16 2v3'></path><rect x='3' y='3' width='18' height='18' rx='2'></rect><path d='M3 9h18'></path></svg>");
}
.ev-ic-external-link {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M15 3h6v6'/><path d='M10 14 21 3'/><path d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M15 3h6v6'/><path d='M10 14 21 3'/><path d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/></svg>");
}
.ev-ic-info {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 16v-4'/><path d='M12 8h.01'/></svg>");
}
.ev-ic-x {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 6 6 18'/><path d='m6 6 12 12'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 6 6 18'/><path d='m6 6 12 12'/></svg>");
}
.ev-ic-quote {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'></path><path d='M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'></path><path d='M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z'></path></svg>");
}
.ev-ic-target {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'></circle><circle cx='12' cy='12' r='6'></circle><circle cx='12' cy='12' r='2'></circle></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'></circle><circle cx='12' cy='12' r='6'></circle><circle cx='12' cy='12' r='2'></circle></svg>");
}
.ev-ic-flask-conical {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2'></path><path d='M6.453 15h11.094'></path><path d='M8.5 2h7'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2'></path><path d='M6.453 15h11.094'></path><path d='M8.5 2h7'></path></svg>");
}

.ev-ic-share-2 {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='18' cy='5' r='3'></circle><circle cx='6' cy='12' r='3'></circle><circle cx='18' cy='19' r='3'></circle><line x1='8.59' x2='15.42' y1='13.51' y2='17.49'></line><line x1='15.41' x2='8.59' y1='6.51' y2='10.49'></line></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='18' cy='5' r='3'></circle><circle cx='6' cy='12' r='3'></circle><circle cx='18' cy='19' r='3'></circle><line x1='8.59' x2='15.42' y1='13.51' y2='17.49'></line><line x1='15.41' x2='8.59' y1='6.51' y2='10.49'></line></svg>");
}
.ev-ic-download {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 15V3'></path><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'></path><path d='m7 10 5 5 5-5'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 15V3'></path><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'></path><path d='m7 10 5 5 5-5'></path></svg>");
}
.ev-ic-clipboard-copy {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect width='8' height='4' x='8' y='2' rx='1' ry='1'></rect><path d='M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2'></path><path d='M16 4h2a2 2 0 0 1 2 2v4'></path><path d='M21 14H11'></path><path d='m15 10-4 4 4 4'></path></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect width='8' height='4' x='8' y='2' rx='1' ry='1'></rect><path d='M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2'></path><path d='M16 4h2a2 2 0 0 1 2 2v4'></path><path d='M21 14H11'></path><path d='m15 10-4 4 4 4'></path></svg>");
}

/* ====== Taking the card somewhere else ====== */
.ev-share-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: .9rem;
  padding-top: .8rem;
  border-top: 1px solid color-mix(in srgb, var(--ev-surface-2) 60%, transparent);
}
.ev-share-btn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .7rem;
  border-radius: 999px;
  border: 1px solid var(--ev-surface-2);
  background: color-mix(in srgb, var(--ev-bg-deep) 45%, transparent);
  color: var(--ev-text-muted);
  font-size: .78rem;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.ev-share-btn:hover {
  color: var(--ev-text);
  border-color: var(--ev-accent);
  background: color-mix(in srgb, var(--ev-accent) 14%, transparent);
}
.ev-share-status {
  color: var(--ev-text-muted);
  font-size: .76rem;
  margin-left: .2rem;
}


/* ==========================================================================
   The explore panel's controls
   ==========================================================================
   The search box, the edition picker and the four controls under them used to
   take three full-width rows between the heading and the first gauge: a search
   field stretched across eight columns to hold one name, the picker on its own
   line below it, then four Bootstrap columns spread across the width with the
   longest label in the app sitting in the middle of them.

   They are three flex rows now, each only as wide as its contents. */
.ev-explore-bar,
.ev-explore-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 16px;
}
.ev-explore-bar { margin-bottom: 4px; }
/* Neither control may shrink. The row is a flex container, and a dropdown
   renders <div class="dash-dropdown"><div class="Select">: an intermediate
   wrapper with no width of its own collapsed to its content as soon as it
   became a flex item, which left the search box 120px wide with the name
   clipped inside it. */
.ev-explore-bar > * { flex: 0 0 auto; }
.ev-explore-controls { margin-top: 10px; }

/* The picker centres itself with auto side margins when it stands alone. As a
   flex item beside the search box those margins become a 250px gap, so inside
   this row it sits where the row puts it. */
.ev-explore-bar .ev-picker-inline { margin: 0; }

/* A name is not a paragraph. Wide enough for the longest one, not for the
   column it happens to sit in. */
.ev-author-search { width: 300px; max-width: 100%; }

/* The toggles carry their own labels underneath, so they need no column. */
.ev-explore-controls > div { flex: 0 0 auto; }

.ev-compare {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The two switches label themselves underneath, which made the control row
   twice as tall as the things next to it and left the labels floating below a
   line they belong on. daq only offers top or bottom, so the label block is
   turned on its side here instead. */
.ev-explore-controls [class*="daq-booleanswitch"][class*="__label"] {
  flex-direction: row !important;
  align-items: center !important;
  gap: 8px;
}
.ev-explore-controls [class*="daq-booleanswitch"] label {
  margin: 0 !important;
  font-size: .82rem;
  color: var(--ev-text-muted);
  white-space: nowrap;
}
.ev-compare .Select { min-width: 132px; }
.ev-control-label {
  color: var(--ev-text-muted);
  font-size: .78rem;
  white-space: nowrap;
}

/* ====== What the comparison group sets ======
   It sets the two reference marks on each bullet row, the median and the
   middle half, and nothing else: the bars divide by the edition maximum, so
   a bar does not change length when the group changes. This used to say
   "gauge maximum: the highest in <group>", which was true of the gauges that
   are gone and true of nothing now. */
.ev-comparison-legend {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin: 8px 0 14px;
  color: var(--ev-text-muted);
  font-size: .78rem;
}
.ev-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.ev-legend-item strong { color: var(--ev-text); font-weight: 600; }
.ev-legend-line {
  width: 16px;
  height: 3px;
  border-radius: 2px;
  background: var(--ev-orange);
}
/* The q1-q3 band, as it is drawn on the rows. */
.ev-legend-band {
  width: 16px;
  height: 9px;
  border-radius: 2px;
  /* The same faint text-colour wash as the band in the chart. */
  background: color-mix(in srgb, var(--ev-text) 22%, transparent);
}
/* The scale note is an explanation, not a key, so it carries no swatch. */
.ev-legend-note { opacity: .85; }

/* ==========================================================================
   The bullet rows in the author card
   ==========================================================================
   Six half-donut gauges in a 3x2 grid became six rows on one axis. The gauges
   each had their own scale -- 250k for citations, 200 for the h-index, 80 for
   hm -- so nothing could be read across them, and the group median was a 3px
   tick near zero on the wide ones. Every row here is that indicator's term in
   the composite score, so one axis serves all six and they add up to the
   number the formula produces.

   The geometry is shared with the drawing callback in auth_find.py: rows are
   34px apart starting 26px down, and the input column below positions its
   boxes to match. If one changes the other has to. */
.ev-bullets {
  position: relative;
  margin-top: .9rem;
  padding-top: .8rem;
  border-top: 1px solid color-mix(in srgb, var(--ev-surface-2) 60%, transparent);
}
.ev-bullet-chart {
  /* 10 top + seven 34px rows + 8 bottom. */
  height: 256px;
  width: 100%;
}

/* The boxes are the readout as well as the control: the value used to appear
   twice, once inside the gauge arc and again in a box underneath it. */
.ev-bullet-inputs {
  position: absolute;
  right: 0;
  /* 10px grid offset + (34 - 26) / 2 to centre the box on its row, plus the
     8px of padding on the container above. */
  top: calc(.8rem + 14px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 104px;
}
.ev-bullet-inputs > div { height: 26px; }
/* ====== The what-if boxes ======
   One per bullet row, aligned with it, and the row's readout as well as its
   control: the value used to appear twice, once inside a gauge arc and again
   in a box underneath it. */
.ev-whatif-input {
  background: var(--ev-bg-deep) !important;
  color: var(--ev-text) !important;
  border: 1px solid var(--ev-surface-2) !important;
  border-radius: 8px !important;
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ev-whatif-input:focus {
  border-color: #D86CB4 !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, #D86CB4 22%, transparent) !important;
  outline: none;
}
/* A disabled box is still worth reading: it is the published value. It just
   must not look like somewhere to type. */
.ev-whatif-input:disabled {
  opacity: .55;
  cursor: not-allowed;
}

.ev-bullet-inputs .ev-whatif-input {
  height: 26px;
  padding: 0 .5rem !important;
  font-size: .82rem;
}
/* The composite box is a readout: it shows the score the six above it add up
   to and is never typed into, so it does not carry the dimmed look the other
   five get when the calculator is off. */
.ev-whatif-derived {
  opacity: 1 !important;
  font-weight: 600;
  cursor: default;
}

/* ==========================================================================
   Top 10
   ==========================================================================
   Two questions side by side, because they disagree: the ten highest
   composite scores, and the ten highest of each indicator that goes into
   that score. The disagreement is the finding, so the layout puts the lists
   where one glance covers both.

   The heights here are shared with citations_lib/top10.py. ECharts measures
   the element it draws into, so a chart div with no height renders nothing
   at all rather than rendering small. COMPOSITE: 12 top + ten 44px rows + 6
   bottom. CELL: ten rows at 26px plus the labels' own padding. */

.ev-top10 { width: 100%; max-width: 1500px; text-align: left; }

.ev-top10 .ev-panel-toolbar { justify-content: space-between; gap: 1rem; }
.ev-top10-switch { display: flex; align-items: center; }

.ev-top10-head { margin-bottom: .35rem; }
.ev-top10-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ev-text);
  margin: 0;
}
.ev-top10-sub {
  font-size: .84rem;
  color: var(--ev-text-muted);
  margin: .15rem 0 0;
  max-width: 62ch;
}

.ev-top10-main { margin-top: 1rem; min-width: 0; }

/* The ranked names and the bars they belong to, side by side.

   The names are HTML rather than axis labels because a two-line axis label
   cannot be aligned across rows. That means this file owns the alignment:
   .ev-top10-listrow is the chart's ROW constant and the column's padding-top
   is its TOP. Both live in COMPOSITE_DRAW_JS in citations_lib/top10.py, and
   if one changes the other has to. */
.ev-top10-listing {
  display: grid;
  grid-template-columns: minmax(240px, 330px) minmax(0, 1fr);
  align-items: start;
}
.ev-top10-rows { padding-top: 30px; }
.ev-top10-listrow {
  display: flex;
  align-items: center;
  gap: .55rem;
  width: 100%;
  height: 52px;
  padding: 0 .4rem;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: inherit;
  cursor: pointer;
  transition: background .12s ease;
}
.ev-top10-listrow:hover { background: var(--ev-surface); }
.ev-top10-listrow:focus-visible {
  outline: 2px solid var(--ev-accent);
  outline-offset: -2px;
}
.ev-top10-flag {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
}
/* A country with no two-letter code still has to occupy the same space, or
   the names below it step sideways. */
.ev-top10-flag-none {
  flex: 0 0 22px;
  font-size: .6rem;
  color: var(--ev-text-muted);
  text-align: center;
}
.ev-top10-rank {
  flex: 0 0 22px;
  text-align: right;
  font-size: .82rem;
  font-weight: 700;
  color: var(--ev-accent);
  font-variant-numeric: tabular-nums;
}
.ev-top10-who { min-width: 0; display: flex; flex-direction: column; }
.ev-top10-name {
  font-size: .84rem;
  color: var(--ev-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ev-top10-inst {
  font-size: .68rem;
  color: var(--ev-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Self-citations, under the name. Drawn against 30% rather than 100%,
   because everyone on these lists sits in the low single digits and against
   100 they are all the same invisible sliver. */
.ev-top10-self {
  display: flex;
  align-items: center;
  gap: .35rem;
  /* Tight to the institution above it rather than floating midway to the
     next researcher's name, which is what 2px looked like. */
  margin-top: 0;
  line-height: 1;
}
.ev-top10-self-track {
  flex: 0 0 52px;
  height: 3px;
  border-radius: 2px;
  background: var(--ev-surface-2);
  overflow: hidden;
}
.ev-top10-self-fill {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--ev-orange);
}
.ev-top10-self-value {
  font-size: .62rem;
  color: var(--ev-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 30 top, for the axis labels above the plot, then ten 52px rows and 6
   below. */
.ev-top10-composite { height: 556px; width: 100%; }

.ev-top10-legend {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1rem;
  margin-top: .35rem;
  font-size: .78rem;
  color: var(--ev-text-muted);
}
.ev-top10-key {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: .35rem;
  vertical-align: middle;
}
.ev-top10-key-shared { background: var(--ev-accent); }
.ev-top10-key-dim    { background: var(--ev-cat-dim); }
.ev-top10-key-follow { background: var(--ev-magenta); }
.ev-top10-key-self   { background: var(--ev-orange); }

.ev-top10-note:empty { display: none; }
.ev-top10-warning {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  padding: .55rem .7rem;
  margin: .5rem 0;
  border-radius: var(--ev-radius);
  border: 1px solid color-mix(in srgb, var(--ev-orange) 45%, transparent);
  background: color-mix(in srgb, var(--ev-orange) 12%, transparent);
  color: var(--ev-text);
  font-size: .82rem;
}

/* The six indicators. Three across on a wide screen, because six charts in
   two rows of three is one shape the eye can take in, and two across or one
   below that. */
.ev-top10-metrics { margin-top: 1.5rem; }
.ev-top10-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-top: .75rem;
}
.ev-top10-cell {
  background: var(--ev-surface);
  border: 1px solid var(--ev-surface-2);
  border-radius: var(--ev-radius);
  padding: .6rem .7rem .4rem;
}
.ev-top10-cell-title {
  font-size: .82rem;
  font-weight: 600;
  color: var(--ev-text);
  margin-bottom: .2rem;
}
.ev-top10-cell-chart { height: 286px; width: 100%; }

@media (max-width: 1240px) {
  .ev-top10-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .ev-top10-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Where to read the work behind the numbers. Sits under the card's header,
   empty until OpenAlex confirms which researcher this is, so the row has no
   height of its own when there is no confident match. */
.ev-id-links:empty { display: none; }
.ev-id-links {
  display: flex;
  gap: .5rem;
  margin: -.2rem 0 .6rem;
}
.ev-id-link {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .76rem;
  color: var(--ev-text-muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.ev-id-link:hover {
  color: var(--ev-accent);
  border-bottom-color: var(--ev-accent);
}

/* ==========================================================================
   The city map
   ==========================================================================
   Under the choropleth and on the same toolbar. ECharts measures the element
   it draws into, so this needs a height of its own or it renders nothing at
   all rather than rendering small. */

.ev-glow { display: flex; flex-direction: column; width: 100%; }
.ev-glow-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: .5rem;
}
.ev-glow-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ev-text);
  margin: 0;
}
.ev-glow-sub {
  font-size: .84rem;
  color: var(--ev-text-muted);
  margin: .15rem 0 0;
  max-width: 68ch;
}
/* Two button rows, granularity then measure, sitting together at the right
   of the heading. */
.ev-glow-measures { display: flex; gap: .5rem; flex-wrap: wrap; }

/* The years, as a track under the map. The radio buttons in the toolbar
   above say the same thing and drive the same selection; this is for walking
   the editions rather than aiming at one. dcc.Slider ships unstyled, so
   these are its own class names rather than the app's. */
/* The arrows sit either side of the track, so a reader can step one edition
   at a time instead of aiming at a mark. */
.ev-glow-track {
  display: flex;
  align-items: stretch;
  background: var(--ev-bg-deep);
  border: 1px solid var(--ev-surface-2);
  border-top: 0;
  border-radius: 0 0 var(--ev-radius) var(--ev-radius);
  margin-top: -1px;
}
.ev-glow-track .ev-glow-years {
  flex: 1 1 auto;
  background: transparent;
  border: 0;
  border-radius: 0;
  margin-top: 0;
}
.ev-glow-step {
  flex: 0 0 34px;
  background: transparent;
  border: 0;
  color: var(--ev-text-muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0 1.1rem;
}
.ev-glow-step:hover { color: var(--ev-accent); }

.ev-glow-years {
  padding: .5rem 1.5rem .25rem;
  background: var(--ev-bg-deep);
  border: 1px solid var(--ev-surface-2);
  border-top: 0;
  border-radius: 0 0 var(--ev-radius) var(--ev-radius);
  margin-top: -1px;
}
.ev-glow-years .rc-slider-rail { background-color: var(--ev-surface-2); }
.ev-glow-years .rc-slider-track { background-color: transparent; }
.ev-glow-years .rc-slider-dot {
  background-color: var(--ev-surface-2);
  border-color: var(--ev-surface-2);
}
.ev-glow-years .rc-slider-dot-active {
  background-color: var(--ev-accent);
  border-color: var(--ev-accent);
}
.ev-glow-years .rc-slider-handle {
  background-color: var(--ev-accent);
  border-color: var(--ev-accent);
  opacity: 1;
}
.ev-glow-years .rc-slider-handle:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ev-accent) 35%, transparent);
}
.ev-glow-years .rc-slider-mark-text {
  color: var(--ev-text-muted);
  font-size: .72rem;
}
.ev-glow-years .rc-slider-mark-text-active { color: var(--ev-text); }

/* The map and its zoom buttons, which sit over its top right corner. */
.ev-glow-frame { position: relative; }
.ev-glow-zoom {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ev-glow-zoom-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .95rem;
  line-height: 1;
  color: var(--ev-text);
  background: color-mix(in srgb, #0B1020 80%, transparent);
  border: 1px solid #243049;
  border-radius: 6px;
  cursor: pointer;
}
.ev-glow-zoom-btn:hover {
  border-color: var(--ev-accent);
  color: var(--ev-accent);
}

.ev-glow-chart {
  flex: 1 1 auto;
  min-height: 460px;
  height: 560px;
  width: 100%;
  border-radius: var(--ev-radius) var(--ev-radius) 0 0;
  overflow: hidden;
  border: 1px solid var(--ev-surface-2);
}
@media (max-width: 900px) {
  .ev-glow-chart { height: 420px; }
}

/* ==========================================================================
   The map and the list beside it
   ==========================================================================
   They are one row of two panes and they have to start and end together.
   The map pane is the map, its header and its year track; the list pane is
   the statistic, the summary and the table. Before this the two began at
   different heights, because one started with a heading and the other with a
   dropdown. */

.ev-panes { align-items: stretch; }
.ev-panes > [class*="col"] { display: flex; }
.ev-map-pane,
.ev-list-pane {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
}
/* Both panes open with a control row of the same height, so the map and the
   summary below them line up. */
.ev-glow-head,
.ev-pane-head {
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: .75rem;
  margin-bottom: .5rem;
}
.ev-pane-head { justify-content: space-between; }
.ev-pane-label {
  font-size: .78rem;
  color: var(--ev-text-muted);
  white-space: nowrap;
}
.ev-pane-head .Select, .ev-pane-head > div:last-child { min-width: 190px; }
.ev-list-pane > :last-child { flex: 1 1 auto; min-height: 0; }

/* Dataset, granularity and measure are one row of buttons, set together at
   the left rather than one group at each end. They wrap as a group on a
   narrow screen. */
.ev-glow-head { justify-content: flex-start; flex-wrap: wrap; }
.ev-glow-measures { align-items: center; }
/* The three groups are one set of controls, so they are sized and coloured
   as one. The dataset toggle carried orange from a rule that exists to keep
   it apart from a cyan year picker beside it; on this map the year picker is
   the track underneath and there is nothing to be told apart from, so it
   takes the same cyan as its neighbours. The rule it is overriding is
   !important, which is why this one is too. */
.ev-glow-measures .radio-group .btn-group > .form-check > .btn,
.ev-glow-measures .radio-group .btn {
  padding: .3rem .65rem;
  font-size: .82rem;
  line-height: 1.35;
}
.ev-glow-measures [id^="careerORSingleYr"] .btn.active {
  background-color: var(--ev-accent) !important;
  border-color: var(--ev-accent) !important;
  color: #10151D !important;
}
/* In the light theme the granularity and measure buttons were white on
   white. Their labels are Bootstrap .btn-outline-primary, whose colour comes
   from SLATE and is tuned for a dark ground; the year picker and the dataset
   toggle were given the theme's own foreground long ago and these two groups
   were missed. Saying it here rather than adding two more ids to that rule
   keeps this row's appearance in the block that describes this row. */
.ev-glow-measures .radio-group .btn {
  color: var(--ev-text) !important;
  background-color: transparent !important;
  border-color: var(--ev-surface-2) !important;
}
.ev-glow-measures .radio-group .btn:hover:not(.active) {
  background-color: var(--ev-surface-2) !important;
}
/* The transparent ground above is !important, so the selected button has to
   say its fill at least as loudly or the selection disappears. */
.ev-glow-measures .radio-group .btn.active {
  background-color: var(--ev-accent) !important;
  border-color: var(--ev-accent) !important;
}

/* An icon-only navbar button, for "about this data". */
.ev-nav-icon { padding-left: .55rem; padding-right: .55rem; }

/* ==========================================================================
   The card over the list
   ==========================================================================
   Clicking a row used to print its detail under the table, which pushed the
   table up and meant reading one row cost you the sight of the others. It
   sits over the list now and closes.

   It sits over the map, not over the list: the list is what the reader is
   working through, and covering that takes away the thing they are reading.
   The glass is a blur of what is behind it plus a translucent fill, which
   needs something behind it to blur, and the map is the darkest, busiest
   thing on the page to put it against. It clears the year track below. */

.ev-map-pane { position: relative; }
.ev-row-card {
  position: absolute;
  /* Centred on the map rather than sitting on its bottom edge, which put it
     over the year track and read as a bar rather than as a card. */
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  width: min(520px, calc(100% - 2rem));
  max-height: 76%;
  overflow-y: auto;
  padding: 1rem 1.1rem .6rem;
  border-radius: var(--ev-radius);
  border: 1px solid color-mix(in srgb, var(--ev-text) 14%, transparent);
  background: color-mix(in srgb, var(--ev-surface) 62%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
          backdrop-filter: blur(14px) saturate(140%);
  box-shadow: 0 8px 30px rgba(0, 0, 0, .35);
  /* Above the hint card, which is absolutely positioned in the same corner
     of the same pane and would otherwise share a stacking order with it. */
  z-index: 6;
}
/* Without backdrop-filter the fill alone would leave the table legible
   through it, so browsers that cannot blur get an opaque card instead. */
@supports not ((backdrop-filter: blur(1px)) or
               (-webkit-backdrop-filter: blur(1px))) {
  .ev-row-card { background: var(--ev-surface); }
}
.ev-row-card > :last-child { margin-bottom: 0; }
.ev-row-card-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--ev-text-muted);
  cursor: pointer;
}
.ev-row-card-close:hover {
  color: var(--ev-text);
  border-color: var(--ev-surface-2);
}
.ev-row-card-close .ev-ic { width: 15px; height: 15px; }

/* ==========================================================================
   The dataset toggle, as two icons
   ==========================================================================
   Career and single-year are a pair of icons rather than a pair of words, on
   every page that has this control. Words gave it a width of its own: the
   rules that size a dataset toggle are keyed to the careerORSingleYr id
   prefix and were written for a toolbar where it stands alone and is meant
   to be large, 118px per half. That is wrong wherever it stands next to
   something else, and an icon is the same size whatever it says. The minimum
   has to be said louder than the rule it overrides, which is why it carries
   !important. */
.ev-kind-toggle .btn-group > .form-check {
  flex: 0 0 auto !important;
  min-width: 0 !important;
}
.ev-kind-toggle .btn {
  min-width: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* The icons themselves, as masks on the label rather than as an element
   inside it: dbc's RadioItems takes a string for a label and nothing else,
   so there is nowhere to put a span. A mask also inherits the label's
   colour, so the selected half's icon turns dark on the accent fill with no
   second rule. */
.ev-kind-toggle .btn::before {
  content: "";
  display: inline-block;
  /* As wide as the glyph and as tall as a line of the text in the buttons
     beside it, so this button comes out their height. Bootstrap's .btn has
     line-height 1.5; the row above the map sets its own and says so below.
     mask-size: contain keeps the glyph square inside that taller box. */
  width: 1.05em;
  height: var(--ev-kind-icon, 1.5em);
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
/* lucide "history": a clock with a rewind arrow, for the record that runs up
   to the year selected. */
.ev-kind-toggle .btn[id^="kindCareer"]::before {
  -webkit-mask-image: var(--ev-mask-history);
          mask-image: var(--ev-mask-history);
}
/* lucide "calendar": one year on its own. */
.ev-kind-toggle .btn[id^="kindSingle"]::before {
  -webkit-mask-image: var(--ev-mask-calendar);
          mask-image: var(--ev-mask-calendar);
}

/* The row above the map sets its own line-height and has no space above it,
   both of which the shared rules above and the id-prefixed ones would
   otherwise decide. */
.ev-glow-measures .ev-kind-toggle,
.ev-glow-measures .ev-kind-toggle .btn-group { margin-top: 0 !important; }
.ev-glow-measures .ev-kind-toggle { --ev-kind-icon: 1.35em; }
.ev-glow-measures .ev-kind-toggle .btn { padding: .3rem .7rem !important; }

/* The same two glyphs, as ordinary icons, for the prose beside the map. */
.ev-ic-history {
  -webkit-mask-image: var(--ev-mask-history);
          mask-image: var(--ev-mask-history);
}

/* ==========================================================================
   The place modal and the row card
   ==========================================================================
   A click on the map opens the place in a modal, once; a click on a row of
   its list opens the card over the map. Both are drawn from the Explore
   card's pieces (.ev-id-card, .ev-id-head, .ev-chip), plus the tiles below,
   so a researcher looks the same wherever they are opened. */

/* The modal's content is the card, with the close icon in its corner; the
   place card drawn into it gives up its own frame. */
.ev-place-modal {
  background: var(--ev-surface);
  border: 1px solid color-mix(in srgb, #ffffff 10%, transparent);
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
}
.ev-place-body { position: relative; padding: 1.4rem 1.6rem 1.1rem; }
.ev-place-body .ev-row-card-close { top: 12px; right: 12px; }
.ev-place-body .ev-id-head { margin-right: 2rem; }  /* clear of the icon */
.ev-place-modal .ev-id-card {
  background: transparent;
  border: none;
  box-shadow: none;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  padding: 0;
}
.ev-place-modal .ev-id-name { font-size: 1.6rem; }

/* Inside the row card the card is already a glass panel, so the inner one
   gives up its own frame. */
.ev-row-card .ev-id-card {
  background: transparent;
  box-shadow: none;
  border: none;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  padding: .2rem .4rem .4rem .2rem;
  margin-right: 1.4rem;   /* clear of the close button */
}

.ev-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: .7rem;
  margin: .9rem 0 .4rem;
}
.ev-tile {
  padding: .7rem .8rem .6rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--ev-bg-deep) 40%, transparent);
  border: 1px solid color-mix(in srgb, var(--ev-text) 8%, transparent);
}
.ev-tile-value {
  color: var(--ev-accent);
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.ev-tile-label {
  color: var(--ev-text);
  font-size: .8rem;
  font-weight: 600;
  margin-top: .3rem;
}
.ev-tile-detail {
  color: var(--ev-text-muted);
  font-size: .72rem;
  margin-top: .1rem;
}
.ev-tile-detail:empty { display: none; }
.ev-place-note {
  color: var(--ev-text-muted);
  margin: .6rem 0 .2rem;
}

/* The links under the row card: OpenAlex or ROR, a Scholar search, and the
   way into Explore. */
.ev-row-links {
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .9rem;
  margin: .5rem 0 .2rem .2rem;
}
.ev-row-links .ev-share-btn { margin-left: auto; }

/* The pane is as tall as the list column beside it, which is taller than
   the map, so centring the card on the pane put it over the year track and
   past the bottom of the map. It is centred on the map instead: the map's
   head is about 50px and the chart 560px (420px on narrow screens). */
.ev-row-card {
  top: 330px;
  max-height: 520px;
}
@media (max-width: 900px) {
  .ev-row-card { top: 260px; max-height: 400px; }
}
.ev-row-card .ev-tiles {
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
}
.ev-row-card .ev-tile-value { font-size: 1.35rem; }

/* The tip that says the what-if boxes can be typed into. Magenta is the
   what-if colour on the rest of the card. */
.ev-whatif-tip .tooltip-inner {
  max-width: 260px;
  padding: .6rem .75rem;
  text-align: left;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--ev-text);
  background: var(--ev-surface);
  border: 1px solid #D86CB4;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
}
.ev-whatif-tip .tooltip-inner strong { color: #D86CB4; }
.ev-whatif-tip.bs-tooltip-start .tooltip-arrow::before,
.ev-whatif-tip.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {
  border-left-color: #D86CB4;
}
.ev-whatif-tip { opacity: 1 !important; }

/* The notes beside the map. The dataset icons in the first note are drawn
   the way the toggle above the map draws them, bigger than the text around
   them, so a reader can match one to the other at a glance. */
.ev-map-notes .danger { margin-bottom: .75rem; }
.ev-kind-line { display: flex; align-items: flex-start; gap: .55rem; }
.ev-kind-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 7px;
  border: 1px solid var(--ev-surface-2);
  color: var(--ev-text);
  margin-top: -.2rem;
}
.ev-kind-chip .ev-ic { width: 17px; height: 17px; }
.ev-kind-chip-on {
  background: var(--ev-accent);
  border-color: var(--ev-accent);
  color: #10151D;
}
.ev-map-notes .ev-formula { margin: .4rem 0 .6rem; overflow-x: auto; }
.ev-map-notes .ev-formula mjx-container { font-size: 125% !important; }


/* ==========================================================================
   Icons on the switches
   ==========================================================================
   The icon rides in the knob, the circle that slides when the switch is
   thrown, rather than sitting beside the words underneath. daq builds that
   knob as a <button> with a generated class name, so it is matched on the
   part of the name daq controls.

   The knob is pale in both themes and in both states, so the glyph is dark
   and stays dark: it is a mark on the knob, not a second indicator of
   whether the switch is on. What the switch is set to is the knob's
   position and the colour behind it, which is what a switch has always
   said. */
.ev-switch button[class*="booleanswitch"][class*="__button"] {
  display: flex;
  align-items: center;
  justify-content: center;
}
.ev-switch button[class*="booleanswitch"][class*="__button"]::before {
  content: "";
  display: block;
  width: 62%;
  height: 62%;
  background-color: #1B2432;
  opacity: .78;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.ev-switch-whatif button[class*="__button"]::before {
  -webkit-mask-image: var(--ev-mask-flask);
          mask-image: var(--ev-mask-flask);
}
.ev-switch-selfcite button[class*="__button"]::before {
  -webkit-mask-image: var(--ev-mask-quote);
          mask-image: var(--ev-mask-quote);
}
.ev-switch-log button[class*="__button"]::before {
  -webkit-mask-image: var(--ev-mask-trend);
          mask-image: var(--ev-mask-trend);
}
