  /* ============================================================
     BAHUJAN POLITICAL PALETTE
     ------------------------------------------------------------
     --accent             Ambedkarite cobalt-navy — for tab indicator,
                          link bottom-rules, card hover borders, and
                          other secondary chrome. Deeper than the
                          masthead/CTA blue.
     --ambedkar-blue      Brighter Ambedkar blue — for the masthead
                          title and the Apply CTA. Single source of
                          truth for the primary editorial blue:
                          #0047AB light / #5b8ad6 dark.
     --alarm              Dalit Panther / Maoist vermillion — for the
                          masthead strapline, the "Article 16" pill,
                          critical-deadline numbers, and protest
                          signaling. NOT used as a top/bottom strip
                          on the masthead or footer (those alarm
                          strips were dropped — they read as
                          decoration without political weight).
     --ink                Near-black, broadsheet print register.
     --bg                 Clean off-white (light) / charcoal (dark).
                          Tinted color-mix(--alarm × --bg) is
                          deliberately avoided — it drifts into beige
                          in light mode against the off-white.

     ============================================================
     PAGE LAYOUT RULES
     ------------------------------------------------------------
     • #listings-tab and #vacancies-tab cap at 880px and centre via
       margin: 0 auto. Other tabs (#map-tab, #resources-tab) keep
       main's full 1080px so card grids stay wide.
     • Section headings on The Gap tab (H2 / Point N / The cost /
       appendix / bibliography / verdict) all carry an id and a
       hover-visible "#" anchor link (.heading-anchor). Deep-link
       URLs like /#point-3 route via the click handler in app.js
       (data-tab-link + data-scroll-target), and any closed
       <details> ancestor on the way to the target is auto-opened.
     • <details> blocks at the end of The Gap tab (appendix and
       bibliography) share a single summary treatment — same font,
       size, weight, padding, and ▸/▾ disclosure arrow.
     • Job cards have no decorative left tier-bar and no
       scope-private hover override; the urgency hierarchy lives in
       the deadline column's tier-critical / tier-soon / tier-ok
       coloring (alarm / alarm / muted).
     • Masthead is centered, compact (~80 px), title in
       --ambedkar-blue, strapline italic vermillion. No top
       alarm strip; footer carries only a thin neutral border.
     ============================================================ */
  :root {
    /* Palette redesign: moved off the generic civic-tech (cobalt + alarm
       red on white) palette into a warmer, broadsheet-publication
       register. Ivory background instead of pure-white, oxblood instead
       of generic alarm red (more specifically the Dalit Panther
       saturated red the page already cites in comments), warmer-ink
       text instead of cool charcoal. The cobalt stays — it's the
       Ambedkarite anti-caste color of the project — but goes deeper
       and less bureaucratic-bright. */
    --bg: #fbfaf7;             /* austere off-white, not khaki */
    --panel: #ffffff;          /* record surfaces */
    --ink: #171512;            /* near-black, print register */
    --muted: #5f5f5a;          /* neutral secondary text */
    --muted-soft: #888883;     /* neutral non-urgent signal */
    --accent: #123f73;         /* Ambedkar cobalt/navy for actions */
    --accent-deep: #0b2d55;    /* hover / pressed */
    --ambedkar-blue: #0047AB;        /* Ambedkar blue — masthead title + Apply CTA */
    --ambedkar-blue-deep: #003380;   /* Ambedkar blue hover/pressed */
    --warn: #8a5a18;           /* amber for disclosure absence */
    --alarm: #7a1620;          /* oxblood — Dalit Panther saturated red */
    --good: #1b5e20;
    --border: #d8d6cf;         /* neutral rule */
    --chip-bg: #efeee9;        /* quiet neutral chip background */
    --serif: "Newsreader", "Source Serif 4", Georgia, serif;
    --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
    color-scheme: light;
  }
  html[data-theme="dark"] {
    --bg: #101113;             /* charcoal paper */
    --panel: #17191c;          /* record surfaces */
    --ink: #ede9df;            /* soft paper text */
    --muted: #aaa69d;
    --muted-soft: #6f716f;
    --accent: #7ea7df;         /* luminous cobalt */
    --accent-deep: #a4c3ee;
    --ambedkar-blue: #5b8ad6;        /* Ambedkar blue, lifted for dark-mode contrast */
    --ambedkar-blue-deep: #82a6e0;   /* Ambedkar blue hover/pressed in dark mode */
    --warn: #d0a05e;           /* amber */
    --alarm: #e05b63;          /* oxblood in dark mode */
    --good: #63ad78;
    --border: #30343a;
    --chip-bg: #22262b;
    color-scheme: dark;
  }
  /* Adjust signal-color tints for dark backgrounds */
  html[data-theme="dark"] .listing.tier-critical .deadline-pill { background: rgba(236,106,106,0.12); color: #f08585; }
  html[data-theme="dark"] .listing.tier-soon     .deadline-pill { background: rgba(224,160,96,0.12); color: #e8b478; }
  html[data-theme="dark"] .listing.tier-ok       .deadline-pill { background: rgba(111,207,138,0.12); color: #88dd9d; }
  /* Add a soft border in dark mode — at 0.15 alpha the chip otherwise reads
     as flat against the panel on lower-contrast displays (WCAG 1.4.11 NTC). */
  html[data-theme="dark"] .listing .inst-line .hss-flag { background: rgba(224,160,96,0.15); color: #e8b478; border: 1px solid rgba(224,160,96,0.4); }
  html[data-theme="dark"] .banner { background: #2a2820; border-color: #3d3a25; color: #d6c79b; }
  html[data-theme="dark"] .banner button { color: #d6c79b; }
  * { box-sizing: border-box; }
  html, body { margin: 0; font: 15px/1.55 "Inter", system-ui, -apple-system, sans-serif; color: var(--ink); background: var(--bg); }
  a { color: var(--accent); }

  /* Custom focus ring (WCAG 2.4.7). Browser default is 1px and easy to miss. */
  /* WCAG 2.4.7: every focusable element gets a visible indicator. We rely on
     :focus-visible (keyboard-only) instead of :focus (also fires on mouse
     click); the previous global `*:focus { outline: none }` was suppressing
     the fallback for browsers without :focus-visible support. Removed. */
  *:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
  /* Form controls already have border-radius; keep the offset. */
  input:focus-visible, select:focus-visible, textarea:focus-visible { outline-offset: 1px; }

  /* Skip-to-content link (WCAG 2.4.1). Hidden until focused. */
  .skip-link { position: absolute; left: -9999px; top: 0; background: var(--accent); color: var(--panel); padding: 10px 14px; font-weight: 600; text-decoration: none; border-radius: 0 0 6px 0; z-index: 1000; }
  .skip-link:focus { left: 0; }

  /* Visually-hidden, screen-reader-accessible (WCAG 1.3.1). Used for section
     H2s that name each tab panel without visually duplicating the tab label. */
  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

  /* Smooth theme transitions (WCAG 3.2.1 — predictable on focus / no jarring flash). */
  body, aside, header.masthead, nav.tabs, .listing, .banner, footer { transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease; }

  /* Center-aligned masthead (Phase-2). Title sits on its own line, subtitle
     beneath it, then the lede paragraph — all max-width 720 px and centred.
     Portrait moved to a small centred figure below the lede so the page
     still has a face but doesn't compete with the headline. */
  /* The 6px red strip is the Bahujan radical-tradition signature
     (Dalit Panthers / protest red). Politically explicit, not subtle. */
  /* Masthead — broadsheet wordmark register. Was: 38px h1 + small italic
     subtitle on white, no anchoring. Now: an issue/date eyebrow, a
     larger Newsreader wordmark, a serif italic standfirst, with
     vertical rules above and below to feel like a publication
     nameplate. The 6px Dalit Panther red strip stays. */
  header.masthead {
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    padding: 28px 32px 32px;
    text-align: center;
  }
  header.masthead .text-wrap { max-width: 820px; margin: 0 auto; }
  header.masthead .nameplate-eyebrow {
    font-family: var(--sans);
    font-size: 11px; font-weight: 600; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--muted);
    margin: 0 0 18px;
    display: inline-flex; align-items: center; gap: 12px;
  }
  header.masthead .nameplate-eyebrow::before,
  header.masthead .nameplate-eyebrow::after {
    content: ""; width: 32px; height: 1px; background: var(--border);
  }
  header.masthead h1 {
    margin: 0;
    font-family: var(--serif); font-size: 56px; font-weight: 700;
    color: var(--accent); letter-spacing: -0.025em; line-height: 1;
    font-feature-settings: "ss01" 1;  /* Newsreader stylistic alt */
  }
  header.masthead .subtitle {
    display: block; max-width: 580px; margin: 16px auto 0;
    font-family: var(--serif); font-style: italic;
    color: var(--ink); font-size: 16px; line-height: 1.55; font-weight: 400;
  }
  @media (max-width: 720px) {
    header.masthead h1 { font-size: 36px; }
    header.masthead .subtitle { font-size: 14px; }
    header.masthead .nameplate-eyebrow { font-size: 10px; letter-spacing: 0.14em; }
  }

  /* Compact masthead variant — title + strapline laid out inline so the
     header eats ~80 px of vertical space instead of ~165 px, leaving the
     fold for the actual feed. The strapline still uses the serif italic
     register; just smaller and beside the title rather than below it. */
  header.masthead.masthead-compact {
    padding: 22px 32px 24px;
    text-align: center;
  }
  header.masthead.masthead-compact h1 {
    font-size: 40px;
    font-weight: 700;
    /* Ambedkar blue token — same colour the Apply CTA fills with, in
       both modes. Light: #0047AB. Dark: #5b8ad6 (lifted for text
       contrast against charcoal — Apply button shifts up too so they
       still match exactly). */
    color: var(--ambedkar-blue);
    letter-spacing: -0.024em;
    line-height: 1.2;
    display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 22px;
    max-width: 1180px; margin: 0 auto;
  }
  header.masthead.masthead-compact .masthead-title {
    font-family: var(--serif);
    /* Inherits color: var(--ambedkar-blue) from the parent h1 — same
       blue the Apply CTA fills with, so the masthead title sits in the
       same family as the site's primary action. Strapline below stays
       vermillion. */
  }
  header.masthead.masthead-compact .masthead-strapline {
    font-family: var(--serif);
    font-style: italic;
    font-size: 18px;
    font-weight: 400;
    color: var(--alarm);                /* Dalit Panther vermillion */
    line-height: 1.4;
  }
  /* No column-mode breakpoint here — the h1 keeps `flex-wrap: wrap` on,
     so as long as title + strapline can fit on one line they will. When
     they can't (very narrow viewports), flex naturally wraps the
     strapline onto a second row, both still centered via the parent's
     justify-content: center. The earlier @media (max-width: 720px)
     forced flex-direction: column even at widths where the items would
     have fit inline — that was the artificial constraint. */
  @media (max-width: 540px) {
    header.masthead.masthead-compact h1 {
      font-size: 30px; gap: 6px;
    }
    header.masthead.masthead-compact .masthead-strapline { font-size: 15px; }
  }

  /* (Vacancies-tab strip removed; compact vacancy-gap line is now
     defined alongside .vacancy-gap-banner-compact further below.) */
  /* "Public-interest service" tag in the footer disclaimer. Cobalt
     to align with the political register; everything else in the
     footer keeps its muted-gray paragraph style. */
  /* The "Public-interest service" tag uses Dalit Panther red — the
     framing is an editorial claim, not a constitutional reference, so
     it earns the protest register rather than cobalt. */
  /* Compact colophon — appears at the foot of every tab. The full project
     description and disclaimer paragraphs live on the About page (#about);
     this footer carries only:
       - the verdict pull-quote (editorial signature, weighted)
       - a one-line research-and-reference caveat with a link to About
       - a metadata strip (last-updated, licence, repo)
     The previous expanded footer drowned every page in 5 disclaimer
     paragraphs; readers either skipped or felt sermonised. The compact
     version reads cleanly and routes detail-seekers to a destination
     designed to receive them. */
  footer.colophon {
    background: var(--bg);
    border-top: 1px solid var(--border);
    margin-top: 64px;
    padding: 36px 32px 40px;
    color: var(--ink);
    text-align: center;
  }
  /* Single line on desktop. The verdict is the editorial signature; a
     two-line wrap (which 56ch was forcing) breaks its rhythm. We let the
     line run to the width of the colophon's centred container; on viewports
     too narrow to fit it, font-size drops at the @media break below and
     `text-wrap: balance` distributes the wrap evenly across the two
     clauses (the natural break is at the period mid-sentence). */
  footer.colophon .colophon-verdict {
    font-family: var(--serif); font-size: 19px; font-style: italic;
    color: var(--ink); margin: 0 auto 24px; line-height: 1.45;
    letter-spacing: -0.005em;
    text-wrap: balance;
    white-space: nowrap;
  }
  footer.colophon .colophon-caveat {
    font-family: var(--sans); font-size: 13px; color: var(--muted);
    margin: 0 auto 18px; line-height: 1.55;
    /* No max-width: lets the line span the full footer width and stay
       on one line at desktop widths. On narrower viewports it wraps
       naturally. */
  }
  footer.colophon .colophon-caveat .colophon-about-link {
    color: var(--accent); text-decoration: none; font-weight: 600;
    border-bottom: 1px solid var(--accent); margin-left: 6px; white-space: nowrap;
  }
  footer.colophon .colophon-caveat .colophon-about-link:hover {
    background: var(--accent); color: var(--bg);
  }
  footer.colophon .colophon-meta-line {
    font-family: var(--sans); font-size: 11.5px; color: var(--muted);
    margin: 0 auto; letter-spacing: 0.02em; line-height: 1.7;
    /* No max-width: lets the meta line span the full footer width and
       stay on one line at desktop widths. */
  }
  footer.colophon .colophon-meta-line a {
    color: var(--muted); text-decoration: none; border-bottom: 1px solid var(--border);
  }
  footer.colophon .colophon-meta-line a:hover { color: var(--accent); border-bottom-color: var(--accent); }
  .github-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    vertical-align: -0.12em;
  }
  .github-link .github-icon {
    width: 1em;
    height: 1em;
    flex: 0 0 auto;
    fill: currentColor;
  }
  @media (max-width: 720px) {
    footer.colophon { padding: 28px 16px 32px; }
    /* Mobile: drop the nowrap so the line wraps naturally rather than
       overflowing the viewport. text-wrap: balance keeps the wrap even. */
    footer.colophon .colophon-verdict { font-size: 16px; white-space: normal; }
  }

  /* About page — destination, not a tool. Substantive long-form on the
     project's purpose, methodology, disclaimers, and citation. Linked to
     from the colophon's "About & methodology →". Editorial register: the
     same Newsreader / oxblood / deep-navy voice the rest of the site uses,
     but at reading-essay scale rather than dashboard density. */
  #about-tab.about-page {
    max-width: 720px;
    margin: 32px auto 80px;
    padding: 0 24px;
    font-family: var(--serif);
    color: var(--ink);
    line-height: 1.6;
  }
  #about-tab.about-page .about-h2 {
    font-family: var(--serif); font-size: 38px; font-weight: 700;
    color: var(--ink); margin: 0 0 24px; letter-spacing: -0.015em;
  }
  #about-tab.about-page .about-h3 {
    font-family: var(--serif); font-size: 19px; font-weight: 700;
    color: var(--alarm); margin: 36px 0 8px; letter-spacing: -0.005em;
  }
  #about-tab.about-page p {
    font-family: var(--serif); font-size: 16px; line-height: 1.65;
    color: var(--ink); margin: 0 0 14px;
  }
  #about-tab.about-page p.about-lede {
    font-size: 18.5px; line-height: 1.55; margin-bottom: 28px;
    border-left: 3px solid var(--accent); padding-left: 16px;
    font-weight: 500;
  }
  #about-tab.about-page code {
    font-family: var(--mono); font-size: 13.5px; background: var(--chip-bg);
    padding: 2px 6px; border-radius: 4px; color: var(--ink);
  }
  #about-tab.about-page a {
    color: var(--accent); text-decoration: none;
    border-bottom: 1px solid var(--accent);
  }
  #about-tab.about-page a.github-link {
    font-family: var(--sans);
    font-size: 14px;
    font-weight: 700;
  }
  #about-tab.about-page a:hover { background: var(--accent); color: var(--bg); }
  #about-tab.about-page p.about-verdict {
    font-family: var(--serif); font-size: 22px; font-style: italic;
    font-weight: 500; color: var(--ink); margin: 56px 0 0;
    padding-top: 28px; border-top: 2px solid var(--alarm);
    text-align: center; letter-spacing: -0.005em; line-height: 1.45;
  }
  @media (max-width: 720px) {
    #about-tab.about-page { padding: 0 16px; margin: 16px auto 48px; }
    #about-tab.about-page .about-h2 { font-size: 30px; }
    #about-tab.about-page .about-h3 { font-size: 17px; }
    #about-tab.about-page p { font-size: 15.5px; }
    #about-tab.about-page p.about-lede { font-size: 17px; }
    #about-tab.about-page p.about-verdict { font-size: 19px; }
  }
  header.masthead p { margin: 10px auto 0; color: var(--muted); font-size: 13px; max-width: 720px; line-height: 1.55; }

  /* ============================================================
     HERO (Phase-2 redesign): a single search input + 4 quick-filter
     chips, sitting directly under the masthead. Replaces the previous
     sidebar-only search affordance. The motto is "minimum to scan,
     maximum to act on" — one keystroke and a click should be enough
     to narrow 300 ads to ~10.
     ============================================================ */
  .hero-search { background: var(--panel); border-bottom: 1px solid var(--border); padding: 18px 32px 22px; }
  .hero-search-inner { max-width: 1100px; margin: 0 auto; }
  .hero-search-box {
    display: flex; align-items: stretch; gap: 0;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 12px; box-shadow: 0 1px 2px rgba(15,23,42,0.04);
    overflow: hidden;
  }
  .hero-search-box:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px rgba(31, 78, 121, 0.15), 0 1px 2px rgba(15,23,42,0.04);
  }
  .hero-search-box .search-cell {
    display: flex; align-items: center; gap: 10px;
    flex: 1; padding: 0 16px; min-height: 48px;
  }
  .hero-search-box .search-cell .search-ico {
    color: var(--muted); font-size: 16px; flex-shrink: 0;
  }
  .hero-search-box input {
    flex: 1; min-width: 0;
    border: none; outline: none; background: transparent;
    font: inherit; font-size: 14px; color: var(--ink); padding: 0;
  }
  .hero-search-box input::placeholder { color: var(--muted-soft); }
  .hero-search-box .clear-btn {
    background: transparent; border: none; cursor: pointer;
    color: var(--muted); font-size: 16px; padding: 4px 8px;
    border-radius: 6px; flex-shrink: 0;
  }
  .hero-search-box .clear-btn:hover { background: var(--chip-bg); color: var(--ink); }
  .hero-search-box .clear-btn[hidden] { display: none; }

  .hero-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; align-items: center; }
  .hero-chips .chips-label { font-size: 12px; color: var(--muted); margin-right: 4px; }
  .hero-chips .quick-chip {
    background: var(--panel); border: 1px solid var(--border);
    color: var(--ink); padding: 6px 12px; border-radius: 16px;
    font: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
  }
  .hero-chips .quick-chip:hover { border-color: var(--accent); color: var(--accent); }
  /* "On" state: a quick-chip that's currently driving the filter set. */
  .hero-chips .quick-chip.on {
    background: var(--accent); border-color: var(--accent); color: var(--panel);
  }

  nav.tabs { background: var(--panel); border-bottom: 1px solid var(--border); padding: 0 32px; display: flex; gap: 4px; align-items: stretch; }
  nav.tabs .tabs-spacer { flex: 1; }
  nav.tabs .tabs-right { flex: 1; display: flex; gap: 4px; justify-content: flex-end; align-items: center; }
  nav.tabs button { background: transparent; border: none; padding: 14px 18px; font: inherit; font-size: 15px; cursor: pointer; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -1px; font-weight: 600; }
  nav.tabs button.active,
  nav.tabs button[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 700; }
  nav.tabs .tab-count { color: var(--muted); font-weight: 400; margin-left: 6px; font-variant-numeric: tabular-nums; }
  /* WCAG 2.5.5: 44x44 tap area. Visual button stays compact via inner pseudo-disc. */
  nav.tabs .theme-toggle { background: transparent; border: none; cursor: pointer; color: var(--muted); padding: 0; align-self: center; transition: color .15s; font-size: 14px; line-height: 1; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; position: relative; }
  nav.tabs .theme-toggle::before { content: ""; position: absolute; left: 50%; top: 50%; width: 32px; height: 32px; transform: translate(-50%, -50%); border: 1px solid var(--border); border-radius: 18px; transition: border-color .15s, background .15s; pointer-events: none; }
  nav.tabs .theme-toggle:hover { color: var(--accent); }
  nav.tabs .theme-toggle:hover::before { border-color: var(--accent); }

  /* Single-column layout. The filter strip + tab bar span full width above,
     but `main` is centred at a comfortable reading width — long listing
     rows stretching edge-to-edge on a wide monitor are unscannable. 1080 px
     is roughly the width at which the deadline column, meta line, and
     title still read in one eye-sweep without the eye having to traverse
     half a screen. */
  main { padding: 18px 24px 40px; max-width: 1080px; margin: 0 auto; }

  /* ============================================================
     HORIZONTAL FILTER STRIP
     A row of click-to-open dropdowns. Each trigger button shows the
     filter name + the count of selections under it (when any). The
     popover that drops down contains the same checkbox markup the
     old sidebar used — IDs preserved so existing JS keeps working.
     One dropdown open at a time; click-outside closes.
     ============================================================ */
  .filter-strip {
    background: color-mix(in srgb, var(--panel) 92%, var(--bg) 8%);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 8px 32px; display: flex; flex-wrap: wrap; gap: 8px;
    align-items: center; justify-content: center; position: sticky; top: 0; z-index: 1000;
  }
  .filter-strip .strip-label { font-size: 12px; color: var(--muted); margin-right: 4px; font-weight: 500; }
  .filter-search {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 40px; min-width: 260px; max-width: 360px; flex: 1 1 280px;
    padding: 0 10px; border: 1px solid var(--border); border-radius: 4px;
    background: var(--panel); color: var(--muted);
  }
  .filter-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
  }
  .filter-search .search-ico { font-size: 14px; line-height: 1; flex-shrink: 0; }
  .filter-search input {
    width: 100%; min-width: 0; border: 0; outline: 0; background: transparent;
    color: var(--ink); font: inherit; font-size: 13px; padding: 8px 0;
  }
  .filter-search input::placeholder { color: var(--muted-soft); }
  /* WCAG 2.5.5: 44 px minimum tap area. The visual chip stays compact via
     padding; the min-height pads the focusable rect to the AA target without
     visibly inflating the pill. */
  .filter-strip .quick-chip { background: transparent; border: 1px solid var(--border); border-radius: 4px; padding: 7px 12px; min-height: 40px; font: inherit; font-size: 13px; color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: background .15s, border-color .15s, color .15s; font-weight: 650; }
  .filter-strip .quick-chip:hover { background: var(--chip-bg); }
  .filter-strip .quick-chip .quick-chip-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); transition: background .15s; }
  /* Reserved-posts chip pressed state uses Ambedkarite cobalt — affirmative
     action gets its actual political color, not a generic 'go' green. */
  .filter-strip .quick-chip[aria-pressed="true"] { background: var(--accent); color: #fff; border-color: var(--accent); }
  .filter-strip .quick-chip[aria-pressed="true"] .quick-chip-dot { background: #fff; }
  .filter-strip .quick-chip[aria-pressed="true"] .sel-pill { background: rgba(255,255,255,0.25); color: #fff; }
  .filter-dd { position: relative; }
  .filter-dd > .filter-trigger {
    background: transparent; border: 1px solid var(--border); border-radius: 4px;
    padding: 7px 12px; min-height: 40px; font: inherit; font-size: 13px; color: var(--ink);
    cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
    transition: border-color .15s, background .15s;
  }
  .filter-dd > .filter-trigger:hover { border-color: var(--accent); }
  .filter-dd.has-active > .filter-trigger { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
  .filter-dd > .filter-trigger .sel-pill {
    font-size: 11px; font-weight: 600; padding: 1px 7px; border-radius: 10px;
    background: var(--accent); color: var(--panel); margin-left: 2px;
  }
  .filter-dd > .filter-trigger .chev { color: var(--muted); font-size: 10px; }
  .filter-dd > .popover {
    position: absolute; top: calc(100% + 6px); left: 0;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 4px; box-shadow: 0 12px 32px rgba(15,23,42,0.14);
    padding: 12px; min-width: 240px; max-width: 320px;
    z-index: 1100; display: none;
  }
  /* Right-edge filters (Location, Institution type): open the popover
     leftward so it doesn't extend off-screen on the right. */
  .filter-dd:last-child > .popover,
  .filter-dd:nth-last-child(2) > .popover {
    left: auto; right: 0;
  }
  .filter-dd.open > .popover { display: block; }
  .filter-dd > .popover .filter-group { display: flex; flex-direction: column; gap: 2px; }
  .filter-dd > .popover .filter-group.scrollable { max-height: 280px; overflow-y: auto; }
  /* Small helper: a "Clear" link inside each popover. */
  .filter-dd > .popover .popover-foot { display: flex; justify-content: space-between; align-items: center; padding: 8px 4px 0; margin-top: 8px; border-top: 1px solid var(--border); font-size: 12px; }
  .filter-dd > .popover .popover-foot button { background: transparent; border: none; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; padding: 4px 6px; border-radius: 4px; }
  .filter-dd > .popover .popover-foot button:hover { color: var(--accent); background: var(--chip-bg); }
  /* Reuse the existing label / cnt styling from the old sidebar. */
  .filter-strip .filter-group label { display: flex; align-items: center; gap: 8px; padding: 6px 4px; cursor: pointer; font-size: 13px; border-radius: 4px; }
  .filter-strip .filter-group label:hover { background: var(--chip-bg); }
  .filter-strip .filter-group label .grow { flex: 1; }
  .filter-strip .filter-group label .cnt { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }

  @media (max-width: 720px) {
    .filter-strip { padding: 8px 14px; gap: 6px; }
    .filter-search { order: -1; flex-basis: 100%; max-width: none; min-width: 0; }
    .filter-dd > .popover { left: -4px; right: auto; min-width: calc(100vw - 28px); }
  }

  aside { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; overscroll-behavior: contain; }
  aside .search-wrap { padding: 16px 16px 12px; border-bottom: 1px solid var(--border); }
  aside label.upper { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); font-weight: 600; display: block; margin-bottom: 6px; }
  aside .search-box { position: relative; }
  aside .search-box input { width: 100%; padding: 9px 12px 9px 32px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--ink); font: inherit; font-size: 13px; outline: none; }
  aside .search-box .search-ico { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 13px; }

  .filter-section { border-bottom: 1px solid var(--border); }
  .filter-section:last-of-type { border-bottom: none; }
  .filter-section > button.filter-head { width: 100%; background: transparent; border: none; cursor: pointer; padding: 12px 16px; font: inherit; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink); font-weight: 700; display: flex; justify-content: space-between; align-items: center; }
  .filter-section .filter-head .sel-count { color: var(--accent); font-weight: 700; margin-left: 6px; }
  .filter-section .filter-head .chev { font-size: 10px; transition: transform 0.15s; }
  .filter-section.open .filter-head .chev { transform: rotate(90deg); }
  .filter-section .filter-body { padding: 0 16px 12px; display: none; }
  .filter-section.open .filter-body { display: block; }
  .filter-group label { display: flex; align-items: center; gap: 8px; padding: 4px 0; cursor: pointer; font-size: 13px; }
  .filter-group input[type="checkbox"] { accent-color: var(--accent); cursor: pointer; margin: 0; }
  .filter-group label .grow { flex: 1; }
  .filter-group label .cnt { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
  .filter-group.scrollable, .filter-group .scrollable { max-height: 220px; overflow-y: auto; }

  section#feed { min-width: 0; }

  .chipbar { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; align-items: center; }
  .chipbar .chip-active { background: var(--chip-bg); color: var(--ink); padding: 3px 9px; border-radius: 12px; font-size: 12px; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); }
  /* Active-filter chip × — keep visual glyph small, but expose a 24px tap area
     via padding. Full 44x44 would visibly inflate the chip; 24x24 is the
     minimum target size in WCAG 2.5.8 (AAA, but a reasonable compromise here). */
  .chipbar .chip-active button { background: transparent; border: none; color: var(--muted); cursor: pointer; padding: 6px 8px; margin: -6px -6px -6px 0; font-size: 14px; line-height: 1; min-width: 24px; min-height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: 4px; }
  .chipbar .chip-active button:hover { color: var(--ink); background: var(--border); }
  .chipbar .chip-summary { cursor: pointer; background: var(--accent); color: var(--panel); border-color: var(--accent); }
  .chipbar .chip-summary button { color: var(--panel); opacity: 0.85; }
  .chipbar .chip-summary:hover { opacity: 0.9; }
  .chipbar .chip-clear { background: transparent; border: none; color: var(--accent); font: inherit; font-size: 12px; cursor: pointer; padding: 3px 6px; text-decoration: underline; }

  .summary-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; flex-wrap: wrap; gap: 10px; color: var(--muted); font-size: 13px; }
  .summary-row .emph { color: var(--ink); font-weight: 600; }
  .summary-row .active-mark { margin-left: 8px; color: var(--accent); }
  .summary-row .sort-wrap { display: flex; align-items: center; gap: 8px; }
  .summary-row select { border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; font: inherit; font-size: 13px; background: var(--panel); color: var(--ink); cursor: pointer; }

  /* Disclaimer banner — quieter, single line, dismissible */
  .banner { background: color-mix(in srgb, var(--warn) 9%, var(--panel)); border: 1px solid color-mix(in srgb, var(--warn) 38%, var(--border)); color: color-mix(in srgb, var(--warn) 58%, var(--ink)); padding: 8px 12px; border-radius: 4px; margin-bottom: 12px; font-size: 12px; display: flex; gap: 8px; align-items: center; }
  .banner .warn-ico { font-size: 14px; line-height: 1; }
  /* WCAG 2.5.5: 44x44 tap target. Padding expands the hitbox; glyph stays small. */
  .banner button { margin-left: auto; background: transparent; border: none; color: currentColor; cursor: pointer; font-size: 16px; line-height: 1; padding: 14px 14px; opacity: 0.6; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .banner button:hover { opacity: 1; }

  /* ============================================================
     COMPACT ROW LAYOUT (Phase-1 redesign, May 2026).
     Replaces the previous 3-band card. Per ad:
       [tier-bar 4px] [main content] [large deadline column] [actions]
     Same `.listing` class kept so existing JS selectors work; the visual is
     row-style. The motto is "minimalism with maximum impact" — every
     pixel here was bargained for.
     ============================================================ */
  /* Vacancy-gap headline banner — sits above filters on the Listings tab.
     Cobalt + red split: cobalt for the "should be" number, red for the gap.
     This is the page's central claim, not decoration. */
  /* Compact vacancy-gap line. Replaces the previous full-bleed hero —
     a single inline statement of the gap (10,637 vacancies vs N
     currently advertised) with a thin alarm-coloured left rule.
     Lives at the top of the Vacancies tab. Numerator is hardcoded
     in the HTML; the denominator (#vgb-ads) is filled by app.js,
     filtered to non-private institutions so the ratio is honest. */
  .vacancy-gap-banner.vacancy-gap-banner-compact {
    /* No background tint — color-mix(alarm × bg) drifts into beige in
       light mode. The 3px alarm left rule + thin neutral top/bottom rules
       carry the editorial register without warming the page background. */
    background: transparent;
    border-left: 3px solid var(--alarm);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 12px 18px;
    margin: 4px 0 14px;
    border-radius: 0;
  }
  .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-line {
    margin: 0;
    font-family: var(--serif);
    font-style: italic;
    font-size: 16.5px;
    line-height: 1.55;
    color: var(--ink);
    text-align: center;
    letter-spacing: 0.005em;
  }
  .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-num {
    /* Numbers stay editorial-bold but switch off italic so the digits read
       cleanly. Tabular nums keep 10,637 and 249 from drifting on width. */
    font-family: var(--sans);
    font-style: normal;
    color: var(--alarm);
    font-weight: 800;
    font-size: 19px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.015em;
    padding: 0 1px;
  }
  .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-link {
    font-family: var(--sans);
    font-style: normal;
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    margin-left: 10px;
    border-bottom: 1px solid var(--accent);
    white-space: nowrap;
  }
  .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-link:hover {
    background: var(--accent);
    color: var(--bg);
  }
  html[data-theme="dark"] .vacancy-gap-banner.vacancy-gap-banner-compact {
    background: color-mix(in srgb, var(--alarm) 12%, var(--bg));
  }
  .feed-list { display: flex; flex-direction: column; gap: 18px; }
  /* Load-more button — large, satisfying tap target. Cobalt to align with
     the political register; the chevron suggests progressive expansion. */
  .load-more { display: block; width: 100%; margin: 14px 0 0; padding: 18px 24px; background: var(--panel); border: 2px solid var(--accent); border-radius: 10px; color: var(--accent); font: inherit; font-size: 15px; font-weight: 700; cursor: pointer; transition: background .15s, color .15s; text-align: center; letter-spacing: 0.01em; }
  .load-more:hover { background: var(--accent); color: #fff; }
  .load-more:hover .lm-sub { color: rgba(255,255,255,0.85); }
  .load-more .lm-sub { display: inline; color: var(--muted); font-weight: 500; margin-left: 6px; }
  .load-more-done { text-align: center; padding: 14px; font-size: 13px; color: var(--muted); font-style: italic; margin-top: 14px; border-top: 1px dashed var(--border); }
  /* === Listing card (discipline-first, May 2026 redesign) =============
   *
   * Three-line headline scanned in <2 seconds:
   *   DISCIPLINE        — what field is this  (h3, large serif)
   *   Rank · Contract   — what kind of position (smaller serif)
   *   Institution, City — the where           (sans body)
   *
   * Reservation row, deadline, and actions follow. The institution's own
   * ad title is no longer rendered as the headline; it duplicates the
   * discipline + rank + contract that now appear in their own lines.
   *
   * Layout grid (desktop):
   *   [4-px tier bar] [headline (1fr)] [deadline column] [star]
   * The reservation row, traps, apply links, and details disclosure
   * span the full row width below the headline grid.
   */
  .listing {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 0; padding: 18px 22px 16px;
    transition: border-color 0.15s, background 0.15s;
    position: relative; display: block;
  }
  html[data-theme="dark"] .listing:hover {
    background: color-mix(in srgb, var(--panel) 92%, var(--accent) 8%);
  }
  /* All listing cards (public + private) share the same neutral
     surface and the same cobalt hover. The earlier scope-private
     amber/brown hover override was the "ugly brown" tinge — dropped
     so private-uni cards don't read as visually downranked. The
     "Private university" tag in the card meta is sufficient as
     scope signal; we don't need a colour difference too. */
  .listing.scope-public,
  .listing.scope-private {
    background: var(--panel);
    border-color: var(--border);
  }
  .listing:hover { border-color: var(--accent); background: color-mix(in srgb, var(--panel) 96%, var(--accent) 4%); }
  /* Tier bar removed entirely — the 4px strip on the left of every
     listing read as a vestigial decorative accent. Urgency is now
     conveyed by the deadline column's red intensity alone. */
  .listing .tier-bar { display: none; }

  /* Headline grid: discipline + rank + inst on the left, deadline column
     on the right, star button in its own column. */
  .listing .card-body {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 18px;
    align-items: start;
  }
  .listing .card-headline { min-width: 0; }
  /* Headline = institution + parenthetical campus city. The institution
     is the candidate's primary scan target (the filter strip already
     handles discipline / position / contract / location-state). The
     campus city is rendered in muted weight to read as parenthetical
     disambiguator without competing with the institution name. */
  .listing .card-institution {
    margin: 0;
    font-family: var(--serif); font-size: 22px; font-weight: 700;
    line-height: 1.2; color: var(--ink); letter-spacing: -0.014em;
    display: inline-flex; align-items: center; flex-wrap: wrap; gap: 8px;
  }
  .listing .card-institution .card-campus {
    font-family: var(--serif); font-weight: 500;
    color: var(--muted); letter-spacing: 0;
  }
  /* Subhead carries the discipline + rank + contract in one line. The
     discipline is the secondary scan target — bolder weight inside the
     subhead, with the separator and rank in lighter weight. Italic
     register matches the publication aesthetic without competing with
     the headline. */
  .listing .card-subhead {
    margin: 7px 0 0;
    font-family: var(--sans); font-size: 15px; line-height: 1.45;
    color: var(--muted); font-style: normal;
  }
  .listing .card-subhead .card-rank {
    color: var(--ink); font-weight: 650; font-style: normal;
  }
  .listing .card-subhead .card-discipline {
    color: var(--muted); font-weight: 500;
  }
  .listing .card-subhead .card-contract-inline {
    color: var(--warn); font-weight: 650;
  }
  /* Flag row: posts count + provenance flags + dates. */
  .listing .card-flags {
    display: flex; flex-wrap: wrap; gap: 8px 14px;
    margin: 14px 0 0;
    font-family: var(--sans); font-size: 11.5px;
  }
  .listing .card-footer {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-top: 14px;
    padding-top: 12px;
    gap: 20px;
    border-top: 1px dashed var(--border);
  }
  .listing .card-flags.bottom-right {
    margin: 0;
    justify-content: flex-end;
    text-align: right;
  }
  .listing .card-flag {
    color: var(--muted); font-weight: 500;
  }
  .listing .card-flag.scope {
    border: 0;
    border-radius: 0;
    padding: 0;
    font-size: 11.5px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
  }
  .listing .card-flag.scope.public { color: var(--muted); background: transparent; }
  .listing .card-flag.scope.private { color: var(--muted); background: transparent; }
  .listing .card-flag.warn { color: #8a3a1a; font-weight: 600; }
  .listing .card-flag.manual { color: #78350f; font-weight: 600; }
  .listing .card-flag.dim { color: var(--muted); opacity: 0.85; }
  /* Deadline + actions retain their previous selectors so existing CSS
     rules below — .row-deadline, .row-actions, .star, etc. — keep
     applying. We rename the *containers* but keep the content classes. */
  .listing .card-deadline { text-align: right; flex-shrink: 0; min-width: 106px; }
  .listing .card-actions { display: flex; flex-direction: column; gap: 4px; align-items: center; }
  /* Mobile: collapse the actions column (star moves under flags), drop
     the dedicated padding for a denser scroll. */
  @media (max-width: 720px) {
    .listing { padding: 14px 16px 14px 18px; }
    .listing .card-body { grid-template-columns: 1fr auto; gap: 12px; }
    .listing .card-actions { display: none; }
    .listing .card-institution { font-size: 18px; }
    .listing .card-subhead { font-size: 14px; }
    .listing .card-deadline { min-width: 72px; }
  }
  /* Backwards-compat selectors so existing CSS for deadline / star /
     reservation pills / traps / apply links / details — written against
     .row-deadline, .row-actions etc. — keep applying. */
  .listing .card-deadline { /* alias of old .row-deadline */ }
  .listing .card-actions { /* alias of old .row-actions */ }

  /* Meta-line: institution / department / job-type / reservation pills */
  .listing .row-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12px; }
  .listing .meta-pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 14px; font-weight: 500; line-height: 1.4; }
  /* Institution pill — soft accent, the strongest secondary identifier after the title. */
  .listing .meta-pill.m-inst { background: var(--chip-bg); color: var(--accent); border: 1px solid var(--border); }
  /* Department pill — outlined neutral. */
  .listing .meta-pill.m-dept { background: transparent; color: var(--ink); border: 1px solid var(--border); }
  /* Job-type / contract pills — muted chips. */
  .listing .meta-pill.m-job { background: var(--chip-bg); color: var(--muted); border: 1px solid var(--border); font-weight: 400; }
  .listing .meta-pill.m-job.lowconf { background: #fde2d6; color: #8a3a1a; border-color: #f5c5a8; font-weight: 500; }
  /* Hand-transcribed entries (no primary-source URL on the institution's
     own site). Yellow-on-tan to differentiate from rough-parse red, while
     still flagging "verify before relying on this". */
  .listing .meta-pill.m-job.manual-stub-pill { background: #fef3c7; color: #78350f; border-color: #fde68a; font-weight: 500; cursor: help; }
  .listing .meta-tert { color: #545049; font-size: 11.5px; padding: 0 2px; }
  html[data-theme="dark"] .listing .meta-tert { color: #b3aea3; }

  /* Reservation pills — colour-coded per category so a quick glance shows
     which seats are SC/ST/OBC/EWS/PwBD. Counts are appended where parsed. */
  .listing .reserv-group { display: inline-flex; gap: 3px; align-items: center; flex-wrap: wrap; }
  .listing .reserv-pill { font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em; padding: 2px 5px; border-radius: 4px; line-height: 1.2; border: 1px solid; }
  .listing .reserv-pill.r-UR  { background: #f1f5f9; color: #334155; border-color: #cbd5e1; }
  .listing .reserv-pill.r-SC  { background: #fef3c7; color: #92400e; border-color: #fde68a; }
  .listing .reserv-pill.r-ST  { background: #ddd6fe; color: #5b21b6; border-color: #c4b5fd; }
  .listing .reserv-pill.r-OBC { background: #ccfbf1; color: #115e59; border-color: #99f6e4; }
  .listing .reserv-pill.r-EWS { background: #e0f2fe; color: #075985; border-color: #bae6fd; }
  .listing .reserv-pill.r-PwBD { background: #fce7f3; color: #9d174d; border-color: #fbcfe8; }
  html[data-theme="dark"] .listing .reserv-pill { filter: brightness(0.9) saturate(0.85); }

  /* Inline reservation strip — surfaces the per-institution policy
     (SC/ST/OBC/EWS/PwBD percentages) directly under the meta line, not
     buried in the details disclosure. Each category is colour-coded with
     the same palette as the per-position pills. */
  .listing .row-reserv { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin: 10px 0 0; grid-column: 2 / span 3; }
  .listing .reserv-info { position: relative; }
  .listing .art16-btn {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
    border: 1px solid transparent;
    list-style: none;
    user-select: none;
    transition: filter 0.2s;
  }
  .listing .art16-btn:hover { filter: brightness(0.95); }
  .listing .art16-btn::-webkit-details-marker { display: none; }
  .listing .art16-btn.art16-red {
    background: #ffebe9; color: #b91c1c; border-color: #fca5a5;
  }
  html[data-theme="dark"] .listing .art16-btn.art16-red {
    background: rgba(185, 28, 28, 0.2); color: #fca5a5; border-color: rgba(252, 165, 165, 0.3);
  }
  .listing .art16-btn.art16-green {
    background: #ecfdf5; color: #047857; border-color: #6ee7b7;
  }
  html[data-theme="dark"] .listing .art16-btn.art16-green {
    background: rgba(4, 120, 87, 0.2); color: #6ee7b7; border-color: rgba(110, 231, 183, 0.3);
  }
  .listing .art16-btn.art16-grey {
    background: #f3f4f6; color: #4b5563; border-color: #d1d5db;
  }
  html[data-theme="dark"] .listing .art16-btn.art16-grey {
    background: rgba(75, 85, 99, 0.2); color: #9ca3af; border-color: rgba(156, 163, 175, 0.3);
  }
  .listing .art16-btn.art16-strike {
    position: relative;
    overflow: hidden;
  }
  .listing .art16-btn.art16-strike::after {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(to top right, transparent calc(50% - 1px), currentColor calc(50%), transparent calc(50% + 1px));
    opacity: 0.5;
    pointer-events: none;
  }
  .listing .art16-details { display: inline-flex; position: relative; margin-left: 4px; vertical-align: middle; }
  .listing .reserv-info-pop {
    position: absolute;
    z-index: 20;
    top: 28px;
    left: 0;
    width: min(320px, calc(100vw - 48px));
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--ink);
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.45;
  }
  .listing .reserv-info-pop strong { color: var(--accent); display: block; margin-bottom: 4px; }
  .listing .reserv-breakdown { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; }
  .listing .reserv-label.warn { color: var(--warn); font-size: 11px; font-weight: 600; text-transform: uppercase; }
  .listing .reserv-label.good { color: #047857; font-size: 11px; font-weight: 600; text-transform: uppercase; }
  html[data-theme="dark"] .listing .reserv-label.good { color: #6ee7b7; }
  /* Hiring-language traps */
  .listing .row-traps { grid-column: 2 / span 3; margin: 8px 0 0; background: #fff8e7; border: 1px solid #f0d98e; border-left: 3px solid #d49a2a; border-radius: 6px; padding: 0; }
  .listing .row-traps summary { padding: 8px 12px; cursor: pointer; font-size: 12.5px; font-weight: 600; color: #5c4a1a; list-style: none; display: flex; align-items: center; gap: 8px; }
  .listing .row-traps summary::-webkit-details-marker { display: none; }
  .listing .row-traps summary:hover { background: rgba(212, 154, 42, 0.08); }
  .listing .row-traps .traps-icon { color: #b88a2e; font-size: 14px; }
  .listing .row-traps .traps-hint { color: var(--muted); font-weight: 400; font-size: 11.5px; font-style: italic; margin-left: auto; }
  .listing .row-traps[open] summary { border-bottom: 1px solid #f0d98e; }
  .listing .row-traps .traps-body { padding: 8px 12px 10px; }
  .listing .row-traps .trap { margin: 8px 0; }
  .listing .row-traps .trap:first-child { margin-top: 0; }
  .listing .row-traps .trap-label { font-size: 12.5px; font-weight: 700; color: #5c4a1a; margin-bottom: 2px; }
  .listing .row-traps .trap-why { font-size: 12px; color: #3d3108; line-height: 1.5; }
  /* Resources tab */
  #resources-tab { max-width: 980px; }
  #resources-tab .res-intro h2 { font-family: var(--serif); font-weight: 600; font-size: 22px; margin: 8px 0 8px; }
  #resources-tab .res-intro p { font-size: 14px; color: var(--ink); line-height: 1.6; max-width: 70ch; margin-bottom: 24px; }
  #resources-tab .res-accordion { margin-bottom: 24px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.03); transition: box-shadow 0.2s ease, transform 0.2s ease; }
  #resources-tab .res-accordion:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.08); transform: translateY(-2px); }
  html[data-theme="dark"] #resources-tab .res-accordion:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
  #resources-tab .res-accordion > summary { list-style: none; padding: 22px 26px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 16px; background: color-mix(in srgb, var(--chip-bg) 30%, transparent); transition: background 0.2s ease; }
  #resources-tab .res-accordion > summary::-webkit-details-marker { display: none; }
  #resources-tab .res-accordion > summary:hover { background: color-mix(in srgb, var(--chip-bg) 60%, transparent); }
  #resources-tab .res-accordion > summary .acc-title { font-family: var(--serif); font-weight: 700; font-size: 20px; color: var(--ink); line-height: 1.3; border-left: 4px solid var(--accent); padding-left: 14px; }
  #resources-tab .res-accordion > summary .acc-icon { font-size: 18px; color: var(--accent); font-weight: 600; padding: 4px 12px; background: color-mix(in srgb, var(--accent) 10%, transparent); border-radius: 12px; transition: transform 0.3s ease, background 0.2s ease; }
  #resources-tab .res-accordion:hover > summary .acc-icon { background: color-mix(in srgb, var(--accent) 15%, transparent); }
  #resources-tab .res-accordion[open] > summary { border-bottom: 1px solid var(--border); background: var(--chip-bg); }
  #resources-tab .res-accordion[open] > summary .acc-icon { transform: rotate(180deg); }
  #resources-tab .res-accordion .acc-content { padding: 24px 28px; background: color-mix(in srgb, var(--bg) 50%, var(--panel)); }
  #resources-tab .postdoc-block > summary .acc-title { border-left-color: var(--alarm); }
  #resources-tab .rti-block > summary .acc-title { border-left-color: var(--accent); }
  #resources-tab .res-block { margin-bottom: 28px; }
  #resources-tab .res-block h3 { display: none; }
  #resources-tab .res-block ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
  #resources-tab .res-block li { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 18px 20px; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center; }
  #resources-tab .res-block li:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(0,0,0,0.06); border-color: var(--accent); }
  html[data-theme="dark"] #resources-tab .res-block li:hover { box-shadow: 0 12px 32px rgba(0,0,0,0.3); }
  #resources-tab .res-block li a { color: var(--accent); text-decoration: none; font-weight: 600; font-size: 15px; display: inline-flex; align-items: center; gap: 4px; }
  #resources-tab .res-block li a:hover { color: var(--accent-deep); }
  #resources-tab .res-block li .ext { font-size: 11px; color: var(--muted); margin-left: 2px; }
  #resources-tab .res-block li .res-name { font-weight: 600; font-size: 14px; color: var(--ink); }
  #resources-tab .res-block li .res-note { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin-top: 4px; }
  /* Postdoc-abroad block — distinct register from the rest of the
     Resources tab: a longer political introduction, sub-grouped lists
     so candidates can navigate by program type rather than scrolling
     through one flat list of 25 fellowships. */
  #resources-tab .postdoc-block { margin-bottom: 24px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.03); }
  html[data-theme="dark"] #resources-tab .postdoc-block { box-shadow: none; }
  #resources-tab .postdoc-block h3 { display: none; }
  #resources-tab .postdoc-block .res-block-intro { font-size: 13.5px; line-height: 1.65; color: var(--ink); margin: 0 0 16px; max-width: none; text-align: justify; }
  #resources-tab .postdoc-block .res-block-intro p { margin: 0 0 10px; }
  #resources-tab .postdoc-block .res-block-intro p:last-child { margin-bottom: 0; }
  #resources-tab .postdoc-block .res-block-intro em { color: var(--alarm); font-style: normal; font-weight: 600; }
  #resources-tab .postdoc-filters { display: flex; flex-wrap: wrap; gap: 16px; margin: 24px 0 20px; padding: 16px 20px; background: color-mix(in srgb, var(--chip-bg) 40%, transparent); border: 1px dashed var(--border); border-radius: 12px; align-items: center; }
  #resources-tab .postdoc-filters label { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
  #resources-tab .postdoc-filters select { padding: 8px 32px 8px 12px; font-size: 14px; font-weight: 600; color: var(--ink); background: var(--bg); border: 1px solid var(--border); border-radius: 8px; appearance: none; cursor: pointer; outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease; background-image: url('data:image/svg+xml;utf8,<svg fill="none" stroke="%23666" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>'); background-repeat: no-repeat; background-position: right 10px center; background-size: 14px; }
  html[data-theme="dark"] #resources-tab .postdoc-filters select { background-image: url('data:image/svg+xml;utf8,<svg fill="none" stroke="%23999" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>'); }
  #resources-tab .postdoc-filters select:hover { border-color: var(--accent); }
  #resources-tab .postdoc-filters select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent); }
  #resources-tab .postdoc-subgroup { margin-top: 16px; }
  #resources-tab .postdoc-subgroup h4 { font-family: var(--sans); font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin: 0 0 12px; padding: 0; border: none; }
  #resources-tab .postdoc-subgroup ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
  #resources-tab .postdoc-subgroup li { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 16px 20px; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; display: flex; flex-direction: column; justify-content: flex-start; }
  #resources-tab .postdoc-subgroup li:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(0,0,0,0.06); border-color: var(--accent); }
  html[data-theme="dark"] #resources-tab .postdoc-subgroup li:hover { box-shadow: 0 12px 32px rgba(0,0,0,0.3); }
  #resources-tab .postdoc-subgroup li a { color: var(--accent); text-decoration: none; font-weight: 600; font-size: 15px; margin-bottom: 4px; display: inline-block; }
  #resources-tab .postdoc-subgroup li a:hover { color: var(--accent-deep); }
  #resources-tab .postdoc-subgroup li .res-note { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin-top: 6px; }
  #resources-tab .postdoc-subgroup li .ext { font-size: 11px; color: var(--muted); margin-left: 2px; }
  /* Eligibility chip — surfaces citizenship/residency restrictions per
     fellowship so an Indian-PhD applicant doesn't waste hours on a
     program that excludes them at the door. Three visual registers:
     open (green), caveat (amber), restricted (red). */
  #resources-tab .elig { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 10px; margin-left: 6px; vertical-align: middle; letter-spacing: 0.02em; line-height: 1.3; white-space: nowrap; }
  #resources-tab .elig.elig-open { background: rgba(46,125,50,0.10); color: #2e7d32; border: 1px solid rgba(46,125,50,0.30); }
  #resources-tab .elig.elig-caveat { background: rgba(180,120,30,0.10); color: #8a5a10; border: 1px solid rgba(180,120,30,0.35); }
  #resources-tab .elig.elig-restricted { background: rgba(180,30,40,0.10); color: var(--alarm); border: 1px solid rgba(180,30,40,0.35); }
  #resources-tab .elig.elig-varies { background: var(--chip-bg); color: var(--muted); border: 1px solid var(--border); }
  html[data-theme="dark"] #resources-tab .elig.elig-open { background: rgba(111,207,138,0.10); color: #88dd9d; border-color: rgba(111,207,138,0.35); }
  html[data-theme="dark"] #resources-tab .elig.elig-caveat { background: rgba(232,180,120,0.10); color: #e8b478; border-color: rgba(232,180,120,0.35); }
  html[data-theme="dark"] #resources-tab .elig.elig-restricted { background: rgba(240,133,133,0.10); color: #f08585; border-color: rgba(240,133,133,0.35); }
  /* Region chip — neutral register, sits alongside eligibility but
     visually quieter so eligibility remains the dominant signal. The
     region is informational ("where would I be"); eligibility is
     gating ("can I even apply"). Six values: US, Canada, UK, EU,
     Japan, Multi. */
  #resources-tab .region { display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 10px; margin-left: 6px; vertical-align: middle; letter-spacing: 0.04em; line-height: 1.3; white-space: nowrap; background: var(--chip-bg); color: var(--accent); border: 1px solid rgba(31,58,138,0.25); text-transform: uppercase; }
  html[data-theme="dark"] #resources-tab .region { background: rgba(91,141,217,0.10); color: #9ab8e6; border-color: rgba(91,141,217,0.30); }
  /* Eligibility legend at the top of the postdoc block. */
  #resources-tab .elig-legend { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 14px; padding: 10px 12px; background: var(--bg); border: 1px dashed var(--border); border-radius: 8px; font-size: 11.5px; color: var(--muted); align-items: center; }
  #resources-tab .elig-legend .leg-label { font-weight: 600; color: var(--ink); margin-right: 4px; }
  /* RTI templates block — distinct visual register from the link-list
     blocks: this is action infrastructure, not reading. */
  #resources-tab .rti-block { margin-bottom: 24px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.03); }
  html[data-theme="dark"] #resources-tab .rti-block { box-shadow: none; }
  #resources-tab .rti-block h3 { display: none; }
  #resources-tab .rti-block .res-block-intro { font-size: 14px; line-height: 1.6; color: var(--ink); margin: 0 0 18px; }
  #resources-tab .rti-block .rti-subhead { font-family: var(--sans); font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--accent); margin: 28px 0 12px; padding: 0; border: none; }
  #resources-tab .rti-block .rti-subhead:first-of-type { margin-top: 8px; }
  #resources-tab .rti-block .rti-subnote { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 0 0 16px; font-style: italic; }
  #resources-tab .rti-block .indian-link-list { list-style: none; padding: 0; margin: 0 0 8px; display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
  #resources-tab .rti-block .indian-link-list li { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 14px 18px; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; }
  #resources-tab .rti-block .indian-link-list li:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.06); border-color: var(--accent); }
  html[data-theme="dark"] #resources-tab .rti-block .indian-link-list li:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
  #resources-tab .rti-block .indian-link-list li a { color: var(--accent); text-decoration: none; font-weight: 600; font-size: 14.5px; display: inline-block; margin-bottom: 2px; }
  #resources-tab .rti-block .indian-link-list li a:hover { color: var(--accent-deep); }
  #resources-tab .rti-block .indian-link-list li .res-note { font-size: 12px; color: var(--muted); line-height: 1.55; margin-top: 4px; }
  #resources-tab .rti-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
  #resources-tab .rti-card { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.02); transition: box-shadow 0.2s ease, transform 0.2s ease; }
  #resources-tab .rti-card:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.06); transform: translateY(-2px); }
  html[data-theme="dark"] #resources-tab .rti-card:hover { box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
  #resources-tab .rti-card summary { padding: 16px 20px; cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 12px; font-weight: 600; font-size: 15px; color: var(--ink); background: color-mix(in srgb, var(--chip-bg) 50%, transparent); transition: background 0.15s ease; }
  #resources-tab .rti-card summary::-webkit-details-marker { display: none; }
  #resources-tab .rti-card summary:hover { background: var(--chip-bg); }
  #resources-tab .rti-card[open] summary { border-bottom: 1px solid var(--border); background: var(--chip-bg); }
  #resources-tab .rti-card .rti-expand { font-size: 12.5px; color: var(--accent); font-weight: 600; white-space: nowrap; background: color-mix(in srgb, var(--accent) 10%, transparent); padding: 4px 10px; border-radius: 12px; transition: background 0.15s ease, color 0.15s ease; }
  #resources-tab .rti-card:hover .rti-expand { background: color-mix(in srgb, var(--accent) 15%, transparent); }
  #resources-tab .rti-card[open] .rti-expand { color: var(--muted); background: transparent; }
  #resources-tab .rti-card[open] .rti-expand::before { content: "Hide template ▴"; }
  #resources-tab .rti-card[open] .rti-expand { font-size: 0; padding: 0; }
  #resources-tab .rti-card[open] .rti-expand::before { font-size: 12.5px; font-weight: 500; }
  #resources-tab .rti-card .rti-body { padding: 20px 24px; background: color-mix(in srgb, var(--panel) 98%, var(--border) 2%); }
  #resources-tab .rti-card .rti-scenario { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 0 0 16px; font-style: italic; }
  #resources-tab .rti-card .rti-target { font-size: 13.5px; color: var(--ink); margin-bottom: 12px; }
  #resources-tab .rti-card .rti-text { width: 100%; min-height: 240px; padding: 16px; font-family: var(--mono); font-size: 13px; line-height: 1.6; color: var(--ink); background: var(--bg); border: 1px solid var(--border); border-radius: 8px; resize: vertical; box-sizing: border-box; box-shadow: inset 0 2px 4px rgba(0,0,0,0.02); }
  #resources-tab .rti-card .rti-actions { display: flex; gap: 14px; align-items: center; margin-top: 16px; flex-wrap: wrap; }
  #resources-tab .rti-card .rti-copy { padding: 10px 20px; background: var(--accent); color: #fff; border: none; border-radius: 8px; font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; transition: background 0.15s ease, transform 0.1s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
  #resources-tab .rti-card .rti-copy:hover { background: var(--accent-deep); transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0,0,0,0.15); }
  #resources-tab .rti-card .rti-copy:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
  #resources-tab .rti-card .rti-copy.copied { background: var(--good); }
  #resources-tab .rti-card .rti-online { font-size: 14px; font-weight: 600; color: var(--accent); text-decoration: none; padding: 8px 12px; border-radius: 6px; transition: background 0.15s ease; }
  #resources-tab .rti-card .rti-online:hover { text-decoration: none; background: color-mix(in srgb, var(--accent) 8%, transparent); }

  /* Always-visible action strip: PDF + Apply portal + Listing page +
     Annexure links sitting under the meta line. The user shouldn't have to
     expand a disclosure just to find out where to apply. */
  .listing .row-actions-inline { display: flex; flex-wrap: wrap; gap: 18px; align-items: baseline; font-size: 13px; }
  .listing .row-actions-inline a { color: var(--accent); font-weight: 650; text-decoration: none; }
  .listing .row-actions-inline a:hover { text-decoration: underline; }

  /* Areas excerpt: small body text below the meta line. Collapsible details
     sit immediately after, so the row stays compact at rest. */
  .listing .row-areas { font-size: 12.5px; color: var(--ink); margin: 8px 0 0; line-height: 1.5; grid-column: 2 / span 3; }
  .listing .row-areas .k { display: none; }

  /* === Card cues — the cover-letter scan ============================
   *
   * The previous design rendered ad.raw_text_excerpt as a 500-character
   * paragraph. Candidates couldn't scan it: the high-signal pieces
   * (sub-areas list, methods preference, sub-disciplinary approach)
   * were embedded in boilerplate ("specialisation must be clearly
   * evidenced through research and publications…"). Now we parse and
   * label the three pieces explicitly so a candidate can answer in two
   * seconds: do my projects fit the sub-areas listed; do my methods
   * match what they want; does my disciplinary self-presentation map
   * onto theirs. The boilerplate stays in the expanded details and
   * gets surfaced separately by the trap-detector.
   */
  .listing .card-cues { margin: 12px 0 0; display: flex; flex-direction: column; gap: 8px; }
  .listing .card-cue {
    display: flex; align-items: baseline; gap: 10px;
    font-family: var(--sans);
  }
  .listing .card-cue-label {
    flex: 0 0 auto;
    font-size: 12px; font-weight: 700; text-transform: none;
    letter-spacing: 0; color: var(--muted);
    padding-top: 1px;
  }
  .listing .card-cue-value {
    font-family: var(--sans);
    font-size: 14.5px; color: var(--ink); line-height: 1.55;
    font-style: normal;
  }
  /* Areas: tag chips. Wrap freely; don't make a candidate hunt across
     a wall of comma-separated text. */
  .listing .card-cue-tags { display: flex; flex-wrap: wrap; gap: 5px; }
  .listing .card-area-chip {
    display: inline-flex; align-items: center;
    padding: 2px 9px; border-radius: 4px;
    font-size: 12.5px; font-weight: 600; line-height: 1.4;
    background: color-mix(in srgb, var(--chip-bg) 72%, transparent); color: var(--ink);
    border: 1px solid var(--border);
  }
  .listing .card-area-more {
    display: inline-flex; align-items: center;
    padding: 2px 0;
    font-size: 12.5px; font-weight: 600; line-height: 1.4;
    color: var(--muted);
    cursor: pointer;
  }
  .listing .card-area-more:hover { color: var(--accent); text-decoration: underline; }
  .listing .card-area-more-wrap { display: contents; }
  .listing .card-area-more-wrap > summary { list-style: none; }
  .listing .card-area-more-wrap > summary::-webkit-details-marker { display: none; }
  .listing .card-area-more-list { display: contents; }
  .listing .card-area-more-wrap[open] > summary { display: none; }
  /* Empty state: when the recruiting department has not enunciated the
     topical fit / eligibility / evaluation criteria in the advertisement, name that
     absence explicitly. Italic muted phrasing is visible without
     screaming, so the pattern is legible across many cards — most ads
     do not specify; that's the political point. The `cursor: help`
     surfaces the tooltip explaining the silence. */
  .listing .card-cue-empty {
    font-family: var(--sans); font-size: 12.5px;
    color: var(--muted); font-style: italic; line-height: 1.45;
    cursor: help;
  }
  .listing .card-cue.is-empty .card-cue-label {
    color: var(--muted); font-weight: 600;
  }
  @media (max-width: 720px) {
    .listing .card-cue { flex-direction: column; gap: 4px; }
    .listing .card-cue-label { min-width: 0; padding-top: 0; }
  }
  .listing .details { font-size: 12.5px; color: var(--ink); margin: 8px 0 0; grid-column: 2 / span 3; }
  .listing .details > summary { cursor: pointer; color: var(--muted); font-size: 12px; padding: 4px 0; user-select: none; display: inline-flex; align-items: center; gap: 4px; }
  .listing .details > summary:hover { color: var(--accent); }
  .listing .details[open] > summary { color: var(--accent); }
  .listing .detail-block { margin-top: 6px; padding: 6px 0; }
  .listing .detail-block .k { color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; font-size: 10px; font-weight: 600; display: block; margin-bottom: 3px; }
  .listing .detail-block .v { line-height: 1.55; }

  /* Action links live in the details disclosure for compactness; only the
     Original-PDF link is promoted to the always-visible action column. */
  .listing .details .action-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--border); font-size: 12.5px; }
  .listing .details .action-links a { color: var(--accent); font-weight: 500; text-decoration: none; }
  .listing .details .action-links a:hover { text-decoration: underline; }

  /* Large deadline column — the big "66 / DAYS / 30 Jun 2026" stack on
     the right of each row. Tier-coloured. Replaces the previous pill. */
  .listing .row-deadline { text-align: right; flex-shrink: 0; min-width: 96px; }
  .listing .deadline-num { font-family: var(--serif); font-size: 27px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--muted); }
  /* Critical-tier deadlines (≤7 days) get heavier weight and a stronger
     red — the protest register applied to the moment that actually
     matters: "this closes soon, act on it." */
  /* Urgency hierarchy on the deadline number. One colour family — the
     project's protest red — at different intensities, plus muted for
     "not soon": critical (≤7 days) is the boldest, largest, and most
     saturated; soon (8-30 days) reads in the same red but at the
     default size + weight; ok (31+ days) drops to muted. The earlier
     amber #8a5403 read as ugly brown — replaced. */
  .listing.tier-critical .deadline-num { color: var(--alarm); font-weight: 850; font-size: 29px; }
  .listing.tier-soon     .deadline-num { color: var(--alarm); font-weight: 700; }
  .listing.tier-ok       .deadline-num { color: var(--muted); }
  .listing .deadline-num.small { font-size: 12px; font-weight: 500; color: var(--muted); }
  /* Rolling-deadline pill — same visual slot as the big number, but
     pill-shaped so it reads "still active, no specific cut-off"
     instead of "missing data." Warm amber to match the existing warn
     palette (composite-roster banner, etc.) rather than a hot color. */
  .listing .deadline-rolling {
    display: inline-block;
    background: rgba(160, 110, 21, 0.10);
    color: var(--warn);
    border: 1px solid rgba(160, 110, 21, 0.32);
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
  }
  html[data-theme="dark"] .listing .deadline-rolling {
    background: rgba(194, 140, 80, 0.14);
    color: #d8a368;
    border-color: rgba(194, 140, 80, 0.40);
  }
  .listing .deadline-unit { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 600; margin-top: 3px; }
  .listing .deadline-date { font-size: 11px; color: var(--muted); font-family: var(--mono); margin-top: 2px; }

  /* Actions column — currently just the save star. */
  .listing .row-actions { display: flex; flex-direction: column; gap: 4px; align-items: center; }
  /* WCAG 2.5.5 AA: 44x44 minimum tap area (was 36x36 — visual unchanged, the
     padding box just expands to meet the AA target). */
  .listing .star { background: transparent; border: 1px solid transparent; cursor: pointer; font-size: 16px; color: var(--muted); border-radius: 8px; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .listing .star:hover { background: var(--chip-bg); color: var(--accent); }
  .listing .star.on { color: var(--warn); }

  /* ============================================================
     MOBILE — comprehensive overhaul (May 2026).
     The desktop layout assumes ~1080 px reading width with edge
     padding of 32 px. On phones every one of those numbers is wrong:
     the masthead steals 200 px before the content starts, the tab
     bar wraps onto two lines, the filter strip fills the screen with
     a single dropdown, and the listing card's 4-column grid breaks
     into an unreadable shape. This block fixes all of that.
     ============================================================ */
  @media (max-width: 720px) {
    /* Masthead — keep the political register but stop eating a fifth
       of the viewport on a 6-inch phone. */
    header.masthead { padding: 20px 14px 14px; border-top-width: 4px; }
    header.masthead h1 { font-size: 28px; letter-spacing: -0.015em; }
    header.masthead .subtitle { font-size: 12.5px; line-height: 1.5; max-width: 100%; }

    /* Tab bar — horizontally scrollable instead of wrapping onto a
       second row. The flex spacers that center the bar on desktop
       are pointless here and force the right-side group off-screen. */
    nav.tabs { padding: 0 8px; overflow-x: auto; gap: 0;
               scrollbar-width: none; -webkit-overflow-scrolling: touch; }
    nav.tabs::-webkit-scrollbar { display: none; }
    nav.tabs .tabs-spacer { display: none; }
    nav.tabs .tabs-right { flex: none; }
    nav.tabs button { padding: 12px 12px; font-size: 14px; white-space: nowrap; flex-shrink: 0; }
    nav.tabs .theme-toggle { min-width: 40px; min-height: 40px; }

    /* Main container — tighter side padding so cards have room to breathe. */
    main { padding: 14px 12px 32px; }

    /* Filter strip — left-justify and collapse the "Filter:" label.
       On a phone, dropdown buttons need every horizontal pixel. */
    .filter-strip { padding: 8px 10px; gap: 6px; justify-content: flex-start; }
    .filter-strip .strip-label { display: none; }
    .filter-search { min-height: 42px; }
    .filter-dd > .filter-trigger { padding: 6px 10px; font-size: 12.5px; }
    .filter-strip .quick-chip { padding: 6px 10px; font-size: 12px; }
    .filter-dd > .popover { left: -4px; right: auto; min-width: calc(100vw - 28px); max-width: calc(100vw - 28px); }
    /* Override right-aligned positioning for edge filters on mobile —
       everything goes full-width on small screens. */
    .filter-dd:last-child > .popover,
    .filter-dd:nth-last-child(2) > .popover { left: auto; right: -4px; }

    /* Map: shorter on mobile, summary stacks vertically. */
    #map-container { height: calc(100vh - 220px); min-height: 320px; max-height: 560px; }
    .map-summary { font-size: 12px; gap: 4px 8px; padding: 8px 0; }
    .map-legend { padding: 8px 10px; gap: 4px; font-size: 11px; }

    /* Compact vacancy-gap line — slightly smaller body text on phones;
       border + colour stay so the line still reads as alarm copy. */
    .vacancy-gap-banner.vacancy-gap-banner-compact { padding: 10px 14px; }
    .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-line { font-size: 14.5px; line-height: 1.55; }
    .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-num { font-size: 17px; }
    .vacancy-gap-banner.vacancy-gap-banner-compact .vgb-link { display: inline-block; margin-left: 6px; }

    /* Listing card — collapse to 3 columns (tier-bar | content | deadline),
       drop the actions column entirely. The row-meta pills wrap naturally. */
    .listing { grid-template-columns: 4px 1fr auto; gap: 12px; padding: 12px 14px; }
    .listing .row-actions { display: none; }
    .listing .row-title { font-size: 14.5px; }
    .listing .row-meta { font-size: 11.5px; gap: 4px 5px; }
    .listing .meta-pill { padding: 2px 7px; font-size: 11px; }
    .listing .deadline-num { font-size: 18px; }
    .listing .row-deadline { min-width: 72px; }

    /* Summary row + sort dropdown — sort goes full-width on phone. */
    .summary-row { font-size: 12.5px; align-items: stretch; }
    .summary-row .sort-wrap { justify-content: flex-end; }

    /* Banner (deadline-warning + data-unavailable) — tighter type. */
    .banner { font-size: 11.5px; padding: 8px 10px; }

    /* Footer — keep readable, stop eating screen with 32 px side padding. */
    footer { padding: 18px 14px !important; font-size: 11.5px; }
  }

  /* Sub-360 px (older / smaller phones in landscape with browser chrome).
     Collapse the deadline column as a final fallback so the title isn't
     squeezed into a 60 px ribbon. */
  @media (max-width: 420px) {
    .listing { grid-template-columns: 4px 1fr; }
    .listing .row-deadline { grid-column: 2; text-align: left; min-width: 0; margin-top: 6px; }
    .listing .row-deadline .deadline-num { font-size: 14px; display: inline; margin-right: 6px; font-weight: 700; color: var(--alarm); }
    .listing .row-deadline .deadline-pill { font-size: 11px; }
    header.masthead h1 { font-size: 24px; }
    nav.tabs button { padding: 11px 9px; font-size: 13px; }
  }

  .empty-state { padding: 60px 20px; text-align: center; color: var(--muted); font-size: 14px; }
  .empty-state .big { font-size: 40px; margin-bottom: 10px; }
  .empty-state .empty-state-headline {
    font-family: var(--serif); font-size: 18px; color: var(--ink);
    font-weight: 650; margin-bottom: 8px;
  }
  .empty-state .empty-state-body {
    max-width: 460px; margin: 0 auto 14px; line-height: 1.55;
  }
  .empty-state .empty-state-clear {
    min-height: 40px; padding: 8px 14px; border: 1px solid var(--accent);
    border-radius: 4px; background: transparent; color: var(--accent);
    font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  }
  .empty-state .empty-state-clear:hover { background: var(--accent); color: var(--panel); }

  /* Reserved-posts toggle empty state — editorial framing, not a generic
     "no match." Headline + body + CTA, narrower max-width so the body
     paragraph reads as prose, not as scattered words. */
  .empty-state-reserved { max-width: 560px; margin: 0 auto; }
  .empty-state-reserved .big { color: var(--warn); font-size: 36px; }
  .empty-state-reserved .empty-state-headline {
    font-family: var(--serif, var(--font-serif, Newsreader, Georgia, serif));
    font-size: 18px; color: var(--ink); margin: 4px 0 12px;
    font-weight: 600; line-height: 1.35;
  }
  .empty-state-reserved .empty-state-body {
    font-size: 13.5px; line-height: 1.55; color: var(--muted);
    margin: 0 auto 16px; max-width: 480px;
  }
  .empty-state-reserved .empty-state-cta a {
    color: var(--accent); font-weight: 600; text-decoration: none;
    border-bottom: 1px solid currentColor;
  }
  .empty-state-reserved .empty-state-cta a:hover { opacity: 0.8; }

  /* Apply CTA — filled button in Ambedkar blue (#0047AB). Hardcoded
     here rather than driven by --accent so the broader palette stays
     untouched until the full Ambedkar/Left aesthetic redesign lands.
     The earlier classified-row treatment (text-only, var(--accent))
     is preserved in git history; restoring filled-button styling per
     2026-05-05 maintainer call. */
  .listing .row-actions-inline a.btn-apply {
    display: inline-flex; align-items: center; gap: 4px;
    /* Ambedkar blue — same token the masthead title uses, so the
       primary CTA and the editorial nameplate sit in the same blue. */
    background: var(--ambedkar-blue); color: #fff;
    padding: 6px 14px; border-radius: 6px;
    font-size: 13px; font-weight: 600; text-decoration: none;
    border: 1px solid var(--ambedkar-blue);
    transition: background 0.15s ease, opacity 0.15s ease;
    flex-shrink: 0;
  }
  .listing .row-actions-inline a.btn-apply:hover {
    background: var(--ambedkar-blue-deep); border-color: var(--ambedkar-blue-deep);
    color: #fff; opacity: 1; text-decoration: none;
  }
  /* Third-party apply portal disclosure: shown next to the Apply
     button when the apply URL's registered domain differs from the
     institution's own domain (e.g. Ashoka → apply.interfolio.com).
     Quiet, monospace, no surrounding box — reads as truth-in-
     labelling rather than a warning. */
  .listing .row-actions-inline .apply-host-via {
    font-size: 11px;
    color: var(--muted);
    font-family: var(--mono);
    margin-left: -4px;
    white-space: nowrap;
    align-self: center;
  }
  .listing .quiet-links {
    display: inline-flex; flex-wrap: wrap; gap: 16px;
    color: var(--muted); font-size: 12.5px;
  }
  .listing .row-actions-inline .quiet-links a {
    color: var(--muted); font-weight: 600; text-decoration: none;
  }
  .listing .row-actions-inline .quiet-links a:hover {
    color: var(--accent); text-decoration: underline;
  }

  /* Deadline column — "25 days" inline as the headline, date below
     muted. Far-out deadlines (> 60 days) drop the big number and show
     only a quiet "Closes <date>" anchor. */
  .listing .deadline-num .deadline-unit-inline {
    font-family: var(--sans); font-size: 10.5px; font-weight: 760; color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.04em;
    margin-left: 2px; vertical-align: 0.2em;
    font-variant-numeric: normal;
  }
  .listing .deadline-meta {
    font-size: 11.5px; color: var(--muted); font-family: var(--mono);
    margin-top: 3px; line-height: 1.3;
  }
  .listing .deadline-future {
    font-size: 11.5px; color: var(--muted); font-family: var(--mono);
    line-height: 1.4; padding-top: 4px;
  }
  .listing .deadline-future-date { color: var(--ink); font-weight: 500; }

  /* Map */
  /* Trap Leaflet's internal z-indexes (tile pane 200, controls 800+)
     inside its own stacking context so the filter-strip popovers
     (z-index: 1100) always paint above the map surface. */
  #map-container {
    height: calc(100vh - 200px); min-height: 480px; max-height: 800px;
    border-radius: 8px; overflow: hidden; border: 1px solid var(--border);
    position: relative; z-index: 0;
  }
  /* Map summary bar — sits between filter strip and the map, mirrors
     the listings summary row so the user gets count feedback. */
  .map-summary {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: 8px 16px;
    padding: 10px 0; font-size: 13px; color: var(--muted);
  }
  .map-summary .map-counts {
    display: flex; gap: 16px; align-items: center;
  }
  .map-summary .map-counts .emph {
    font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums;
  }
  .map-summary .map-active-chips {
    display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
  }
  /* Legend — upgraded from a flat flex row to a styled strip with
     clickable items that double as institution-type toggles. */
  .map-legend {
    display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px;
    font-size: 12px; padding: 10px 14px;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 8px;
  }
  .map-legend-item {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px; border-radius: 4px;
    cursor: default; transition: background 0.15s ease;
    font-weight: 500;
  }
  .map-legend-item:hover { background: var(--chip-bg); }
  .map-legend-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
  /* Map tile boundary disclaimer — legally important for Indian maps.
     Styled quiet so it doesn't overpower the map itself. */
  .map-disclaimer {
    font-size: 11.5px; color: var(--muted); line-height: 1.5;
    margin: 10px 0 0; padding: 0; font-style: italic;
  }
  .map-disclaimer a { color: var(--accent); text-decoration: none; }
  .map-disclaimer a:hover { text-decoration: underline; }
  .leaflet-popup-content { font-size: 13px; line-height: 1.5; min-width: 180px; }
  .leaflet-popup-content strong { color: var(--accent); }
  .popup-hss { color: var(--warn); font-weight: 600; margin-top: 4px; }
  .popup-link { color: var(--accent); text-decoration: none; font-size: 12px; }
  /* Dark-mode overrides for Leaflet popups + map legend. */
  html[data-theme="dark"] .leaflet-popup-content-wrapper { background: var(--panel); color: var(--ink); }
  html[data-theme="dark"] .leaflet-popup-tip { background: var(--panel); }
  html[data-theme="dark"] .leaflet-popup-close-button { color: var(--muted); }
  html[data-theme="dark"] .map-legend { background: var(--panel); border-color: var(--border); }
  html[data-theme="dark"] .map-legend-item:hover { background: rgba(255,255,255,0.06); }

  /* Coverage */
  #coverage-summary .kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 20px; }
  #coverage-summary .kpi { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; }
  #coverage-summary .kpi .lbl { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 600; margin-bottom: 4px; }
  #coverage-summary .kpi .val { font-family: var(--serif); font-size: 28px; font-weight: 600; font-variant-numeric: tabular-nums; }
  #coverage-tab table { width: 100%; border-collapse: collapse; font-size: 13px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
  #coverage-tab th, #coverage-tab td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); }
  #coverage-tab th { background: var(--chip-bg); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
  .status-ok { color: var(--good); }
  .status-err { color: var(--alarm); }
  .status-no { color: var(--muted); }

  /* Vacancy data */
  /* Single narrative column for the entire Gap tab — centered within
     the 1080px main. The 880px column matches what the inner blocks
     (act-header, act-deck, jbm-card, hero-stat-strip, gap-bibliography,
     vacancies-appendix) cap themselves at, so everything aligns to the
     same edges. */
  #vacancies-tab { max-width: 880px; margin-left: auto; margin-right: auto; }
  /* Listings tab uses the same narrative column — narrower job cards
     centered within main, matching The Gap tab's column. The filter
     strip, vacancy-gap line, summary row, heuristic banner, and the
     listing cards all sit inside this 880px frame. */
  #listings-tab { max-width: 880px; margin-left: auto; margin-right: auto; }
  /* H3 section headers on Vacancies tab carry a red left bar — these
     are arguments, not just navigation, and the visual register says so. */
  #vacancies-tab h3 { font-family: var(--serif); font-weight: 700; font-size: 19px; margin: 24px 0 10px; padding: 4px 0 4px 14px; border-left: 4px solid var(--alarm); }
  #vacancies-tab .vac-intro { font-size: 13px; color: var(--muted); line-height: 1.6; margin-bottom: 16px; }
  #vacancies-tab .vac-footnote { background: #fff8e7; border: 1px solid #f0d98e; border-radius: 8px; padding: 12px 14px; font-size: 12.5px; color: #5c4a1a; line-height: 1.55; margin: 14px 0 22px; }
  #vacancies-tab .vac-footnote strong { color: #3d3108; }
  #vacancies-tab .vac-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); margin-bottom: 18px; }
  #vacancies-tab .vac-table-scroll::-webkit-scrollbar { height: 8px; }
  #vacancies-tab .vac-table-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
  #vacancies-tab table.vac { width: 100%; min-width: 920px; border-collapse: collapse; font-size: 12px; font-variant-numeric: tabular-nums; }
  #vacancies-tab table.vac th, #vacancies-tab table.vac td { text-align: right; padding: 7px 9px; border-bottom: 1px solid var(--border); white-space: nowrap; }
  #vacancies-tab table.vac td:first-child, #vacancies-tab table.vac th:first-child { position: sticky; left: 0; background: var(--panel); z-index: 1; box-shadow: 1px 0 0 var(--border); }
  #vacancies-tab table.vac th:first-child { background: var(--chip-bg); }
  #vacancies-tab table.vac th:first-child, #vacancies-tab table.vac td:first-child { text-align: left; }
  #vacancies-tab table.vac th { background: var(--chip-bg); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
  #vacancies-tab table.vac .ews-marker { font-size: 10px; color: #a6802a; margin-left: 3px; cursor: help; }
  #vacancies-tab table.vac .refused { color: var(--muted); font-style: italic; font-size: 12px; }
  #vacancies-tab .vac-card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 18px 22px; margin-bottom: 14px; }
  #vacancies-tab .vac-card .vac-hdr { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
  #vacancies-tab .vac-card h4 { font-family: var(--serif); font-weight: 600; font-size: 16px; margin: 0; }
  #vacancies-tab .vac-card h4 .grain-tag { font-family: var(--sans); font-weight: 500; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); background: var(--chip-bg); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px; margin-left: 8px; vertical-align: middle; }
  #vacancies-tab .vac-card .vac-meta { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
  #vacancies-tab .vac-card .vac-src { font-size: 12px; color: var(--muted); margin-top: 8px; }
  #vacancies-tab .vac-card .vac-src a { color: var(--accent); text-decoration: none; }
  #vacancies-tab .vac-card .vac-notes { font-size: 12px; color: var(--muted); margin-top: 8px; font-style: italic; line-height: 1.5; }
  #vacancies-tab .disclosure-warning { background: #fdf2f2; border: 1px solid #f5c5c5; border-left: 3px solid #c44; border-radius: 8px; padding: 14px 16px; font-size: 13px; color: #6b2020; line-height: 1.6; margin: 18px 0; }

  /* Inequality educational viz */
  #vacancies-tab .ineq-section { margin: 28px 0; }
  #vacancies-tab .ineq-section h3 { margin-top: 0; }
  #vacancies-tab .ineq-lede { font-family: var(--serif); font-size: 17px; line-height: 1.55; color: var(--ink); margin: 4px 0 18px; }
  #vacancies-tab .ineq-lede strong { color: var(--alarm); font-weight: 700; }
  #vacancies-tab .viz-card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 20px 24px; margin-bottom: 18px; }
  #vacancies-tab .viz-card .viz-hdr { font-family: var(--serif); font-weight: 600; font-size: 15px; margin: 0 0 4px; }
  #vacancies-tab .viz-card .viz-sub { font-size: 12px; color: var(--muted); margin-bottom: 16px; line-height: 1.5; }
  #vacancies-tab .viz-card .viz-source { font-size: 11px; color: var(--muted); margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border); }
  #vacancies-tab .viz-card .viz-source a { color: var(--accent); text-decoration: none; }
  /* Vacancy-rate horizontal bar chart */
  #vacancies-tab .vrbar-row { display: grid; grid-template-columns: 56px 1fr 64px; align-items: center; gap: 10px; margin: 6px 0; font-size: 13px; }
  #vacancies-tab .vrbar-cat { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
  #vacancies-tab .vrbar-track { position: relative; height: 22px; background: var(--chip-bg); border-radius: 4px; overflow: hidden; }
  #vacancies-tab .vrbar-fill { height: 100%; border-radius: 4px; transition: width 0.4s ease; }
  #vacancies-tab .vrbar-fill.cat-GEN { background: linear-gradient(90deg, #5b8bbf, #4a7aa8); }
  #vacancies-tab .vrbar-fill.cat-SC  { background: linear-gradient(90deg, #c97a4a, #b46438); }
  #vacancies-tab .vrbar-fill.cat-ST  { background: linear-gradient(90deg, #c44, #a32626); }
  #vacancies-tab .vrbar-fill.cat-OBC { background: linear-gradient(90deg, #d4a347, #b88a2e); }
  #vacancies-tab .vrbar-baseline { position: absolute; top: -2px; bottom: -2px; width: 1.5px; background: var(--ink); opacity: 0.4; pointer-events: none; }
  #vacancies-tab .vrbar-baseline-lbl { font-size: 10px; color: var(--muted); margin-top: 2px; padding-left: 66px; font-style: italic; }
  #vacancies-tab .vrbar-pct { text-align: right; font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ink); font-weight: 600; }
  #vacancies-tab .vrbar-pct .raw { display: block; font-size: 10.5px; color: var(--muted); font-weight: 400; margin-top: 1px; }
  /* Realisation index: dot-on-rail */
  #vacancies-tab .real-row { display: grid; grid-template-columns: 90px 1fr 50px; align-items: center; gap: 12px; margin: 10px 0; font-size: 13px; }
  #vacancies-tab .real-cat { font-weight: 600; }
  #vacancies-tab .real-rail { position: relative; height: 8px; background: var(--chip-bg); border-radius: 4px; }
  #vacancies-tab .real-mark { position: absolute; top: -3px; bottom: -3px; width: 14px; border-radius: 7px; transition: left 0.4s ease; }
  #vacancies-tab .real-target-line { position: absolute; top: -6px; bottom: -6px; left: 100%; width: 2px; background: var(--ink); opacity: 0.5; transform: translateX(-1px); }
  #vacancies-tab .real-target-lbl { position: absolute; top: -22px; right: -22px; font-size: 10px; color: var(--muted); white-space: nowrap; font-style: italic; }
  #vacancies-tab .real-val { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
  #vacancies-tab .real-val.under { color: var(--alarm); }
  /* Two-column layout for paired snapshots */
  #vacancies-tab .ineq-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  @media (max-width: 760px) { #vacancies-tab .ineq-grid { grid-template-columns: 1fr; } }
  /* Prose explainer blocks */
  #vacancies-tab .explain-block { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 18px 22px; margin-bottom: 14px; }
  #vacancies-tab .explain-block h4 { font-family: var(--serif); font-weight: 600; font-size: 15px; margin: 0 0 12px; color: var(--ink); }
  #vacancies-tab .explain-block p { font-size: 13.5px; line-height: 1.6; color: var(--ink); margin: 12px 0 0; }
  #vacancies-tab .explain-block p:last-child { margin-bottom: 0; }
  #vacancies-tab .explain-block .caption { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin-top: 12px; font-style: italic; }
  #vacancies-tab .explain-block .cite { font-size: 11.5px; color: var(--muted); }

  /* Concept diagram (sanctioned = in-pos + vacant; what we cannot see) */
  #vacancies-tab .concept-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 22px; align-items: start; }
  @media (max-width: 720px) { #vacancies-tab .concept-grid { grid-template-columns: 1fr; } }
  #vacancies-tab .concept-bar { font-size: 12px; }
  #vacancies-tab .concept-bar .lbl { color: var(--muted); margin-bottom: 4px; font-weight: 600; text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em; }
  #vacancies-tab .concept-bar .stack { display: flex; height: 32px; border-radius: 5px; overflow: hidden; border: 1px solid var(--border); margin-bottom: 4px; }
  #vacancies-tab .concept-bar .seg-inp { background: #4a7aa8; color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; }
  #vacancies-tab .concept-bar .seg-vac { background: #c97a4a; color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; }
  #vacancies-tab .concept-bar .stack-key { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); }
  #vacancies-tab .concept-blind { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
  #vacancies-tab .concept-blind .blind { background: var(--chip-bg); border: 1px dashed var(--border); border-radius: 4px; padding: 8px 10px; font-size: 11.5px; color: var(--ink); line-height: 1.4; }
  #vacancies-tab .concept-blind .blind strong { display: block; color: var(--alarm); font-weight: 700; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px; }

  /* Timeline (13-point roster) */
  #vacancies-tab .timeline { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; padding: 8px 0 0; margin-top: 4px; }
  @media (max-width: 720px) { #vacancies-tab .timeline { grid-template-columns: repeat(2, 1fr); gap: 16px 0; } }
  #vacancies-tab .timeline::before { content: ""; position: absolute; top: 18px; left: 16%; right: 16%; height: 2px; background: var(--border); }
  #vacancies-tab .timeline-node { padding: 0 14px; position: relative; }
  #vacancies-tab .timeline-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--accent); margin: 12px auto 14px; position: relative; z-index: 1; box-shadow: 0 0 0 4px var(--panel); }
  #vacancies-tab .timeline-node.harm .timeline-dot { background: var(--alarm); }
  #vacancies-tab .timeline-date { font-family: var(--mono); font-size: 11px; color: var(--muted); text-align: center; margin-bottom: 4px; font-weight: 600; }
  #vacancies-tab .timeline-title { font-weight: 600; font-size: 12.5px; text-align: center; margin-bottom: 4px; color: var(--ink); }
  #vacancies-tab .timeline-body { font-size: 11.5px; color: var(--muted); text-align: center; line-height: 1.45; }

  /* Side-by-side stacked bars (EWS redistribution) */
  #vacancies-tab .ews-bars { display: grid; gap: 14px; margin-top: 4px; }
  #vacancies-tab .ews-row { display: grid; grid-template-columns: 110px 1fr; gap: 12px; align-items: center; }
  #vacancies-tab .ews-row .ews-label { font-size: 11.5px; color: var(--muted); font-weight: 600; }
  #vacancies-tab .ews-row .ews-label .yr { display: block; font-size: 10px; font-weight: 400; margin-top: 1px; }
  #vacancies-tab .ews-stack { display: flex; height: 30px; border-radius: 5px; overflow: hidden; border: 1px solid var(--border); }
  #vacancies-tab .ews-seg { display: flex; align-items: center; justify-content: center; font-size: 10.5px; color: white; font-weight: 700; min-width: 0; }
  #vacancies-tab .seg-GEN  { background: #6b8aab; }
  #vacancies-tab .seg-EWS  { background: #2a4a6e; border-left: 2px solid #fff3; }
  #vacancies-tab .seg-OBC  { background: #b88a2e; }
  #vacancies-tab .seg-SC   { background: #b46438; }
  #vacancies-tab .seg-ST   { background: #a32626; }
  #vacancies-tab .ews-callout { font-size: 11.5px; color: var(--alarm); margin-top: 4px; padding: 6px 10px; background: #fdf2f2; border-left: 3px solid var(--alarm); border-radius: 0 4px 4px 0; line-height: 1.5; }

  /* Gap chart (PwBD) */
  #vacancies-tab .gap-chart { display: grid; gap: 8px; max-width: 540px; margin-top: 4px; }
  #vacancies-tab .gap-row { display: grid; grid-template-columns: 110px 1fr 80px; gap: 10px; align-items: center; }
  #vacancies-tab .gap-label { font-size: 12px; font-weight: 600; }
  #vacancies-tab .gap-track { position: relative; height: 22px; background: var(--chip-bg); border-radius: 4px; }
  #vacancies-tab .gap-fill-mandate { background: linear-gradient(90deg, #6b8aab, #4a7aa8); height: 100%; border-radius: 4px; }
  #vacancies-tab .gap-fill-actual { background: linear-gradient(90deg, #c44, #a32626); height: 100%; border-radius: 4px; }
  #vacancies-tab .gap-pct { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px; text-align: right; }
  #vacancies-tab .gap-pct.under { color: var(--alarm); }

  /* Contract schematic */
  #vacancies-tab .contract-schema { display: grid; grid-template-columns: 1fr 1fr; gap: 0; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-top: 4px; }
  #vacancies-tab .contract-col { padding: 14px 16px; }
  #vacancies-tab .contract-col.protected { background: rgba(74, 122, 168, 0.08); border-right: 1px solid var(--border); }
  #vacancies-tab .contract-col.exempt { background: rgba(196, 68, 68, 0.06); }
  #vacancies-tab .contract-col h5 { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.05em; margin: 0 0 4px; font-weight: 700; }
  #vacancies-tab .contract-col.protected h5 { color: #4a7aa8; }
  #vacancies-tab .contract-col.exempt h5 { color: var(--alarm); }
  #vacancies-tab .contract-col .body { font-size: 12px; color: var(--ink); line-height: 1.5; margin-bottom: 8px; }
  #vacancies-tab .contract-col .meta { font-size: 11px; color: var(--muted); font-style: italic; }
  #vacancies-tab .contract-arrow { text-align: center; font-size: 12px; color: var(--alarm); margin: 8px 0; padding: 6px 10px; background: var(--chip-bg); border-radius: 4px; }
  /* References */
  #vacancies-tab .references { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--border); }
  #vacancies-tab .references h3 { font-family: var(--serif); font-weight: 600; font-size: 15px; margin: 0 0 12px; }
  #vacancies-tab .references ul { list-style: none; padding: 0; margin: 0; }
  #vacancies-tab .references li { font-size: 12.5px; line-height: 1.55; color: var(--muted); margin-bottom: 8px; padding-left: 1.5em; text-indent: -1.5em; }
  #vacancies-tab .references li em { font-style: italic; }
  /* No-disclosure snapshot card — visually distinct from data cards.
     Striped/dashed styling makes the absence legible as the finding it is. */
  #vacancies-tab .vac-card-nodata { border: 1.5px dashed var(--alarm); background: rgba(200,16,46,0.04); }
  #vacancies-tab .vac-card-nodata h4 { color: var(--alarm); }
  #vacancies-tab .vac-card-nodata .vac-meta { color: var(--alarm); font-weight: 700; }
  #vacancies-tab .vac-card-nodata .nodata-body { font-size: 13.5px; line-height: 1.6; color: var(--ink); padding: 8px 0 4px; }

  /* ============================================================
     LS-corpus visualisations (added when the 25 Lok Sabha PDFs
     were analysed). All sit inside .viz-card so they inherit the
     same panel styling as the existing inequality blocks.
     ============================================================ */

  /* Time series: vacancy stays roughly flat 2024–2025 (CU) */
  #vacancies-tab .timeseries { display: grid; grid-template-columns: 60px 1fr; gap: 8px; }
  #vacancies-tab .ts-y-axis { font-size: 10px; color: var(--muted); display: flex; flex-direction: column; justify-content: space-between; padding: 6px 0 18px; text-align: right; font-variant-numeric: tabular-nums; }
  #vacancies-tab .ts-plot { position: relative; height: 200px; border-bottom: 1.5px solid var(--border); border-left: 1.5px solid var(--border); padding: 4px 0; }
  #vacancies-tab .ts-grid-line { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--border); opacity: 0.5; pointer-events: none; }
  #vacancies-tab .ts-bar { position: absolute; bottom: 0; width: 70px; background: linear-gradient(180deg, var(--accent), var(--accent-deep)); border-radius: 3px 3px 0 0; transition: height 0.4s ease; box-shadow: 0 -1px 0 rgba(255,255,255,0.2) inset; }
  #vacancies-tab .ts-bar.disclosure-loss { background: linear-gradient(180deg, #6f6c64, #4a4842); }
  #vacancies-tab .ts-bar-label { position: absolute; top: -22px; left: 0; right: 0; text-align: center; font-size: 11.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
  #vacancies-tab .ts-x-axis { position: absolute; bottom: -22px; left: 0; right: 0; display: flex; justify-content: space-around; font-size: 10.5px; color: var(--muted); }
  #vacancies-tab .ts-x-tick { width: 70px; text-align: center; }

  /* Mission Mode realisation: horizontal bars, mandate line, achieved fill */
  #vacancies-tab .mm-row { display: grid; grid-template-columns: 70px 1fr 78px; align-items: center; gap: 12px; margin: 10px 0; }
  #vacancies-tab .mm-cat { font-weight: 700; font-size: 13px; }
  #vacancies-tab .mm-track { position: relative; height: 26px; background: var(--chip-bg); border-radius: 4px; overflow: visible; }
  #vacancies-tab .mm-fill-mandate { position: absolute; top: 0; bottom: 0; left: 0; background: rgba(31,58,138,0.12); border-right: 2px dashed var(--accent); border-radius: 4px 0 0 4px; }
  #vacancies-tab .mm-fill-actual { position: absolute; top: 3px; bottom: 3px; left: 0; background: linear-gradient(90deg, var(--accent), var(--accent-deep)); border-radius: 3px; }
  #vacancies-tab .mm-fill-actual.under { background: linear-gradient(90deg, #c97a4a, #b46438); }
  #vacancies-tab .mm-fill-actual.severe { background: linear-gradient(90deg, var(--alarm), #931020); }
  #vacancies-tab .mm-fill-actual.over { background: linear-gradient(90deg, #6c6c6c, #444); }
  #vacancies-tab .mm-mandate-label { position: absolute; top: -16px; font-size: 10px; color: var(--accent); font-weight: 700; transform: translateX(-50%); white-space: nowrap; }
  #vacancies-tab .mm-pct { text-align: right; font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; }
  #vacancies-tab .mm-pct .mm-real { display: block; font-size: 10.5px; font-weight: 600; margin-top: 1px; }
  #vacancies-tab .mm-pct .mm-real.under { color: var(--warn); }
  #vacancies-tab .mm-pct .mm-real.severe { color: var(--alarm); }
  #vacancies-tab .mm-pct .mm-real.over { color: var(--muted); }

  /* Disclosure-regression matrix */
  #vacancies-tab .dr-table { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; margin-top: 4px; }
  #vacancies-tab .dr-table th, #vacancies-tab .dr-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
  #vacancies-tab .dr-table th { background: var(--chip-bg); font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
  #vacancies-tab .dr-table td.dr-cell { text-align: center; font-weight: 700; }
  #vacancies-tab .dr-table td.dr-y { background: rgba(31,58,138,0.10); color: var(--accent); }
  #vacancies-tab .dr-table td.dr-n { background: rgba(200,16,46,0.10); color: var(--alarm); }
  #vacancies-tab .dr-table td.dr-p { background: rgba(160,96,0,0.10); color: var(--warn); }
  #vacancies-tab .dr-q { font-family: var(--mono); font-size: 11px; color: var(--muted); white-space: nowrap; }

  /* AIIMS table — sortable feel without the JS sort */
  #vacancies-tab .aiims-table { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
  #vacancies-tab .aiims-table th, #vacancies-tab .aiims-table td { padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: right; }
  #vacancies-tab .aiims-table th:first-child, #vacancies-tab .aiims-table td:first-child { text-align: left; }
  #vacancies-tab .aiims-table th { background: var(--chip-bg); font-weight: 700; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
  #vacancies-tab .aiims-table tr.severe td { background: rgba(200,16,46,0.06); }
  #vacancies-tab .aiims-table tr.severe td:first-child { color: var(--alarm); font-weight: 700; }
  #vacancies-tab .aiims-table .vrate { font-weight: 700; }
  #vacancies-tab .aiims-table .vrate.severe { color: var(--alarm); }
  #vacancies-tab .aiims-table .vrate.high { color: var(--warn); }

  /* ----- new viz types: donut, RD comparison, pipeline, pyramid, ticker ----- */
  /* SVG donut */
  #vacancies-tab .donut-wrap { display: grid; grid-template-columns: 280px 1fr; gap: 24px; align-items: center; }
  @media (max-width: 720px) { #vacancies-tab .donut-wrap { grid-template-columns: 1fr; } }
  #vacancies-tab .donut-svg { width: 280px; height: 280px; display: block; margin: 0 auto; }
  #vacancies-tab .donut-center { fill: var(--ink); font-family: var(--serif); font-weight: 700; }
  #vacancies-tab .donut-center-label { fill: var(--muted); font-size: 11px; }
  #vacancies-tab .donut-legend { display: flex; flex-direction: column; gap: 6px; font-size: 13px; font-variant-numeric: tabular-nums; }
  #vacancies-tab .donut-legend .row { display: grid; grid-template-columns: 14px 60px 1fr auto; gap: 8px; align-items: center; }
  #vacancies-tab .donut-legend .swatch { width: 14px; height: 14px; border-radius: 3px; }
  #vacancies-tab .donut-legend .cat { font-weight: 700; }
  #vacancies-tab .donut-legend .gap { color: var(--muted); font-style: italic; font-size: 12px; }
  #vacancies-tab .donut-legend .gap.under { color: var(--alarm); }
  #vacancies-tab .donut-legend .gap.over { color: var(--warn); font-weight: 600; }

  /* R&D comparison strip */
  #vacancies-tab .rd-strip { display: grid; gap: 10px; }
  #vacancies-tab .rd-row { display: grid; grid-template-columns: 90px 1fr 90px; gap: 12px; align-items: center; font-size: 13px; }
  #vacancies-tab .rd-country { font-weight: 700; }
  #vacancies-tab .rd-bar-track { background: var(--chip-bg); height: 22px; border-radius: 4px; position: relative; overflow: hidden; }
  #vacancies-tab .rd-bar-fill { height: 100%; border-radius: 4px; }
  #vacancies-tab .rd-pct { font-variant-numeric: tabular-nums; font-weight: 700; text-align: right; }
  #vacancies-tab .rd-row.india .rd-bar-fill { background: linear-gradient(90deg, var(--alarm), #931020); }
  #vacancies-tab .rd-row.india .rd-pct { color: var(--alarm); }
  #vacancies-tab .rd-row:not(.india) .rd-bar-fill { background: linear-gradient(90deg, var(--accent), var(--accent-deep)); opacity: 0.7; }

  /* Talent pipeline (CSS Sankey-ish) */
  #vacancies-tab .pipeline { display: grid; grid-template-columns: 1fr 36px 1fr 36px 1fr; gap: 0; align-items: stretch; margin-top: 8px; }
  #vacancies-tab .pipe-stage { background: var(--chip-bg); border: 1.5px solid var(--border); border-radius: 8px; padding: 14px 14px; text-align: center; min-height: 130px; display: flex; flex-direction: column; justify-content: center; }
  #vacancies-tab .pipe-stage .pipe-num { font-family: var(--serif); font-weight: 700; font-size: 26px; color: var(--ink); display: block; margin-bottom: 2px; line-height: 1.1; }
  #vacancies-tab .pipe-stage .pipe-num-sub { font-size: 11px; color: var(--muted); }
  #vacancies-tab .pipe-stage .pipe-label { font-size: 12px; font-weight: 700; color: var(--ink); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.04em; }
  #vacancies-tab .pipe-stage .pipe-note { font-size: 11.5px; color: var(--muted); line-height: 1.4; margin-top: 6px; }
  #vacancies-tab .pipe-stage.leak { border-left: 4px solid var(--alarm); background: rgba(200,16,46,0.04); }
  #vacancies-tab .pipe-stage.input { border-left: 4px solid var(--accent); }
  #vacancies-tab .pipe-arrow { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 22px; }
  #vacancies-tab .pipe-leak-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-top: 12px; font-size: 11.5px; color: var(--muted); }
  #vacancies-tab .pipe-leak-row .leak-arrow { text-align: center; color: var(--alarm); font-weight: 700; }
  @media (max-width: 720px) { #vacancies-tab .pipeline { grid-template-columns: 1fr; gap: 6px; } #vacancies-tab .pipe-arrow { transform: rotate(90deg); padding: 4px 0; } }

  /* Caste rank pyramid */
  #vacancies-tab .pyramid { display: grid; gap: 6px; max-width: 640px; margin: 8px auto 0; }
  #vacancies-tab .pyr-row { display: grid; grid-template-columns: 130px 1fr 70px; gap: 10px; align-items: center; }
  #vacancies-tab .pyr-rank { font-weight: 700; font-size: 13px; text-align: right; }
  #vacancies-tab .pyr-bar { display: flex; height: 30px; border-radius: 4px; overflow: hidden; border: 1px solid var(--border); }
  #vacancies-tab .pyr-seg { display: flex; align-items: center; justify-content: center; font-size: 10.5px; color: white; font-weight: 700; min-width: 0; }
  #vacancies-tab .pyr-seg.gen { background: #6b6b6b; }
  #vacancies-tab .pyr-seg.obc { background: #b88a2e; }
  #vacancies-tab .pyr-seg.sc { background: #b46438; }
  #vacancies-tab .pyr-seg.st { background: #a32626; }
  #vacancies-tab .pyr-total { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 12px; }
  #vacancies-tab .pyr-legend { display: flex; gap: 16px; justify-content: center; margin-top: 12px; font-size: 11.5px; color: var(--muted); }
  #vacancies-tab .pyr-legend .lswatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; vertical-align: middle; margin-right: 4px; }

  /* ============================================================
     UNIFIED JBM CHART SYSTEM
     One visual language. One color discipline. One typographic scale.
     Every chart on the Vacancies page uses these primitives.
     ============================================================ */
  #vacancies-tab .jbm-card { background: var(--panel); border: 1px solid var(--border); padding: 24px 28px 22px; margin-bottom: 24px; }
  #vacancies-tab .jbm-card .jbm-title { font-family: var(--serif); font-size: 19px; font-weight: 700; color: var(--ink); line-height: 1.32; letter-spacing: -0.005em; margin: 0 0 6px; max-width: 720px; }
  #vacancies-tab .jbm-card .jbm-deck { font-family: var(--sans, "Inter"); font-size: 13px; color: var(--muted); line-height: 1.5; margin: 0 0 18px; max-width: 720px; }
  #vacancies-tab .jbm-card .jbm-chart { margin: 4px 0; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 8px; }
  #vacancies-tab .jbm-card .jbm-source { font-family: var(--sans, "Inter"); font-size: 11px; color: var(--muted); font-style: italic; line-height: 1.5; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); max-width: 720px; }
  #vacancies-tab .jbm-card .jbm-source strong { font-style: normal; color: var(--ink); font-weight: 700; }
  /* JBM color discipline:
       --jbm-emph    : ONE accent for what the chart is making you look at
       --jbm-context : muted grey for everything else
       --jbm-promise : Ambedkar cobalt for what was promised by statute
       --jbm-grid    : barely-there gridline grey
   */
  #vacancies-tab .jbm-card { --jbm-emph: var(--alarm); --jbm-context: #b3b1a6; --jbm-promise: var(--accent); --jbm-grid: rgba(0,0,0,0.08); }
  html[data-theme="dark"] #vacancies-tab .jbm-card { --jbm-grid: rgba(255,255,255,0.10); }
  /* Standard SVG primitives (apply within .jbm-card) */
  /* `height: auto` is defensive: modern browsers compute it from
     viewBox aspect-ratio when only width is set, but some Android
     WebView versions and older mobile Safari render the SVG at its
     intrinsic 760×H instead. Explicit `height: auto` guards both. */
  #vacancies-tab .jbm-card svg.jbm-svg { width: 100%; max-width: 760px; min-width: 600px; height: auto; display: block; overflow: visible; font-family: var(--sans, "Inter"); }
  #vacancies-tab .jbm-card svg.jbm-svg .grid-y, #vacancies-tab .jbm-card svg.jbm-svg .grid-x { stroke: var(--jbm-grid); stroke-width: 1; }
  #vacancies-tab .jbm-card svg.jbm-svg .axis-label { font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
  #vacancies-tab .jbm-card svg.jbm-svg .axis-label.bold { font-weight: 700; fill: var(--ink); }
  #vacancies-tab .jbm-card svg.jbm-svg .axis-title { font-size: 10.5px; fill: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
  #vacancies-tab .jbm-card svg.jbm-svg .data-label { font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
  #vacancies-tab .jbm-card svg.jbm-svg .data-label.emph { fill: var(--jbm-emph); }
  #vacancies-tab .jbm-card svg.jbm-svg .data-label.context { fill: var(--muted); font-weight: 500; }
  #vacancies-tab .jbm-card svg.jbm-svg .anno-line { stroke: var(--jbm-emph); stroke-width: 1.25; fill: none; }
  #vacancies-tab .jbm-card svg.jbm-svg .anno-text { font-size: 11.5px; fill: var(--ink); }
  #vacancies-tab .jbm-card svg.jbm-svg .anno-text.emph { fill: var(--jbm-emph); font-weight: 700; }
  #vacancies-tab .jbm-card svg.jbm-svg .bar-emph { fill: var(--jbm-emph); }
  #vacancies-tab .jbm-card svg.jbm-svg .bar-context { fill: var(--jbm-context); }
  #vacancies-tab .jbm-card svg.jbm-svg .bar-promise { fill: var(--jbm-promise); }
  #vacancies-tab .jbm-card svg.jbm-svg .ref-line { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 4,3; opacity: 0.6; }

  /* JBM-standard SVG line chart for time series */
  #vacancies-tab .line-svg { width: 100%; max-width: 760px; min-width: 600px; height: auto; aspect-ratio: 760/360; display: block; margin: 4px 0 8px; overflow: visible; font-family: var(--sans, "Inter"); }
  #vacancies-tab .line-svg .grid { stroke: var(--border); stroke-width: 1; }
  #vacancies-tab .line-svg .axis-num { font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
  #vacancies-tab .line-svg .axis-label-x { font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
  #vacancies-tab .line-svg .axis-y-title { font-size: 10.5px; fill: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
  #vacancies-tab .line-svg .line-disclosed { stroke: var(--accent); stroke-width: 2.5; fill: none; }
  #vacancies-tab .line-svg .line-withheld  { stroke: var(--alarm);  stroke-width: 2.5; fill: none; }
  #vacancies-tab .line-svg .dot { stroke: white; stroke-width: 2; }
  #vacancies-tab .line-svg .dot.disclosed { fill: var(--accent); }
  #vacancies-tab .line-svg .dot.withheld  { fill: var(--alarm); }
  #vacancies-tab .line-svg .dot-label { font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
  #vacancies-tab .line-svg .dot-label.disclosed { fill: var(--accent); }
  #vacancies-tab .line-svg .dot-label.withheld  { fill: var(--alarm); }
  #vacancies-tab .line-svg .seg-label { font-size: 11.5px; font-weight: 600; }
  #vacancies-tab .line-svg .seg-label.disclosed { fill: var(--accent); }
  #vacancies-tab .line-svg .seg-label.withheld  { fill: var(--alarm); }
  #vacancies-tab .line-svg .anno-line { stroke: var(--ink); stroke-width: 1; opacity: 0.5; fill: none; }
  #vacancies-tab .line-svg .anno-text { font-size: 11.5px; fill: var(--ink); }
  #vacancies-tab .line-svg .anno-text.bold { font-weight: 700; fill: var(--alarm); }

  /* JBM-style ranked horizontal bar chart for AIIMS / institutions */
  #vacancies-tab .ranked-bars { display: grid; gap: 4px; max-width: 760px; margin: 12px 0 8px; font-family: var(--sans, "Inter"); }
  #vacancies-tab .rb-row { display: grid; grid-template-columns: 170px 1fr 60px; gap: 12px; align-items: center; padding: 4px 0; font-size: 12.5px; }
  #vacancies-tab .rb-row.severe { background: rgba(200,16,46,0.05); border-left: 3px solid var(--alarm); padding-left: 8px; margin-left: -11px; }
  #vacancies-tab .rb-row .rb-name { font-weight: 600; }
  #vacancies-tab .rb-row.severe .rb-name { color: var(--alarm); font-weight: 700; }
  #vacancies-tab .rb-row .rb-bar-track { height: 18px; background: transparent; position: relative; }
  #vacancies-tab .rb-row .rb-bar-fill { height: 100%; border-radius: 2px; }
  #vacancies-tab .rb-row .rb-bar-fill.severe { background: var(--alarm); }
  #vacancies-tab .rb-row .rb-bar-fill.high   { background: #c97a4a; }
  #vacancies-tab .rb-row .rb-bar-fill.normal { background: #b3b1a6; }
  #vacancies-tab .rb-row .rb-pct { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
  #vacancies-tab .rb-row.severe .rb-pct { color: var(--alarm); }
  #vacancies-tab .rb-row .rb-pct.high { color: #b46438; }
  #vacancies-tab .rb-axis { display: grid; grid-template-columns: 170px 1fr 60px; gap: 12px; font-size: 10.5px; color: var(--muted); margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border); }
  #vacancies-tab .rb-axis-ticks { display: flex; justify-content: space-between; }

  /* MPs bar chart by state */
  #vacancies-tab .mp-state-chart { display: grid; gap: 6px; max-width: 600px; margin: 8px 0; }
  #vacancies-tab .mp-state-row { display: grid; grid-template-columns: 110px 1fr 30px; gap: 12px; align-items: center; font-size: 12.5px; }
  #vacancies-tab .mp-state-row .mp-state-name { font-weight: 600; text-align: right; }
  #vacancies-tab .mp-state-row .mp-state-bar { height: 22px; background: var(--accent); border-radius: 2px; }
  #vacancies-tab .mp-state-row .mp-state-count { font-variant-numeric: tabular-nums; font-weight: 700; }
  #vacancies-tab .mp-state-row.muted .mp-state-bar { background: #b3b1a6; }
  #vacancies-tab .mp-state-row.muted { color: var(--muted); }

  /* Burn-Murdoch slope chart: mandate (left) → actual share (right).
     Lines that slope down = categories under-realised. One outlier in
     saturated red, others in muted neutral. */
  #vacancies-tab .slope-card { padding: 24px 28px; }
  #vacancies-tab .slope-svg { width: 100%; max-width: 760px; min-width: 600px; height: 320px; display: block; margin: 8px 0; overflow: visible; }
  #vacancies-tab .slope-svg .grid { stroke: var(--border); stroke-dasharray: 2,3; }
  #vacancies-tab .slope-svg .axis-label { font-size: 11px; fill: var(--muted); font-family: var(--sans, "Inter"); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
  #vacancies-tab .slope-svg .col-label { font-size: 13px; fill: var(--ink); font-weight: 700; }
  #vacancies-tab .slope-svg .col-sub { font-size: 11px; fill: var(--muted); }
  #vacancies-tab .slope-svg .line { stroke-width: 2; fill: none; }
  #vacancies-tab .slope-svg .line.muted { stroke: #c5c2b8; }
  #vacancies-tab .slope-svg .line.outlier-red { stroke: var(--alarm); stroke-width: 3; }
  #vacancies-tab .slope-svg .line.outlier-orange { stroke: #c97a4a; stroke-width: 2.5; }
  #vacancies-tab .slope-svg .line.gain { stroke: #6b6b6b; stroke-width: 2; }
  #vacancies-tab .slope-svg .point { stroke-width: 0; }
  #vacancies-tab .slope-svg .point.muted { fill: #c5c2b8; }
  #vacancies-tab .slope-svg .point.outlier-red { fill: var(--alarm); }
  #vacancies-tab .slope-svg .point.outlier-orange { fill: #c97a4a; }
  #vacancies-tab .slope-svg .point.gain { fill: #6b6b6b; }
  #vacancies-tab .slope-svg .row-label { font-size: 12px; font-weight: 600; }
  #vacancies-tab .slope-svg .row-label.muted { fill: var(--muted); }
  #vacancies-tab .slope-svg .row-label.outlier-red { fill: var(--alarm); font-weight: 700; }
  #vacancies-tab .slope-svg .row-label.outlier-orange { fill: #b46438; font-weight: 700; }
  #vacancies-tab .slope-svg .annotation { font-size: 11.5px; font-style: italic; fill: var(--alarm); font-weight: 600; }
  #vacancies-tab .slope-svg .annotation-arrow { stroke: var(--alarm); stroke-width: 1.5; fill: none; marker-end: url(#arrowred); }
  #vacancies-tab .chart-source { font-size: 11px; color: var(--muted); font-style: italic; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
  #vacancies-tab .chart-source strong { color: var(--ink); font-style: normal; font-weight: 700; }

  /* Generic JBM-style chart annotations on top of any chart */
  #vacancies-tab .chart-anno { position: relative; }
  #vacancies-tab .anno-callout { background: rgba(200,16,46,0.92); color: #fff; padding: 4px 8px; border-radius: 4px; font-size: 11.5px; font-weight: 600; line-height: 1.3; max-width: 220px; box-shadow: 0 2px 4px rgba(0,0,0,0.15); }
  #vacancies-tab .anno-callout.cobalt { background: rgba(31,58,138,0.92); }
  #vacancies-tab .anno-callout.muted { background: rgba(95,93,87,0.92); }

  /* Hero stat — Ambedkarite grammar: an opening pretitle that sets the
     denominator, a four-cell grid of per-category withholdings, and a
     closing political claim. The hero block sits centered as a column;
     the pretitle and grid are center-aligned, the closing context
     paragraph is left-aligned (long prose) but its block centers via
     auto margins.

     Per-cell layout: small alarm-colored category label on top, a large
     serif withholding count, a thin sans-serif qualifier under it. PwD
     cell renders the count as an em-dash since the data is suppressed
     by the Ministry — the absence is itself the data point. */
  #vacancies-tab .hero-stat { background: var(--bg); border: none; padding: 32px 0 28px; border-bottom: 1px solid var(--border); margin: 0 auto 32px; max-width: 880px; text-align: center; }
  #vacancies-tab .hero-stat .hs-kicker { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--alarm); font-weight: 700; margin-bottom: 18px; }
  #vacancies-tab .hero-stat .hs-num { font-family: var(--serif); font-weight: 800; font-size: 96px; line-height: 0.95; color: var(--alarm); letter-spacing: -0.04em; display: block; font-variant-numeric: tabular-nums; }
  @media (max-width: 720px) { #vacancies-tab .hero-stat .hs-num { font-size: 64px; } }
  #vacancies-tab .hero-stat .hs-headline { font-family: var(--serif); font-size: 21px; line-height: 1.4; color: var(--ink); font-weight: 600; max-width: 720px; margin: 18px auto 0; }
  #vacancies-tab .hero-stat .hs-headline em { font-style: italic; color: var(--alarm); }

  /* In-page anchor link inside .act-deck (e.g. "Scope, sources, and
     methodology"). Cobalt with bottom-rule on hover only — the default
     <a> text-decoration is suppressed so we don't double-underline. */
  #vacancies-tab .gap-anchor-link {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid var(--accent);
  }
  #vacancies-tab .gap-anchor-link:hover {
    background: var(--accent);
    color: var(--bg);
  }

  /* Section-heading anchor — a small "#" link that appears on hover next
     to each H2/H3/appendix-summary. Click to copy a deep-link URL to the
     section, the same way GitHub's README headings do it.
     The corresponding hashchange-router enhancement in app.js routes
     /#point-3 etc. into the right tab + scrolls. */
  #vacancies-tab .heading-anchor {
    color: var(--accent);
    text-decoration: none;
    margin-left: 10px;
    font-weight: 500;
    font-size: 0.7em;
    opacity: 0;
    transition: opacity 0.18s ease;
  }
  #vacancies-tab h2:hover > .heading-anchor,
  #vacancies-tab .act-title:hover > .heading-anchor,
  #vacancies-tab .vacancies-appendix > summary:hover .heading-anchor,
  #vacancies-tab .heading-anchor:focus {
    opacity: 0.55;
  }
  #vacancies-tab .heading-anchor:hover {
    opacity: 1;
  }

  /* Sub-hero stat strip — three big numbers, rendered flush with the
     hero-stat content above (no card frame). First cell's content
     starts at x=0 of main, matching the kicker / 31% / headline edge.
     Vertical rules separate cells; thin horizontal rules contain the
     row. NYT/FT-style ruled strip, not a Bootstrap card grid. */
  #vacancies-tab .hero-stat-strip {
    display: grid; grid-template-columns: repeat(3, 1fr);
    background: transparent;
    border: none;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    gap: 0;
    margin: 0 0 32px;
  }
  @media (max-width: 720px) { #vacancies-tab .hero-stat-strip { grid-template-columns: 1fr; } }
  #vacancies-tab .hero-stat-strip .hss-cell {
    background: transparent;
    padding: 22px 18px;
    border-right: 1px solid var(--border);
    text-align: center;
  }
  #vacancies-tab .hero-stat-strip .hss-cell:last-child { border-right: none; }
  @media (max-width: 720px) {
    #vacancies-tab .hero-stat-strip .hss-cell {
      padding: 16px 0;
      border-right: none;
      border-bottom: 1px solid var(--border);
    }
    #vacancies-tab .hero-stat-strip .hss-cell:last-child { border-bottom: none; }
  }
  #vacancies-tab .hero-stat-strip .hss-num { font-family: var(--serif); font-weight: 800; font-size: 38px; line-height: 1; color: var(--alarm); display: block; letter-spacing: -0.02em; }
  #vacancies-tab .hero-stat-strip .hss-cell:nth-child(2) .hss-num { color: var(--accent); }
  #vacancies-tab .hero-stat-strip .hss-cell:nth-child(3) .hss-num { color: var(--alarm); }
  #vacancies-tab .hero-stat-strip .hss-label { font-size: 12px; color: var(--ink); margin-top: 6px; line-height: 1.45; font-weight: 500; }
  #vacancies-tab .hero-stat-strip .hss-source { font-size: 10.5px; color: var(--muted); margin-top: 4px; font-style: italic; }

  /* Reading-first: per-chart inline source/citation strips are hidden in
     the main flow and re-collected into a single bibliography at the end of
     the tab (built by renderVacancies after innerHTML is set). The original
     elements remain in the DOM so the bibliography builder can read them;
     `display: none` removes them from rendering AND from the AT tree. */
  #vacancies-tab .chart-source,
  #vacancies-tab .jbm-source,
  #vacancies-tab .hero-stat-strip .hss-source { display: none; }

  /* Both end-of-page collapsibles — appendix and bibliography — share
     a single summary treatment so they read as siblings rather than
     two unrelated sections. Same font, size, weight, padding, arrow
     glyph, hint span. */
  #vacancies-tab details.gap-bibliography,
  #vacancies-tab details.vacancies-appendix {
    margin-top: 64px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
  }
  #vacancies-tab details.gap-bibliography > summary,
  #vacancies-tab details.vacancies-appendix > summary {
    cursor: pointer;
    font-family: var(--serif);
    font-size: 22px;
    font-weight: 700;
    color: var(--ink);
    padding: 12px 0;
    list-style: none;
    letter-spacing: -0.005em;
  }
  #vacancies-tab details.gap-bibliography > summary::-webkit-details-marker,
  #vacancies-tab details.vacancies-appendix > summary::-webkit-details-marker { display: none; }
  #vacancies-tab details.gap-bibliography > summary::before,
  #vacancies-tab details.vacancies-appendix > summary::before {
    content: "▸ ";
    color: var(--accent);
    display: inline-block;
    margin-right: 4px;
    transition: transform 0.15s;
  }
  #vacancies-tab details.gap-bibliography[open] > summary::before,
  #vacancies-tab details.vacancies-appendix[open] > summary::before {
    content: "▾ ";
  }
  #vacancies-tab details.gap-bibliography .bib-summary-hint,
  #vacancies-tab details.vacancies-appendix .bib-summary-hint {
    color: var(--accent);
    font-size: 13px;
    font-weight: 500;
  }
  #vacancies-tab details.gap-bibliography[open] .bib-summary-hint,
  #vacancies-tab details.vacancies-appendix[open] .bib-summary-hint {
    display: none;
  }
  #vacancies-tab details.gap-bibliography .bib-body {
    padding-top: 18px;
  }
  #vacancies-tab details.gap-bibliography .bib-method { font-size: 14px; color: var(--ink); max-width: 760px; line-height: 1.6; margin: 0 0 20px; font-family: var(--serif); }
  #vacancies-tab details.gap-bibliography ol { font-size: 13px; color: var(--muted); max-width: 760px; line-height: 1.6; padding-left: 22px; margin: 0; font-family: var(--sans, "Inter"); }
  #vacancies-tab details.gap-bibliography ol li { margin-bottom: 10px; }
  #vacancies-tab details.gap-bibliography ol li strong { color: var(--ink); font-weight: 700; }

  /* Mobile chart polish: SVG charts and card paddings shrink to make the
     actual data area larger on small viewports. */
  @media (max-width: 640px) {
    #vacancies-tab svg { max-width: 100%; height: auto; }
    #vacancies-tab .jbm-card { padding: 16px 12px; border-radius: 8px; }
    #vacancies-tab .hs-num { font-size: 76px !important; }
    #vacancies-tab .hero-stat-strip { grid-template-columns: 1fr !important; gap: 12px !important; }
    #vacancies-tab .act-header .act-title { font-size: 20px; }
    #vacancies-tab .act-deck { font-size: 15px; line-height: 1.5; }
    /* SVG text scales WITH the SVG via viewBox; on a 320-px-wide phone
       a 760-wide chart becomes ~0.42x, so 11-px labels render at ~5px.
       Bump in-SVG font-sizes proportionally so labels stay readable. */
    #vacancies-tab .jbm-card svg.jbm-svg,
    #vacancies-tab .line-svg,
    #vacancies-tab .slope-svg {
      min-width: 560px;
    }
    #vacancies-tab .jbm-card svg.jbm-svg .axis-label,
    #vacancies-tab .line-svg .axis-num,
    #vacancies-tab .line-svg .axis-label-x,
    #vacancies-tab .slope-svg .axis-label,
    #vacancies-tab .slope-svg .col-sub {
      font-size: 14px;
    }
    #vacancies-tab .jbm-card svg.jbm-svg .axis-title,
    #vacancies-tab .line-svg .axis-y-title {
      font-size: 13px;
    }
    #vacancies-tab .jbm-card svg.jbm-svg .data-label,
    #vacancies-tab .jbm-card svg.jbm-svg .anno-text,
    #vacancies-tab .line-svg .dot-label,
    #vacancies-tab .line-svg .seg-label,
    #vacancies-tab .line-svg .anno-text,
    #vacancies-tab .slope-svg .annotation {
      font-size: 15px;
    }
    #vacancies-tab .slope-svg .row-label,
    #vacancies-tab .slope-svg .col-label {
      font-size: 15px;
    }

  }

  /* Section headers tightened */
  /* Shared narrative-column width — used by every block-level child of
     the Gap tab so the page reads as a single editorial column. Earlier
     we had act-deck at 780, jbm-card at full container width (~1032 at
     1280 viewport), and the bibliography section's border-top running
     wall-to-wall. Capping all of them to 880 produces a coherent column
     rhythm: deck, chart, deck, chart, verdict, appendix, bibliography,
     all the same edge. */
  #vacancies-tab .act-header,
  #vacancies-tab .act-deck,
  #vacancies-tab .jbm-card,
  #vacancies-tab .hero-stat-strip,
  #vacancies-tab .gap-bibliography,
  #vacancies-tab .vacancies-appendix {
    max-width: 880px;
  }
  #vacancies-tab .act-header { margin: 56px 0 8px; padding-bottom: 12px; border-bottom: 2px solid var(--alarm); display: flex; align-items: baseline; gap: 12px; }
  #vacancies-tab .act-header .act-num { font-family: var(--mono); font-size: 11px; color: var(--alarm); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
  #vacancies-tab .act-header .act-title { font-family: var(--serif); font-size: 24px; font-weight: 700; color: var(--ink); margin: 0; letter-spacing: -0.01em; }
  #vacancies-tab .act-deck { font-family: var(--serif); font-size: 17px; line-height: 1.45; color: var(--ink); font-weight: 500; margin: 0 0 18px; }
  #vacancies-tab .act-deck strong { color: var(--alarm); font-weight: 700; }

  /* Counterfactual ticker */
  #vacancies-tab .counterfactual { background: linear-gradient(135deg, rgba(31,58,138,0.08), rgba(200,16,46,0.06)); border: 1.5px solid var(--border); border-left: 5px solid var(--alarm); border-radius: 10px; padding: 20px 24px; }
  #vacancies-tab .counterfactual .cf-num { font-family: var(--serif); font-weight: 800; font-size: 36px; color: var(--alarm); display: block; line-height: 1; margin-bottom: 4px; letter-spacing: -0.02em; }
  #vacancies-tab .counterfactual .cf-label { font-size: 13px; color: var(--ink); font-weight: 600; line-height: 1.5; }
  #vacancies-tab .counterfactual .cf-bullets { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 18px; margin-top: 18px; }
  @media (max-width: 720px) { #vacancies-tab .counterfactual .cf-bullets { grid-template-columns: 1fr; } }
  #vacancies-tab .counterfactual .cf-bullet { background: rgba(255,255,255,0.5); padding: 12px 14px; border-radius: 6px; }
  #vacancies-tab .counterfactual .cf-bullet b { display: block; color: var(--alarm); font-size: 22px; font-family: var(--serif); margin-bottom: 2px; line-height: 1.1; }
  #vacancies-tab .counterfactual .cf-bullet span { font-size: 12px; color: var(--ink); line-height: 1.45; display: block; }
  html[data-theme="dark"] #vacancies-tab .counterfactual { background: linear-gradient(135deg, rgba(108,149,232,0.10), rgba(239,83,80,0.08)); }
  html[data-theme="dark"] #vacancies-tab .counterfactual .cf-bullet { background: rgba(0,0,0,0.25); }

  /* Who-is-asking MPs panel */
  #vacancies-tab .mps-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; margin-top: 6px; }
  #vacancies-tab .mp-card { background: var(--chip-bg); border-left: 3px solid var(--accent); padding: 8px 12px; border-radius: 4px; font-size: 12.5px; }
  #vacancies-tab .mp-name { font-weight: 700; color: var(--ink); display: block; line-height: 1.35; }
  #vacancies-tab .mp-aff { font-size: 11px; color: var(--muted); margin-top: 2px; display: block; }
  #vacancies-tab .mp-state { font-size: 11px; color: var(--accent); font-weight: 600; }

  /* Footer — soft top rule (no longer the heavy alarm-red stripe that
     bookended the masthead's red strip). */
  footer { max-width: 1480px; margin: 40px auto 0; padding: 24px 32px; border-top: 1px solid var(--border); font-size: 12px; color: var(--muted); line-height: 1.6; }
