/*
Theme Name:   Veritas
Theme URI:    https://veritas.cse.tamu.edu/
Author:       Veritas Lab
Author URI:   https://veritas.cse.tamu.edu/
Description:  A standalone theme for the Veritas Lab in Computer Science & Engineering at Texas A&M University. Design direction "Assertion": white ground, hairline rules, a strict grid, and the wordmark's green reserved exclusively for verification signals. Publications render from posts, grouped by year.
Version:      4.3.0
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 7.4
License:      GNU General Public License v2 or later
License URI:  http://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  veritas
Tags:         education, research, one-column, custom-logo, custom-menu, accessibility-ready, translation-ready
*/

/* ==========================================================================
   1. TOKENS

   Brand colors are sampled from the wordmark: #3174DC (the "eritas" blue) and
   #1EB996 (the checkmark). Both are kept for large fills and decorative rules.
   Text and interactive states use the same hues darkened only as far as the
   WCAG thresholds require — the raw blue lands at exactly 4.50:1 on white and
   the raw green at 2.49:1, below the 3:1 floor for meaningful non-text UI.
   ========================================================================== */

:root {
  /* brand, as drawn */
  --v-blue-brand:  #3174DC;
  --v-green-brand: #1EB996;

  /* Sampled from the 2026 wordmark artwork. The navy is the logo's own ink;
     it is deliberately NOT wired into links or buttons — see CLAUDE.md. */
  --v-navy:        #001850;
  --v-teal:        #00B8A8;

  /* brand, shifted for contrast */
  --v-blue:        #2A65C4;  /* links, buttons        — 5.59:1 on white */
  --v-blue-deep:   #2159B4;  /* hover / pressed       — 6.66:1 */
  --v-blue-wash:   #EDF3FD;
  --v-green:       #159478;  /* rules, state markers  — 3.79:1 */
  --v-green-deep:  #0F7A62;  /* signal text           — 5.28:1 */
  --v-green-wash:  #E4F7F1;

  /* ink — cool-biased, never neutral grey */
  --v-ink:         #16202E;
  --v-ink-soft:    #5B6879;
  /* #7B8698 measured 3.68:1 on white and 3.45:1 on the tinted band — below the
     4.5:1 WCAG AA floor for text this size, and it is used for breadcrumbs,
     dates, venues and counts, all of which are small. #667286 clears the floor
     on both grounds (4.87:1 / 4.56:1) at the same visual weight. */
  --v-ink-faint:   #667286;

  /* ground */
  --v-surface:     #FFFFFF;
  --v-sunken:      #F5F8FB;
  --v-rule:        #E3E8EF;
  --v-rule-strong: #C8D2DF;

  /* type */
  --v-display: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --v-body:    "Source Sans 3", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --v-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* scale */
  --v-t-xs:  0.78rem;
  --v-t-sm:  0.9rem;
  --v-t-base: 1.0625rem;
  --v-t-md:  1.16rem;
  --v-t-lg:  1.34rem;
  --v-t-xl:  1.7rem;
  --v-t-2xl: clamp(1.85rem, 3.2vw, 2.4rem);
  --v-t-3xl: clamp(2.2rem, 4.4vw, 3.1rem);
  --v-t-4xl: clamp(2.6rem, 6vw, 4.2rem);
  /* The hero h1 now shares its row with the news card, so it is sized to the
     column it actually occupies rather than to the full viewport. */
  --v-t-hero: clamp(2.15rem, 4.4vw, 3.35rem);

  /* layout */
  --v-shell:   1240px;
  --v-gutter:  clamp(1.15rem, 3.2vw, 2.25rem);

  /* Band rhythm. This was clamp(3.75rem, 7.5vw, 6.5rem) — applied to both the
     top and the bottom of every band, so ~13rem of nothing stacked up between
     one section's last line and the next section's heading. Sections are
     separated by a hairline and a change of ground; they do not also need to be
     separated by most of a screen. */
  --v-section: clamp(2.5rem, 4.5vw, 3.75rem);

  --v-radius:  4px;
  --v-header-h: 68px;
}

/* ==========================================================================
   2. LEGACY BLOCK COMPATIBILITY

   Page content was authored against the previous Astra starter template and
   carries inline styles referencing --ast-global-color-*. Those variables no
   longer exist under this theme, so the inline styles would resolve to nothing.
   Map them onto this palette so existing pages keep rendering while their
   content is migrated.
   ========================================================================== */

:root {
  --ast-global-color-0: var(--v-blue);
  --ast-global-color-1: var(--v-blue-deep);
  --ast-global-color-2: var(--v-ink);
  --ast-global-color-3: var(--v-ink-soft);
  --ast-global-color-4: var(--v-sunken);
  --ast-global-color-5: var(--v-surface);
  --ast-global-color-6: var(--v-rule);
  --ast-global-color-7: var(--v-green);
  --ast-global-color-8: var(--v-ink);
}

