/* CCE Publications — widget/shortcode stylesheet (plugin asset, handle
   cce-publications). Ported unchanged from widget v2. Decisions built
   in: #42 #43 #45 #46 #48.

   NOTE (R4): the html{scrollbar-gutter:stable} rule below is a deliberate
   GLOBAL touch — it stops the sideways jump when filtering shortens the
   page. Documented in the README. */

.pub-publications.pub-publications{
  /* ---- design tokens: override via Elementor style controls ---- */
  --_pub-accent:  var(--pub-accent,  var(--pri1, #4E6470));
  --_pub-text:    var(--pub-text,    var(--blk1, #000000));
  --_pub-muted:   var(--pub-muted,   var(--gry4, #4E6470));
  --_pub-surface: var(--pub-surface, var(--wht1, #FFFFFF));
  --_pub-tint:    var(--pub-tint,    var(--gry1, #EBF1F5));
  --_pub-border:  var(--pub-border,  var(--gry2, #C8D3D9));
  --_pub-radius:  var(--pub-radius,  4px);
  --_pub-focus:   var(--pub-focus,   var(--_pub-accent));
  --_pub-rule:    var(--pub-rule,    var(--_pub-accent));
  /* Year sizes as tokens: the mobile breakpoint redefines them in ONE
     place, so the hover/focus rules below can restate the size without
     hard-coding the desktop value into every breakpoint. */
  --_pub-year-size:  24px;               /* type/h3 */
  --_pub-count-size: 16px;               /* type/small */

  font-family: Poppins, sans-serif;
  color: var(--_pub-text);
  /* Filtering shortens the document. Chrome's scroll anchoring would hold the
     old reading position and shift the list under the pointer. */
  overflow-anchor: none;
  /* Never shrink-to-fit: the block keeps its width when a filter leaves only
     short citations. */
  display: block;
  width: 100%;
}

/* The widget is a flex item of its Elementor container. If that container's
   "Elemente ausrichten" is anything but "Dehnen", its items are sized
   shrink-to-fit — the list is then as wide as its longest citation and every
   filter click resizes the block. Native Elementor setting first; this is the
   safety net. */
.elementor-widget-cce_publications.elementor-widget-cce_publications,
.elementor-widget-cce_publications.elementor-widget-cce_publications > .elementor-widget-container{
  align-self: stretch;
  width: 100%;
}

/* A scrollbar that comes and goes narrows and widens the viewport, so the page
   jumps sideways — filtering down to a short year is exactly that case. */
html{
  scrollbar-gutter: stable;
}

/* The UA rule for [hidden] is display:none, but the list-item / flex rules
   below are more specific and would win — restated at the same strength. */
.pub-publications.pub-publications [hidden]{
  display: none;
}

/* --- Editor preview banner (editor only, never on the live page) --------- */
.pub-preview-note.pub-preview-note{
  margin: 0 0 12px;
  padding: 8px 12px;
  background: var(--gry1, #EBF1F5);
  border: 1px dashed var(--gry2, #C8D3D9);
  border-radius: 4px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--gry4, #4E6470);
}

/* --- Filter bar ----------------------------------------------------------- */

.pub-filters.pub-filters{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pub-filter-gap, var(--gap-fluid, clamp(16px, 2vw, 32px)));
  margin: 0 0 24px;
  padding: 16px 0;
  /* Opaque on purpose: a sticky bar without a background lets the list show
     through it. */
  background: var(--pub-bar-bg, var(--_pub-surface));
  border-bottom: 1px solid var(--_pub-border);
  /* Above the list, below the combobox panel. */
  position: relative;
  z-index: 2;
}

/* Sticky is a widget setting, because the bar is tall: with three filters it
   measures 129px on a desktop and 219px on a 390px phone — a quarter of the
   screen, permanently. "Desktop only" is the default the widget ships with.
   --pub-sticky-top is the "site header height" control: a sticky site header
   would otherwise slide over the bar at top: 0. */
.pub-publications--sticky-always.pub-publications--sticky-always .pub-filters{
  position: sticky;
  top: var(--pub-sticky-top, 0px);
}
@media (min-width: 768px){
  .pub-publications--sticky-desktop.pub-publications--sticky-desktop .pub-filters{
    position: sticky;
    top: var(--pub-sticky-top, 0px);
  }
}

.pub-filter--year.pub-filter--year{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.pub-filter-btn.pub-filter-btn{
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: normal;
  color: var(--pub-btn-text, var(--_pub-muted));
  background: var(--pub-btn-bg, var(--_pub-tint));
  border: 1px solid var(--pub-btn-border, var(--_pub-border));
  border-radius: var(--_pub-radius);
  padding: 6px 14px;
  cursor: pointer;
  /* Transition over colours only. Anything geometric here moves the layout on
     hover — that was one of the six shift causes fixed in the filter-UX pass. */
  transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

/* The theme's button rules grow the button on hover. Every state restates the
   FULL metrics — font included — so the bar cannot move, whatever the theme
   does. (Confirmed live 2026-09-16: without font-size/-weight here a theme
   hover rule changed the type and the buttons breathed on hover.) A widget
   typography control still wins: its selector is 4 classes strong. */
.pub-filter-btn.pub-filter-btn:hover,
.pub-filter-btn.pub-filter-btn:focus,
.pub-filter-btn.pub-filter-btn:focus-visible,
.pub-filter-btn.pub-filter-btn:active,
.pub-filter-btn.pub-filter-btn.is-active{
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: normal;
  padding: 6px 14px;
  /* Style AND width: a theme that sets `border: none` on hover would
     otherwise drop the border and the button would shrink by 2px. */
  border-style: solid;
  border-width: 1px;
  /* `transform: none` does NOT reset the individual transform
     properties — a theme using `scale:` would still shrink the button. */
  transform: none;
  scale: none;
  translate: none;
  rotate: none;
  box-shadow: none;
}
.pub-filter-btn.pub-filter-btn:hover,
.pub-filter-btn.pub-filter-btn:focus-visible{
  background: var(--pub-btn-hover-bg, var(--_pub-border));
  color: var(--pub-btn-hover-text, var(--_pub-text));
  border-color: var(--pub-btn-hover-border, var(--pub-btn-border, var(--_pub-border)));
}
.pub-filter-btn.pub-filter-btn:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 2px;
}
.pub-filter-btn.pub-filter-btn.is-active{
  background: var(--pub-btn-active-bg, var(--_pub-accent));
  border-color: var(--pub-btn-active-bg, var(--_pub-accent));
  color: var(--pub-btn-active-text, var(--_pub-surface));
}

.pub-filter--pi.pub-filter--pi,
.pub-filter--q.pub-filter--q{
  display: flex;
  align-items: center;
  gap: 8px;
}
.pub-filter-label.pub-filter-label{
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-muted);
  margin: 0;
}

/* Fixed width: a field that grows with the selected name shifts the whole bar
   the moment a long PI is chosen. */
.pub-combo.pub-combo{
  position: relative;
  width: var(--pub-combo-w, 260px);
  max-width: 100%;
}
.pub-combo--years.pub-combo--years{
  width: auto;
}
.pub-q.pub-q{
  position: relative;
  width: var(--pub-q-w, 240px);
  max-width: 100%;
}

.pub-combo-input.pub-combo-input,
.pub-q-input.pub-q-input{
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-text);
  background: var(--_pub-surface);
  border: 1px solid var(--_pub-border);
  border-radius: var(--_pub-radius);
  padding: 6px 34px 6px 10px;
  width: 100%;
  /* iOS zooms into any field below 16px on focus; 16 is the floor, not a
     preference. */
  -webkit-appearance: none;
  appearance: none;
}
.pub-combo-input.pub-combo-input:focus,
.pub-q-input.pub-q-input:focus{
  outline: none;
  border-color: var(--_pub-focus);
  box-shadow: 0 0 0 1px var(--_pub-focus);
}

.pub-combo-clear.pub-combo-clear{
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  /* padding 0 + flex centering: the theme gives every <button> a padding,
     which pushed the × off-center in the live install. */
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  border-radius: var(--_pub-radius);
  font-size: 18px;
  line-height: 1;
  color: var(--_pub-muted);
  cursor: pointer;
}
.pub-combo-clear.pub-combo-clear:hover{
  color: var(--_pub-text);
  background: var(--_pub-tint);
}
.pub-combo-clear.pub-combo-clear:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 1px;
}

/* Absolutely positioned over the list, never in the flow — otherwise opening
   the panel pushes the whole page down. */
.pub-combo-list.pub-combo-list{
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 10;
  min-width: 160px;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: var(--_pub-surface);
  border: 1px solid var(--_pub-border);
  border-radius: var(--_pub-radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .12);
}
.pub-combo-option.pub-combo-option{
  padding: 7px 12px;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-text);
  cursor: pointer;
}
.pub-combo-option.pub-combo-option:hover,
.pub-combo-option.pub-combo-option.is-active{
  background: var(--_pub-tint);
}
.pub-combo-option.pub-combo-option.is-selected{
  font-weight: 600;
}
.pub-combo-empty.pub-combo-empty{
  padding: 7px 12px;
  font-size: 15px;
  line-height: 1.4;
  color: var(--_pub-muted);
}

/* --- Status band, notice, empty state ------------------------------------- */

/* A filtered view says so in words. Without it a short list looks broken —
   one PI with a single publication would read as a bug. */
.pub-status.pub-status{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 16px;
  margin: 0 0 24px;
  padding: 12px 16px;
  background: var(--pub-status-bg, var(--_pub-tint));
  border-left: 4px solid var(--pub-status-accent, var(--_pub-accent));
}
.pub-status-text.pub-status-text{
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-text);
  margin: 0;
}
.pub-status-reset.pub-status-reset{
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-muted);
  text-decoration: underline;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.pub-status-reset.pub-status-reset:hover{
  color: var(--_pub-text);
}
.pub-status-reset.pub-status-reset:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 3px;
  border-radius: var(--_pub-radius);
}

/* Unknown ?pi= in the address: full list plus this line. */
.pub-notice.pub-notice{
  margin: 0 0 24px;
  padding: 12px 16px;
  background: var(--pub-error-bg, var(--cce-error-bg, #FDEBEB));
  border-left: 4px solid var(--pub-error-accent, var(--cce-error-red, #C03232));
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-text);
}

.pub-empty.pub-empty{
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-muted);
  margin: 24px 0;
}

/* --- Year groups (collapsible) --------------------------------------------- */

.pub-year-group.pub-year-group{
  margin: 0 0 var(--pub-group-gap, 32px);   /* space/32 */
}

/* The heading stays an <h2> for the document outline; the button inside is the
   control. A button that replaced the heading would take the year out of the
   outline, and the year is how this page is navigated. */
.pub-year-heading.pub-year-heading{
  margin: 0 0 12px;
  padding: 0;
  border: 0;
}
.pub-year-toggle.pub-year-toggle{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  font-family: inherit;
  font-size: var(--_pub-year-size);
  line-height: 1.2;
  font-weight: 700;
  color: var(--_pub-text);
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 2px solid var(--_pub-rule);
  border-radius: 0;
  padding: 0 0 8px;
  cursor: pointer;
}
/* Every state restates the FULL metrics — colour and font included — the
   same lesson the filter buttons already carry. It was only half-applied
   here, and both halves that were missing showed up live: without `color`
   the theme's button-hover colour made the year vanish, and because
   :focus shares this rule the year stayed invisible after a click; without
   the font metrics the heading moved a little on hover and while toggling.
   A widget Style control still wins — its selector is several classes
   stronger than this one. */
.pub-year-toggle.pub-year-toggle:hover,
.pub-year-toggle.pub-year-toggle:focus,
.pub-year-toggle.pub-year-toggle:focus-visible,
.pub-year-toggle.pub-year-toggle:active{
  font-family: inherit;
  font-size: var(--_pub-year-size);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: normal;
  color: var(--_pub-text);
  text-decoration: none;
  background: none;
  /* The FULL shorthand, not just the width: restating the width alone
     left a theme's `border: none` or transparent colour in place, and
     the rule under the year disappeared on hover. */
  border-bottom: 2px solid var(--_pub-rule);
  padding: 0 0 8px;
  transform: none;
  scale: none;
  translate: none;
  rotate: none;
  box-shadow: none;
}

/* The hover/focus look itself, driven by the panel. Both tokens fall back
   to the rest values, so an untouched widget does not change on hover —
   it only stops the theme from changing it. */
.pub-year-toggle.pub-year-toggle:hover,
.pub-year-toggle.pub-year-toggle:focus-visible{
  color: var(--pub-year-hover, var(--_pub-text));
  border-bottom-color: var(--pub-rule-hover, var(--_pub-rule));
}
/* The count sits inside the button, so a theme rule that recolours
   descendants on hover would take it along with the year. */
.pub-year-toggle.pub-year-toggle:hover .pub-year-count,
.pub-year-toggle.pub-year-toggle:focus .pub-year-count,
.pub-year-toggle.pub-year-toggle:active .pub-year-count{
  font-size: var(--_pub-count-size);
  color: var(--_pub-muted);
}
.pub-year-toggle.pub-year-toggle:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 3px;
}
.pub-year-count.pub-year-count{
  font-size: var(--_pub-count-size);
  line-height: 1.4;
  font-weight: 400;
  color: var(--_pub-muted);
  white-space: nowrap;
}
/* The caret is CSS, not markup — the label text stays copyable and screen
   readers get the state from aria-expanded instead of a glyph. */
.pub-year-count.pub-year-count::after{
  content: " \25BE";                     /* ▾ */
}
.pub-year-toggle[aria-expanded="true"] .pub-year-count.pub-year-count::after{
  content: " \25B4";                     /* ▴ */
}

.pub-year-list.pub-year-list{
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --- The entry -------------------------------------------------------------- */

/* Zebra instead of a divider (#45): at four lines per entry the surface holds
   the entry together, which a 1px line does not. No corner radius — the tinted
   band runs straight to the edge like a table row. nth-child, not nth-of-type:
   the list holds only <li>, and nth-child keeps counting correctly once the
   filter hides entries. :nth-child ignores [hidden], so a filtered list can
   show two tinted rows in a row — accepted, the alternative is renumbering in
   JS on every keystroke. */
.pub-item.pub-item{
  list-style: none;
  margin: 0;
  padding: 16px;                         /* space/16 */
  background: var(--pub-zebra-even, var(--_pub-surface));
}
.pub-item.pub-item:nth-child(odd){
  background: var(--pub-zebra-odd, var(--_pub-tint));
}

/* space/4 between the lines — as a sibling rule, not per line type, so the
   rows keep correct spacing in ANY order (the row order is a widget control). */
.pub-item.pub-item > * + *{
  margin-top: var(--pub-entry-gap, 4px); /* space/4 */
}

.pub-title.pub-title{
  display: block;
  font-size: 16px;                       /* type/small */
  line-height: 1.4;
  font-weight: 400;
  color: var(--_pub-text);
}
.pub-authors.pub-authors{
  display: block;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-muted);
}
/* A PI among the authors (Figma 4142:1593): bold surname, colour of the
   author line unless the widget sets one. */
.pub-pi.pub-pi{
  font-weight: 700;
  color: inherit;
}
.pub-venue.pub-venue{
  display: block;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-text);
}
/* The journal carries the emphasis, not the title (#42). */
.pub-journal.pub-journal{
  font-weight: 700;
  font-style: normal;
}
.pub-ref.pub-ref{
  font-weight: 400;
}

.pub-doi.pub-doi{
  display: inline-block;
  font-size: 14px;                       /* type/meta */
  line-height: 1.4;
  color: var(--_pub-muted);
  text-decoration: underline;
  border-radius: var(--_pub-radius);
  /* DOIs have no spaces; without this a long one widens the whole block. */
  overflow-wrap: anywhere;
}
.pub-doi-label.pub-doi-label{
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
  margin-right: 4px;
}
.pub-doi.pub-doi:hover{
  color: var(--_pub-text);
}
/* The one addition of #45: focus must be visible, not only hover. The DOI link
   is the single interactive target in a row, so a keyboard user has to see
   where they are. */
.pub-doi.pub-doi:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 3px;
  color: var(--_pub-text);
}

/* Free-text search hits in title + authors. <mark> keeps its UA meaning
   (relevance highlight, screen readers announce it); only the color is ours.
   Yellow is the shipped default, the widget control writes --pub-hit-bg. */
.pub-publications.pub-publications mark.pub-hit{
  background: var(--pub-hit-bg, #FFEB3B);
  color: inherit;
  padding: 0;
}

/* Line length — the open point from #45, switchable in the widget. A full
   1040px container is roughly 120 characters per line; 72 is the middle of the
   usual recommendation. The tinted band keeps running full width; only the
   text column is capped. */
.pub-publications--measured.pub-publications--measured .pub-title,
.pub-publications--measured.pub-publications--measured .pub-authors,
.pub-publications--measured.pub-publications--measured .pub-venue{
  max-width: var(--pub-measure, 72ch);
}

/* --- Block heading + total count (Figma 4142:1594) ------------------------- */

.pub-head.pub-head{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 16px;                         /* space/16 */
  margin: 0 0 24px;                      /* space/24 */
}
.pub-heading.pub-heading{
  margin: 0;
  padding: 0;
  font-family: inherit;
  font-size: 36px;                       /* H2 */
  line-height: 1.2;
  font-weight: 700;
  color: var(--_pub-text);
}
.pub-total.pub-total{
  margin: 0;
  font-size: 16px;                       /* type/small */
  line-height: 1.4;
  font-weight: 400;
  color: var(--_pub-muted);
}

/* --- Flat layout (Figma 4142:1593) ------------------------------------------ */

/* Fixed year headings instead of the accordion. Only the deltas to the
   accordion look live here; entries, zebra and search are shared. */
.pub-publications--flat.pub-publications--flat .pub-filters{
  padding-top: 0;                        /* the bar starts right under the head */
  gap: var(--pub-filter-gap, 32px);      /* space/32 between years and search */
}
.pub-publications--flat.pub-publications--flat .pub-year-group{
  margin-bottom: var(--pub-group-gap, 24px);
}
/* No visible "Search" label in the design; the <label> stays for screen
   readers, which is why it is clipped rather than removed. */
.pub-publications--flat.pub-publications--flat .pub-filter--q .pub-filter-label{
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* Buttons are Regular in this design (500 in the accordion bar). Same
   selector strength as the state block above, so hover cannot flip it. */
.pub-publications--flat .pub-filter-btn.pub-filter-btn,
.pub-publications--flat .pub-filter-btn.pub-filter-btn:hover,
.pub-publications--flat .pub-filter-btn.pub-filter-btn:focus,
.pub-publications--flat .pub-filter-btn.pub-filter-btn:focus-visible,
.pub-publications--flat .pub-filter-btn.pub-filter-btn:active,
.pub-publications--flat .pub-filter-btn.pub-filter-btn.is-active{
  font-weight: 400;
}

.pub-year-heading--flat.pub-year-heading--flat{
  margin: 0 0 16px;                      /* space/16 to the entries */
  padding: 0 0 8px;                      /* space/8 to the rule */
  border-bottom: 2px solid var(--_pub-rule);
}
.pub-year-title.pub-year-title{
  display: block;
  font-family: inherit;
  font-size: var(--_pub-year-size);      /* type/h3 */
  line-height: 1.2;
  font-weight: 700;
  color: var(--_pub-muted);
}

/* --- Person mode (Figma 4142:1734, #139) ----------------------------------- */

/* The list on a person page: a white card on the page ground. Only the
   person modifier carries these rules, so every other placement stays
   exactly as it was. The palette reads the V4 role variables, which the
   site prints on :root, with the decided hex as fallback — not the
   cce-type-* classes, which are not guaranteed on the page. A widget
   palette control (--pub-*) still wins. Same strength as the base token
   block and later in the file, so these tokens replace those. */
.pub-publications--person.pub-publications--person{
  --_pub-accent:  var(--pub-accent,  var(--text-muted, #4E6470));
  --_pub-text:    var(--pub-text,    var(--text-default, #000000));
  --_pub-muted:   var(--pub-muted,   var(--text-muted, #4E6470));
  --_pub-meta:    var(--pub-meta,    var(--text-meta, #9AABB5));
  --_pub-surface: var(--pub-surface, var(--surface-card, #FFFFFF));
  --_pub-tint:    var(--pub-tint,    var(--bg-page, #EBF1F5));
  --_pub-border:  var(--pub-border,  var(--border-default, #C8D3D9));
  --_pub-radius:  var(--pub-radius,  var(--radius-sm, 4px));

  display: flex;
  flex-direction: column;
  gap: var(--space-24, 24px);            /* between head, bar, groups, button */
  box-sizing: border-box;                /* width 100% includes the padding */
  padding: var(--space-24, 24px);
  background: var(--_pub-surface);
  border-radius: var(--radius-md, 8px);
}

/* The card's gap does the spacing; the margins of the other layouts would
   add to it. Three classes: beats the flat-layout group margin (also
   three, earlier in the file) and the mobile bar margin (two). */
.pub-publications--person.pub-publications--person .pub-head,
.pub-publications--person.pub-publications--person .pub-filters,
.pub-publications--person.pub-publications--person .pub-year-group,
.pub-publications--person.pub-publications--person .pub-empty,
.pub-publications--person.pub-publications--person .pub-all{
  margin: 0;
}
.pub-publications--person.pub-publications--person .pub-filters{
  padding: 0 0 var(--space-16, 16px);
}

.pub-publications--person.pub-publications--person .pub-q-input::placeholder{
  color: var(--_pub-meta);
  opacity: 1;                            /* Firefox dims placeholders */
}

.pub-publications--person.pub-publications--person .pub-doi-label{
  font-weight: 700;
}

/* "See all publications": pill, Poppins (the site's buttons are
   Alexandria), centred under the list. Every state restates the metrics —
   the theme's link and button rules are the same risk as for the filter
   buttons. */
.pub-publications--person.pub-publications--person .pub-all{
  display: flex;
  justify-content: center;
}
.pub-publications--person.pub-publications--person .pub-all-link,
.pub-publications--person.pub-publications--person .pub-all-link:hover,
.pub-publications--person.pub-publications--person .pub-all-link:focus,
.pub-publications--person.pub-publications--person .pub-all-link:active{
  display: inline-flex;
  align-items: center;
  /* Matches the site's V3 pill button (sample on page 12235, measured 2026-10-15): 229×48. */
  padding: var(--space-16, 16px) var(--space-24, 24px);
  border-radius: 24px;
  font-family: inherit;
  font-size: 16px;
  line-height: 1;
  font-weight: 400;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--_pub-text);
  background: var(--_pub-tint);
  transition: background-color .3s ease, color .3s ease;
}
.pub-publications--person.pub-publications--person .pub-all-link:hover,
.pub-publications--person.pub-publications--person .pub-all-link:focus-visible{
  color: var(--wht1, #FFFFFF);
  background: var(--_pub-text);
}
.pub-publications--person.pub-publications--person .pub-all-link:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 2px;
}

@media (max-width: 767px){
  .pub-publications--person.pub-publications--person{
    padding: var(--space-16, 16px);
  }
}

/* --- Editor placeholder (plugin missing) ----------------------------------- */

.pub-publications--placeholder.pub-publications--placeholder{
  padding: 24px;
  background: var(--gry1, #EBF1F5);
  border: 1px dashed var(--gry2, #C8D3D9);
  font-size: 16px;
  line-height: 1.4;
  color: var(--gry4, #4E6470);
}

/* --- Mobile ------------------------------------------------------------------ */

@media (max-width: 767px){
  .pub-filters.pub-filters{
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
    margin-bottom: 24px;
  }
  .pub-combo.pub-combo,
  .pub-q.pub-q{
    width: 100%;
  }
  .pub-combo--years.pub-combo--years{
    width: auto;
  }
  /* One place per breakpoint: the state rules above read these tokens,
     so hovering or tapping cannot jump back to the desktop size. */
  .pub-publications.pub-publications{
    --_pub-year-size:  20px;
    --_pub-count-size: 14px;
  }
  .pub-title.pub-title,
  .pub-authors.pub-authors,
  .pub-venue.pub-venue{
    font-size: 15px;
  }
  .pub-item.pub-item{
    padding: 16px 12px;
  }
}

/* --- Optional "Show more" per year group (default off, 1.3 point 2) ------ */

/* Collapsed entries stay in the DOM (filters and search see them); only
   the paint is suppressed until the group is revealed. Like [hidden],
   collapsed rows keep their :nth-child slot — documented edge case. */
.pub-year-group:not(.pub-more-revealed) .pub-item.pub-item[data-pub-extra]{
  display: none;
}

.pub-more-row.pub-more-row{
  list-style: none;
  margin: 0;
  padding: 8px 16px;
}
.pub-more-btn.pub-more-btn{
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  color: var(--_pub-muted);
  text-decoration: underline;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.pub-more-btn.pub-more-btn:hover{
  color: var(--_pub-text);
}
.pub-more-btn.pub-more-btn:focus-visible{
  outline: 2px solid var(--_pub-focus);
  outline-offset: 3px;
  border-radius: var(--_pub-radius);
}
/* Disabled = revealed: keeps keyboard focus in place, reads as a state. */
.pub-more-btn.pub-more-btn:disabled{
  text-decoration: none;
  cursor: default;
  color: var(--_pub-muted);
}