.has-ast-global-color-0-background-color { background-color: var(--v-blue) !important; }
.has-ast-global-color-4-background-color,
.has-ast-global-color-6-background-color { background-color: var(--v-sunken) !important; }
.has-ast-global-color-5-background-color { background-color: var(--v-surface) !important; }
.has-ast-global-color-0-border-color { border-color: var(--v-rule) !important; }
.has-vivid-cyan-blue-color { color: var(--v-blue) !important; }
.has-black-color { color: var(--v-ink) !important; }

/* theme.json sets defaultPalette:false, so core's preset classes no longer
   ship CSS. Every core slug the legacy content actually uses is defined
   above; this list came from auditing post_content, not from guessing. */

/* ==========================================================================
   3. RESET + BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--v-surface);
  color: var(--v-ink);
  font-family: var(--v-body);
  font-size: var(--v-t-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--v-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
  color: var(--v-ink);
}

p { margin: 0; }

a { color: var(--v-blue); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--v-blue-deep); }

ul, ol { margin: 0; padding: 0; }

::selection { background: var(--v-green-wash); color: var(--v-ink); }

/* ==========================================================================
   4. LAYOUT PRIMITIVES
   ========================================================================== */

.v-shell {
  width: 100%;
  max-width: var(--v-shell);
  margin-inline: auto;
  padding-inline: var(--v-gutter);
}

.v-main { display: block; }

.v-section {
  padding-block: var(--v-section);
  border-top: 1px solid var(--v-rule);
}
.v-section--tint { background: var(--v-sunken); }
.v-section--invite { background: var(--v-surface); }

.v-grid { display: grid; gap: 1.35rem; }
.v-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.v-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Fills the row with as many columns as fit rather than holding a fixed two,
   which is what left the research cards stretched over half a screen each. */
.v-grid--fill { grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); }

/* A shell whose children manage their own bottom spacing. */
.v-shell--flush { padding-bottom: var(--v-section); }

/* Mono eyebrow — used for every section label on the site */
.v-eyebrow {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--v-ink-faint);
  margin: 0;
}
.v-eyebrow--signal { color: var(--v-green-deep); }
.v-eyebrow__sep { margin-inline: 0.5em; opacity: 0.55; }

/* Signal tag — green, and only ever for a verified/typed status */
.v-tag {
  display: inline-block;
  font-family: var(--v-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--v-green-deep);
  background: var(--v-green-wash);
  padding: 0.3em 0.62em;
  border-radius: 3px;
  margin: 0 0 0.85rem;
}

.v-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  line-height: 1;
  color: #FFFFFF;
  background: var(--v-blue);
  border: 1px solid var(--v-blue);
  border-radius: var(--v-radius);
  padding: 0.85em 1.5em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 130ms ease, border-color 130ms ease, color 130ms ease;
}
.v-btn:hover { background: var(--v-blue-deep); border-color: var(--v-blue-deep); color: #FFFFFF; }

.v-btn--ghost {
  background: transparent;
  color: var(--v-blue);
  border-color: var(--v-rule-strong);
}
.v-btn--ghost:hover { background: var(--v-blue-wash); border-color: var(--v-blue); color: var(--v-blue-deep); }

/* The wordmark's checkmark, reused as a glyph */
/* Brand mark — the wordmark's V with its dot. The V takes currentColor so it
   reverses out of the dark footer; the dot stays teal on both grounds. */
.v-mark { flex: none; display: block; }
.v-mark__v { fill: currentColor; }
.v-mark__dot { fill: var(--v-teal); }
.v-mark--brand { color: var(--v-navy); width: 1.1em; height: 1.16em; }
.v-mark--footer { color: #FFFFFF; width: 31px; height: 33px; margin-bottom: 0.9rem; }

.v-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--v-ink);
  color: #FFFFFF;
  font-family: var(--v-display);
  font-weight: 600;
  padding: 0.9em 1.3em;
  border-radius: 0 0 var(--v-radius) 0;
  text-decoration: none;
}
.v-skip:focus { left: 0; color: #FFFFFF; outline: 2px solid var(--v-green-brand); outline-offset: -2px; }

/* ==========================================================================
   5. HEADER + NAVIGATION
   ========================================================================== */

.v-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--v-rule);
  transition: box-shadow 160ms ease;
}
.v-header.is-stuck { box-shadow: 0 8px 24px -18px rgba(22, 32, 46, 0.45); }

.v-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--v-header-h);
}

.v-header__brand { display: flex; align-items: center; }
/* The wordmark is a wide lockup (about 7.6:1), so width is what has to be
   capped — constraining only the height would put a 320px logo in the header.
   Both caps are kept so a squarer logo dropped in later still behaves. */
.v-header__brand img,
.custom-logo-link img {
  max-height: 40px;
  max-width: 250px;
  width: auto;
  height: auto;
  object-fit: contain;
}
@media (max-width: 620px) {
  /* Leaves room for the menu button at 360px without crowding it. */
  .v-header__brand img,
  .custom-logo-link img { max-width: 180px; }
}

.v-brand-fallback {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-family: var(--v-display);
  font-size: var(--v-t-md);
  font-weight: 700;
  letter-spacing: -0.028em;
  color: var(--v-ink);
  text-decoration: none;
}

.v-nav__list {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
}

.v-nav__list a {
  display: block;
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 500;
  color: var(--v-ink-soft);
  text-decoration: none;
  padding: 0.55em 0.85em;
  border-radius: var(--v-radius);
  transition: color 120ms ease, background-color 120ms ease;
}
.v-nav__list a:hover { color: var(--v-blue); background: var(--v-blue-wash); }

/* Current page: weight and color carry it; the green rule confirms it.
   Color is never the only signal. */
.v-nav__list .current-menu-item > a,
.v-nav__list .current_page_item > a,
.v-nav__list a[aria-current="page"] {
  color: var(--v-ink);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 0 var(--v-green);
  border-radius: var(--v-radius) var(--v-radius) 0 0;
}

/* Sub-menus */
.v-nav__list .sub-menu {
  position: absolute;
  min-width: 210px;
  background: var(--v-surface);
  border: 1px solid var(--v-rule);
  border-radius: var(--v-radius);
  box-shadow: 0 14px 34px -18px rgba(22, 32, 46, 0.4);
  padding: 0.35rem;
  list-style: none;
  display: none;
  z-index: 20;
}
.v-nav__list li { position: relative; }
.v-nav__list li:hover > .sub-menu,
.v-nav__list li:focus-within > .sub-menu { display: block; }

/* Mobile toggle — hidden until the breakpoint, so no-JS desktop is unaffected */
.v-navtoggle {
  display: none;
  align-items: center;
  gap: 0.55em;
  background: transparent;
  border: 1px solid var(--v-rule-strong);
  border-radius: var(--v-radius);
  /* 0.55em put the control at about 43px tall — just under the 44px minimum
     touch target. This clears it without changing how it looks. */
  padding: 0.72em 0.95em;
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  color: var(--v-ink);
  cursor: pointer;
}
.v-navtoggle__bars { display: grid; gap: 3px; }
.v-navtoggle__bars i {
  display: block;
  width: 16px;
  height: 2px;
  background: var(--v-ink);
  border-radius: 1px;
}

@media (max-width: 899px) {
  .v-navtoggle { display: inline-flex; }

  .v-nav {
    position: fixed;
    inset: var(--v-header-h) 0 auto 0;
    background: var(--v-surface);
    border-bottom: 1px solid var(--v-rule);
    box-shadow: 0 18px 40px -24px rgba(22, 32, 46, 0.5);
    padding: 0.75rem var(--v-gutter) 1.25rem;
    display: none;
  }
  body.v-nav-open .v-nav { display: block; }

  .v-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .v-nav__list a {
    padding: 0.85em 0.25em;
    border-bottom: 1px solid var(--v-rule);
    border-radius: 0;
    font-size: var(--v-t-md);
  }
  .v-nav__list .current-menu-item > a,
  .v-nav__list a[aria-current="page"] {
    box-shadow: inset 3px 0 0 0 var(--v-green);
    padding-left: 0.85em;
  }
  .v-nav__list .sub-menu {
    position: static;
    display: block;
    border: none;
    box-shadow: none;
    padding: 0 0 0 1rem;
  }
}

/* ==========================================================================
   6. HERO

   Two columns: the lab's statement and its two actions on the left, the most
   recent news item on the right. Previously this was a single 46rem text column
   on a full-width band, so on any desktop viewport the right-hand half of the
   first screen carried nothing at all.

   The substrate grid is kept — it reads as graph paper / die layout without
   literally drawing a chip.
   ========================================================================== */

.v-hero {
  position: relative;
  padding-block: clamp(2.25rem, 4.5vw, 3.75rem);
  background-color: var(--v-surface);
  background-image:
    linear-gradient(var(--v-rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--v-rule) 1px, transparent 1px);
  background-size: 34px 34px;
  background-position: center top;
  border-bottom: 1px solid var(--v-rule);
  overflow: hidden;
}
/* Fade the grid out so it never competes with the type */
.v-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 8% 20%,
    rgba(255,255,255,0.97) 30%,
    rgba(255,255,255,0.88) 58%,
    rgba(255,255,255,0.66) 100%);
  pointer-events: none;
}

.v-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.85fr);
  gap: clamp(1.75rem, 3.5vw, 3.25rem);
  align-items: start;
}

.v-hero__body { min-width: 0; }
.v-hero__eyebrow { margin-bottom: 0.85rem; }

.v-hero__title {
  font-size: var(--v-t-hero);
  letter-spacing: -0.038em;
  line-height: 1.04;
  margin: 0 0 0.9rem;
}

.v-hero__lede {
  font-size: var(--v-t-base);
  line-height: 1.62;
  color: var(--v-ink-soft);
  max-width: 62ch;
  margin: 0;
}

.v-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin: 1.5rem 0 0;
}

/* The news card that occupies what used to be empty ground */
.v-hero__aside { min-width: 0; }

.v-feature {
  background: var(--v-surface);
  border: 1px solid var(--v-rule);
  border-top: 2px solid var(--v-blue-brand);
  border-radius: var(--v-radius);
  padding: 1.25rem 1.35rem 1.35rem;
  display: grid;
  gap: 0.4rem;
}
.v-feature__date {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--v-ink-faint);
  margin: 0.15rem 0 0;
}
.v-feature__title {
  font-size: var(--v-t-md);
  line-height: 1.3;
  letter-spacing: -0.02em;
  margin: 0;
}
.v-feature__title a { color: var(--v-ink); text-decoration: none; }
.v-feature__title a:hover { color: var(--v-blue); }
.v-feature__excerpt {
  font-size: var(--v-t-sm);
  line-height: 1.6;
  color: var(--v-ink-soft);
  margin: 0.2rem 0 0;
}
.v-feature__more { margin: 0.5rem 0 0; }
.v-feature__more a {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--v-blue);
  text-decoration: none;
}
.v-feature__more a:hover { text-decoration: underline; }

/* One column before the two would be too narrow to read comfortably */
@media (max-width: 940px) {
  .v-hero__inner { grid-template-columns: 1fr; gap: 1.75rem; }
  .v-hero__lede { max-width: none; }
}

/* ==========================================================================
   7. SECTION HEADS
   ========================================================================== */

.v-sectionhead { margin-bottom: 1.6rem; }
.v-sectionhead__title {
  font-size: var(--v-t-2xl);
  letter-spacing: -0.028em;
  margin-top: 0.7rem;
}
.v-sectionhead__lede {
  font-size: var(--v-t-md);
  color: var(--v-ink-soft);
  max-width: 62ch;
  margin-top: 1rem;
}
.v-sectionhead--split {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.v-sectionhead__action a {
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.v-sectionhead__action a:hover { text-decoration: underline; }

/* ==========================================================================
   8. CARDS
   ========================================================================== */

.v-card {
  background: var(--v-surface);
  border: 1px solid var(--v-rule);
  border-top: 2px solid var(--v-blue-brand);
  border-radius: var(--v-radius);
  padding: 1.25rem 1.3rem 1.4rem;
  transition: border-color 140ms ease, transform 140ms ease;
}
.v-card:hover { border-color: var(--v-rule-strong); border-top-color: var(--v-blue-brand); }

.v-card__title { font-size: var(--v-t-lg); margin-bottom: 0.6rem; }
.v-card__body { font-size: var(--v-t-sm); line-height: 1.62; color: var(--v-ink-soft); }

/* ==========================================================================
   9. NEWS
   ========================================================================== */

.v-news {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding-top: 1.15rem;
  border-top: 2px solid var(--v-ink);
}
.v-news__date {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--v-ink-faint);
}
.v-news__title { font-size: var(--v-t-md); line-height: 1.3; }
.v-news__title a { color: var(--v-ink); text-decoration: none; }
.v-news__title a:hover { color: var(--v-blue); }
.v-news__excerpt { font-size: var(--v-t-sm); line-height: 1.6; color: var(--v-ink-soft); }
.v-news__more { margin-top: auto; padding-top: 0.4rem; }
.v-news__more a {
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  text-decoration: none;
}
.v-news__more a:hover { text-decoration: underline; }

/* ==========================================================================
   10. PUBLICATIONS
   ========================================================================== */

.v-publist { list-style: none; }

.v-pub {
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: 1.5rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--v-rule);
}
.v-pub:last-child { border-bottom: none; }

.v-pub__year {
  font-family: var(--v-mono);
  font-size: var(--v-t-sm);
  font-weight: 500;
  color: var(--v-green-deep);
  font-variant-numeric: tabular-nums;
  padding-top: 0.15rem;
}

.v-pub__title {
  font-size: var(--v-t-md);
  line-height: 1.32;
  letter-spacing: -0.016em;
  margin-bottom: 0.4rem;
  max-width: 72ch;
}
.v-pub__authors {
  font-size: var(--v-t-sm);
  color: var(--v-ink-soft);
  max-width: 72ch;
}
.v-pub__venue {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.02em;
  color: var(--v-ink-faint);
  margin-top: 0.25rem;
  max-width: 72ch;
}
.v-pub__link { margin-top: 0.7rem; }
.v-pub__link a {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  font-weight: 500;
  color: var(--v-green-deep);
  background: var(--v-green-wash);
  border: 1px solid transparent;
  border-radius: 3px;
  padding: 0.4em 0.7em;
  text-decoration: none;
  transition: border-color 120ms ease;
}
.v-pub__link a:hover { border-color: var(--v-green); }

/* Full publications page: year becomes a sticky rail label */
.v-pubyears { padding-block: 0 var(--v-section); }

.v-pubyear {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 1.5rem;
  padding-block: 1.35rem;
  border-top: 1px solid var(--v-rule);
}
.v-pubyear:first-child { border-top: none; padding-top: 0; }

.v-pubyear__label {
  font-family: var(--v-mono);
  font-size: var(--v-t-md);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--v-ink);
  font-variant-numeric: tabular-nums;
  position: sticky;
  top: calc(var(--v-header-h) + 1.5rem);
  align-self: start;
  padding-top: 0.3rem;
  border-top: 2px solid var(--v-green);
}

/* The citation carries the reading weight; the venue and the link to the paper
   are reference data. Setting them beside the title rather than under it uses
   the width the list already occupies and takes about a third off the height of
   the page, which matters on a list this long. */
.v-pub--full {
  grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr);
  gap: 0.35rem 2rem;
  padding-block: 0.95rem;
  align-items: start;
}
.v-pub--full:first-child { padding-top: 0; }
.v-pub__main { min-width: 0; }
.v-pub__aside { min-width: 0; }
.v-pub--full .v-pub__title { margin-bottom: 0.25rem; max-width: none; }
.v-pub--full .v-pub__authors { max-width: none; }
.v-pub--full .v-pub__venue { margin-top: 0.2rem; max-width: none; }
.v-pub--full .v-pub__link { margin-top: 0.5rem; }

@media (max-width: 820px) {
  .v-pub--full { grid-template-columns: 1fr; gap: 0.2rem; }
  .v-pub--full .v-pub__link { margin-top: 0.6rem; }
}

/* ==========================================================================
   11. OPEN POSITIONS

   Titles only — the lab has not supplied descriptions, and none are invented
   to fill the space. The rule under each title leaves room for one.
   ========================================================================== */

.v-positions {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--v-rule);
}

.v-positions__item {
  padding: 1.5rem 1.5rem 1.5rem 0;
  border-bottom: 1px solid var(--v-rule);
}

.v-positions__title {
  font-size: var(--v-t-md);
  letter-spacing: -0.018em;
  padding-left: 1rem;
  border-left: 2px solid var(--v-green);
}

.v-positions__body {
  font-size: var(--v-t-sm);
  line-height: 1.62;
  color: var(--v-ink-soft);
  margin-top: 0.6rem;
  padding-left: 1rem;
  max-width: 52ch;
}

.v-positions__cta { margin-top: 1.75rem; }
.v-positions__cta a {
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  text-decoration: none;
}
.v-positions__cta a:hover { text-decoration: underline; }

/* ==========================================================================
   12. PAGE HEADER
   ========================================================================== */

.v-pagehead {
  padding-block: clamp(1.5rem, 3vw, 2.35rem) clamp(1.35rem, 2.5vw, 2rem);
  border-bottom: 1px solid var(--v-rule);
  margin-bottom: clamp(1.75rem, 3vw, 2.75rem);
  background: var(--v-sunken);
}
/* The title and the introduction sit side by side, so the band is one line of
   content deep instead of four, and its right half is not empty. Flex rather
   than grid: with no introduction the title simply takes the whole row, where a
   two-column grid would leave the second column standing empty. */
.v-pagehead__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.9rem clamp(1.5rem, 4vw, 3rem);
}
.v-pagehead__lead { flex: 1 1 18rem; min-width: 0; }

.v-pagehead__title {
  font-size: var(--v-t-2xl);
  letter-spacing: -0.032em;
  margin-top: 0.45rem;
  max-width: 22ch;
}

/* Breadcrumbs. Markup only — Yoast publishes the BreadcrumbList to the schema
   graph, so this is a navigation aid rather than a second set of structured
   data competing with the first. */
.v-crumbs__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.5rem;
  margin: 0;
  padding: 0;
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--v-ink-faint);
}
.v-crumbs__item + .v-crumbs__item::before {
  content: "/";
  margin-right: 0.5rem;
  color: var(--v-rule-strong);
}
.v-crumbs a { color: var(--v-ink-faint); text-decoration: none; }
.v-crumbs a:hover { color: var(--v-blue); text-decoration: underline; }
.v-crumbs [aria-current="page"] { color: var(--v-ink-soft); }
.v-pagehead__title--single { max-width: 26ch; font-size: var(--v-t-2xl); }
.v-pagehead__lede {
  flex: 1 1 26rem;
  min-width: 0;
  font-size: var(--v-t-sm);
  line-height: 1.6;
  color: var(--v-ink-soft);
  max-width: 66ch;
  margin: 0;
}
.v-pagehead--single { background: var(--v-surface); }

/* ==========================================================================
   13. PROSE — block content on Faculty, Students, Funding, Contact
   ========================================================================== */

.v-prose { padding-bottom: var(--v-section); }
.v-prose > *:first-child { margin-top: 0; }
.v-prose--narrow { max-width: 70ch; }

.v-prose > * + * { margin-top: 1.15rem; }

/* WordPress's constrained layout centres children with auto margins. Combined
   with a max-width that pushes body copy into the middle of the page instead
   of aligning it to the same left edge as everything else. The blocks nest a
   further inner-container, so this matches by element rather than by child. */
.v-prose p,
.v-prose h1, .v-prose h2, .v-prose h3, .v-prose h4, .v-prose h5, .v-prose h6,
.v-prose ul, .v-prose ol, .v-prose figure,
.v-prose .wp-block-group,
.v-prose .wp-block-group__inner-container {
  margin-left: 0;
  margin-right: 0;
}

.v-prose p { max-width: 68ch; }

.v-prose h2 {
  font-size: var(--v-t-2xl);
  letter-spacing: -0.026em;
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 2px solid var(--v-ink);
}
.v-prose h3 { font-size: var(--v-t-lg); margin-top: 2.75rem; }
.v-prose h3 + .v-people, .v-prose h4 + .v-people { margin-top: 1.5rem; }
.v-prose h4 { font-size: var(--v-t-md); margin-top: 2.75rem; }
.v-prose h4 { font-size: var(--v-t-md); margin-top: 1.75rem; }

/* h5 was used as a section label in the legacy content — keep it reading as one */
.v-prose h5 {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--v-ink-faint);
  margin-top: 2.5rem;
}

.v-prose a { font-weight: 600; }

.v-prose ul, .v-prose ol { padding-left: 1.25rem; }
.v-prose .v-people { padding-left: 0; margin-left: 0; }
.v-prose .v-person { margin: 0; }
.v-prose li { margin-bottom: 0.4rem; }

/* Legacy group wrappers carry no chrome of their own any more (inc-blocks.php),
   so they simply stack. Only the gap between them is set here. */
.v-prose .wp-block-group + .wp-block-group { margin-top: 1.15rem; }

.v-prose .wp-block-columns { gap: 1.5rem; display: flex; flex-wrap: wrap; }
.v-prose .wp-block-column { flex: 1 1 280px; min-width: 0; }

/* People: portraits get one consistent crop, initials stand in when absent */
.v-prose .wp-block-column figure img,
.v-prose .wp-block-image img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center top;
  border-radius: var(--v-radius);
  background: var(--v-sunken);
}

/* A person's name, then their role as mono metadata */
.v-prose .wp-block-column h3,
.v-prose .wp-block-column h4 {
  font-size: var(--v-t-md);
  margin-top: 1rem;
  margin-bottom: 0.15rem;
  letter-spacing: -0.018em;
}
.v-prose .wp-block-column h3 + p,
.v-prose .wp-block-column h4 + p {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--v-green-deep);
  line-height: 1.5;
  margin-top: 0.35rem;
}
.v-prose .wp-block-column p {
  font-size: var(--v-t-sm);
  line-height: 1.62;
  color: var(--v-ink-soft);
  max-width: 62ch;
}

.v-prose figure { margin: 0; }

/* ==========================================================================
   14. FORMS
   ========================================================================== */

.v-searchform { max-width: 34rem; }
.v-searchform__row { display: flex; gap: 0.6rem; margin-top: 0.6rem; }
.v-searchform__input { flex: 1 1 auto; }

input[type="text"], input[type="email"], input[type="search"],
input[type="url"], input[type="tel"], textarea, select,
div.wpforms-container input[type="text"],
div.wpforms-container input[type="email"],
div.wpforms-container textarea {
  font-family: var(--v-body) !important;
  font-size: var(--v-t-base) !important;
  color: var(--v-ink) !important;
  background: var(--v-surface) !important;
  border: 1px solid var(--v-rule-strong) !important;
  border-radius: var(--v-radius) !important;
  padding: 0.7em 0.85em !important;
  width: 100%;
  max-width: 34rem;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
input:focus, textarea:focus, select:focus,
div.wpforms-container input:focus,
div.wpforms-container textarea:focus {
  border-color: var(--v-blue) !important;
  box-shadow: 0 0 0 3px var(--v-blue-wash) !important;
  outline: none !important;
}

.wpforms-field-label {
  font-family: var(--v-display) !important;
  font-size: var(--v-t-sm) !important;
  font-weight: 600 !important;
  color: var(--v-ink) !important;
  margin-bottom: 0.4rem !important;
}
.wpforms-required-label { color: var(--v-green-deep) !important; }
div.wpforms-container .wpforms-error { color: #B3261E !important; font-size: var(--v-t-sm) !important; }

div.wpforms-container button[type="submit"],
.wpforms-submit,
button[type="submit"],
input[type="submit"] {
  font-family: var(--v-display) !important;
  font-size: var(--v-t-sm) !important;
  font-weight: 600 !important;
  color: #FFFFFF !important;
  background: var(--v-blue) !important;
  border: 1px solid var(--v-blue) !important;
  border-radius: var(--v-radius) !important;
  padding: 0.85em 1.5em !important;
  cursor: pointer;
  width: auto !important;
}
div.wpforms-container button[type="submit"]:hover,
.wpforms-submit:hover,
button[type="submit"]:hover,
input[type="submit"]:hover { background: var(--v-blue-deep) !important; border-color: var(--v-blue-deep) !important; }

/* ==========================================================================
   15. POST NAV + PAGINATION
   ========================================================================== */

.v-postnav {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--v-rule);
  padding-top: 1.75rem;
  margin-bottom: var(--v-section);
}
.v-postnav__link {
  display: grid;
  gap: 0.35rem;
  max-width: 32ch;
  text-decoration: none;
}
.v-postnav__link--next { text-align: right; margin-left: auto; }
.v-postnav__title {
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  color: var(--v-ink);
  line-height: 1.35;
}
.v-postnav__link:hover .v-postnav__title { color: var(--v-blue); }

.v-pagination, .pagination {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  padding-block: 2.5rem var(--v-section);
}
.v-pagination .page-numbers, .pagination .page-numbers {
  font-family: var(--v-mono);
  font-size: var(--v-t-sm);
  color: var(--v-ink-soft);
  border: 1px solid var(--v-rule);
  border-radius: var(--v-radius);
  padding: 0.45em 0.8em;
  text-decoration: none;
}
.v-pagination .page-numbers.current, .pagination .page-numbers.current {
  background: var(--v-blue);
  border-color: var(--v-blue);
  color: #FFFFFF;
}

/* ==========================================================================
   16. FOOTER
   ========================================================================== */

.v-footer {
  background: var(--v-ink);
  color: #C6CFDB;
  padding-block: clamp(3rem, 6vw, 4.5rem) 0;
}

.v-footer {
  padding-block: clamp(2.25rem, 4vw, 3.25rem) 0;
}
.v-footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
  gap: 2rem;
  padding-bottom: 2.25rem;
}

.v-footer__name {
  font-family: var(--v-display);
  font-size: var(--v-t-lg);
  font-weight: 700;
  letter-spacing: -0.028em;
  color: #FFFFFF;
  margin-bottom: 0.6rem;
}
.v-footer__blurb {
  font-size: var(--v-t-sm);
  line-height: 1.62;
  color: #9AA7B7;
  max-width: 46ch;
}

.v-footer .v-eyebrow { color: #7E8C9E; margin-bottom: 0.9rem; }

.v-footer__list { list-style: none; display: grid; gap: 0.5rem; }
.v-footer__list li { font-size: var(--v-t-sm); color: #9AA7B7; line-height: 1.5; }
.v-footer__list a { color: #C6CFDB; text-decoration: none; font-size: var(--v-t-sm); }
.v-footer__list a:hover { color: #FFFFFF; text-decoration: underline; }

.v-footer__cta { margin-top: 1.1rem; }
.v-footer__cta a {
  font-family: var(--v-display);
  font-size: var(--v-t-sm);
  font-weight: 600;
  color: #FFFFFF;
  text-decoration: none;
  border-bottom: 2px solid var(--v-green-brand);
  padding-bottom: 2px;
}
.v-footer__cta a:hover { color: var(--v-green-brand); }

.v-footer__bottom {
  border-top: 1px solid #2A3646;
  padding-block: 1.5rem 2rem;
}
.v-footer__bottom p {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.02em;
  color: #7E8C9E;
}

/* ==========================================================================
   17. ACCESSIBILITY
   ========================================================================== */

:focus-visible {
  outline: 2px solid var(--v-blue);
  outline-offset: 2px;
  border-radius: 2px;
}
.v-footer :focus-visible { outline-color: var(--v-green-brand); }

.screen-reader-text {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media (prefers-contrast: more) {
  :root { --v-ink-soft: #3B4757; --v-ink-faint: #5B6879; --v-rule: #B9C4D2; }
}

/* ==========================================================================
   18. RESPONSIVE
   ========================================================================== */

@media (max-width: 900px) {
  .v-grid--3, .v-positions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .v-footer__top { grid-template-columns: 1fr 1fr; }
  .v-footer__brand { grid-column: 1 / -1; }
  .v-pubyear { grid-template-columns: 1fr; gap: 1rem; padding-block: 1.75rem; }
  .v-pubyear__label { position: static; border-top: none; padding-top: 0; }
}

@media (max-width: 600px) {
  :root { --v-header-h: 64px; }
  .v-grid--2, .v-grid--3, .v-positions { grid-template-columns: 1fr; }
  .v-footer__top { grid-template-columns: 1fr; gap: 2rem; }
  .v-pub { grid-template-columns: 1fr; gap: 0.35rem; }
  .v-pub__year { padding-top: 0; }
  .v-prose .wp-block-columns { gap: 1.75rem; }
  .v-prose .wp-block-column figure img { aspect-ratio: 3 / 2; }
  .v-searchform__row { flex-direction: column; }
}

/* Wide content never pushes the page sideways */
html, body { overflow-x: clip; }

.v-prose table, .v-prose pre, .wp-block-table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
}

@media print {
  .v-header, .v-footer, .v-navtoggle, .v-skip, .v-hero__actions { display: none !important; }
  body { color: #000; font-size: 11pt; }
  a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
}

/* ==========================================================================
   19. PEOPLE — Faculty and Students

   These render from the veritas_person post type (see inc-people.php), so the
   markup is written by the theme and known exactly. The previous rules had to
   style whatever the block editor happened to emit, which is why portraits
   arrived at four different aspect ratios and names sat on ragged baselines.

   Every portrait is now cropped to a square by the same rule, so a row of
   people reads as a row rather than as a set of unrelated images.
   ========================================================================== */

.v-peoplegroup + .v-peoplegroup { margin-top: clamp(2rem, 3.5vw, 3rem); }

.v-peoplegroup__title {
  font-size: var(--v-t-xl);
  letter-spacing: -0.025em;
  margin: 0 0 1.35rem;
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--v-rule);
}

/* -- Students: a dense card grid --------------------------------------- */

.v-people {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(10.5rem, 100%), 1fr));
  gap: 1.6rem 1.4rem;
  align-items: start;
}

.v-person { display: grid; gap: 0.75rem; min-width: 0; }

.v-person__media,
.v-person__media--empty {
  aspect-ratio: 1 / 1;
  border-radius: var(--v-radius);
  overflow: hidden;
  background: var(--v-sunken);
  /* A real border, not an inset shadow: the shadow paints on the container,
     underneath the image that covers it, so portraits shot against a white
     backdrop dissolved into the page with no edge at all. */
  border: 1px solid var(--v-rule);
}
.v-person__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Portraits are framed head-and-shoulders; biasing above centre keeps the
     face in the crop instead of the chest. */
  object-position: center 22%;
  display: block;
}
.v-person__media--empty { display: grid; place-items: center; }
.v-person__initials {
  font-family: var(--v-display);
  font-size: clamp(1.35rem, 3.5vw, 1.85rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--v-rule-strong);
}

.v-person__body { min-width: 0; }
.v-person__name {
  font-size: var(--v-t-base);
  letter-spacing: -0.018em;
  line-height: 1.25;
  margin: 0;
}
.v-person__meta {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--v-green-deep);
  line-height: 1.55;
  margin: 0.3rem 0 0;
}

/* -- Faculty: portrait beside a biography ------------------------------ */

.v-profiles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* auto-FILL, not auto-fit. With auto-fit a group holding a single person
     collapses to one full-width track, and the biography then runs about 130
     characters to the line — roughly twice a readable measure. auto-fill keeps
     the empty track, so a lone card stays the same width as the cards above it.
     The students grid already works this way. */
  grid-template-columns: repeat(auto-fill, minmax(min(25rem, 100%), 1fr));
  gap: 1.35rem;
}

.v-profile {
  display: grid;
  grid-template-columns: 124px minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
  background: var(--v-surface);
  border: 1px solid var(--v-rule);
  border-top: 2px solid var(--v-blue-brand);
  border-radius: var(--v-radius);
  padding: 1.3rem 1.4rem 1.4rem;
  min-width: 0;
}

.v-profile__media {
  aspect-ratio: 1 / 1;
  border-radius: var(--v-radius);
  overflow: hidden;
  background: var(--v-sunken);
  border: 1px solid var(--v-rule);
  display: grid;
  place-items: center;
}
.v-profile__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 18%;
  display: block;
}
.v-profile__initials {
  font-family: var(--v-display);
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--v-rule-strong);
}

.v-profile__body { min-width: 0; }
.v-profile__name {
  font-size: var(--v-t-md);
  letter-spacing: -0.022em;
  line-height: 1.25;
  margin: 0;
}
.v-profile__meta {
  font-family: var(--v-mono);
  font-size: var(--v-t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--v-green-deep);
  line-height: 1.55;
  margin: 0.35rem 0 0;
}
.v-profile__bio {
  font-size: var(--v-t-sm);
  line-height: 1.66;
  color: var(--v-ink-soft);
  margin: 0.75rem 0 0;
}
.v-profile__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin: 0.8rem 0 0;
  font-size: var(--v-t-sm);
}
.v-profile__links a { font-weight: 600; }

@media (max-width: 620px) {
  /* Side-by-side would leave the biography about 34 characters wide here,
     which is unreadable for paragraphs this long. */
  .v-profile { grid-template-columns: 1fr; gap: 0.9rem; }
  .v-profile__media { width: 108px; }
  .v-people { grid-template-columns: repeat(auto-fill, minmax(min(8.5rem, 100%), 1fr)); gap: 1.35rem 1rem; }
}
