/* ============================================================================
   examinationnews.4ab.in — SITE STYLESHEET
   ----------------------------------------------------------------------------
   Load order in every page's <head>:
       1. the no-flash theme script (inline, before any stylesheet)
       2. Google Fonts (Poppins + Roboto)
       3. ab-design-system.css        <- the shared package, inside @layer
       4. THIS FILE                   <- unlayered, so it can patch the package

   THIS FILE IS DELIBERATELY UNLAYERED. In the cascade any unlayered declaration
   beats any layered one, so this file can correct the two known package bugs
   (section 0) without editing the shared package — which is live on several
   other sites and must not be touched.

   Prefix for everything site-specific: `exn-`.
   Nothing here restyles a bare element that the package already owns.

   CONTENTS
     0. AB PACKAGE BUG PATCHES              <- read this first
     1. Site tokens (status inks) — all three theme states
     2. Site chrome: brand lockup, breadcrumb, skip link
     3. THE STATUS SYSTEM  .exn-st          <- the core component
     4. Fact rows          .exn-fact
     5. The verdict block  .exn-verdict     <- the one-screen answer
     6. Live strip         .exn-strip
     7. Event rail         .exn-rail
     8. Feed items         .exn-feed
     9. Vacancy entries    .exn-vac
    10. Calendar           .exn-cal
    11. Filter bar         .exn-filter
    12. Source links, data tables, notes, admin
    13. Responsive + tap-target floor
   ========================================================================== */


/* ============================================================================
   0. AB PACKAGE BUG PATCHES — both are load-bearing, do not remove
   ----------------------------------------------------------------------------
   BUG 1 — invisible call-to-action buttons.
     ab-design-system.css line ~379 declares
         .ab-base a, .ab-page a { color: var(--navy); }
     at specificity (0,1,1). Every button colour rule — `.ab-btn--gold`,
     `.ab-btn--navy`, `.ab-btn--ghost` — is only (0,1,0), so the reset WINS on
     any button that is an <a>. Result: white-labelled gradient buttons render
     in navy ink, and `--ghost` on the navy CTA panel renders navy-on-navy and
     disappears entirely.
     FIX: re-declare the same colours with the element qualified — `a.ab-btn--x`
     is (0,1,1) too, and a later equal-specificity rule wins. Unlayered here, so
     it wins regardless.
     The same reset hits four more <a> components in the package; all are
     patched below because they fail the same way.
   ========================================================================== */
a.ab-btn--gold,
a.ab-btn--navy { color: #fff; }

a.ab-btn--ghost { color: #fff; }
a.ab-btn--ghost:hover,
a.ab-btn--ghost:focus-visible { color: var(--gold-soft); }

a.ab-btn--line { color: var(--navy); }

/* .ab-credit__site, .ab-stage__link and .ab-pill--link are <a> elements whose
   colour rules are also (0,1,0) and also lose to the reset. .ab-credit sits
   OUTSIDE <main>, but it is inside <body class="ab-base">, so the reset still
   reaches it — and its gold link on the navy bar goes navy-on-navy too. */
/* Scoped inside .ab-credit so it also outranks the broader dark-panel rule
   further down THIS file — otherwise my own catch-all would silently repaint the
   credit link and the specific value here would never apply. */
.ab-credit a.ab-credit__site { color: #E9C25F; }
.ab-credit a.ab-credit__site:hover,
.ab-credit a.ab-credit__site:focus-visible { color: #F7E7B2; }

a.ab-stage__link { color: var(--gold-soft); }
a.ab-pill--link { color: var(--ink); }

/* Any anchor placed inside a permanently-dark panel needs the same treatment,
   because --navy is a THEMED token that flips to near-white in dark mode and to
   dark navy in light mode — i.e. it is wrong on a dark panel in exactly one of
   the two themes, which is how this class of bug hides. */
.ab-hero__panel a:not(.ab-btn),
.ab-cta__panel a:not(.ab-btn),
.ab-credit a { color: var(--gold-soft); }

/* --------------------------------------------------------------------------
   BUG 2 — cross-page #anchor links land at the top of the page.
     The package sets `html:has(> body.ab-base) { scroll-behavior: smooth }`.
     On a FRESH page load the browser's own scroll-to-fragment is suppressed by
     smooth scrolling and the reader lands at the top instead of at the section
     they clicked. (Same-page anchor clicks are unaffected and still glide.)
     There is no CSS fix — the correction is in site.js `fixHashLanding()`,
     which forces `scroll-behavior:auto` for exactly one scrollIntoView call on
     load and then restores whatever the page had. This declaration is the CSS
     half: it gives the JS a class to toggle so it never has to guess at or
     clobber an inline style.
   -------------------------------------------------------------------------- */
html.exn-jumping { scroll-behavior: auto !important; }

/* Anchored sections must not land under the sticky sub-nav. */
[id] { scroll-margin-top: 84px; }


/* ============================================================================
   1. SITE TOKENS — the status palette
   ----------------------------------------------------------------------------
   THE THREE-STATE CONTRACT (package §8) is followed exactly: every themed
   token is declared in bare :root (light, the default), in the media-guarded
   dark block, and in the [data-theme="dark"] block — and the two dark blocks
   are token-for-token identical. A colour whose only definition sits inside a
   dark block is the classic unreadable-page bug.

   Measured WCAG contrast of each ink (normal text needs 4.5:1):
     light on #FFFFFF   ok 5.4 : stale 4.9 : none 7.6 : held 6.6 : wait 6.7
     dark  on #050914   ok 7.8 : stale 11.3 : none 9.6 : held 6.1 : wait 7.8
   No status is carried by the raw brand --gold or --green: both fail as text
   on a light surface (2.29:1 and 1.99:1).
   ========================================================================== */
:root, .ab-page {
  /* confirmed — read from the official site on the last run */
  --exn-ok:        #177A39;
  --exn-ok-bg:     #EBFBF1;
  --exn-ok-line:   #C8EDD7;
  /* stale — we hold a real value but the last run could not re-read it */
  --exn-stale:     #8A6D1F;
  --exn-stale-bg:  #FFF8E7;
  --exn-stale-line:#EFE2BC;
  /* unconfirmed — nothing official exists yet. We claim nothing. */
  --exn-none:      #4B5563;
  --exn-none-bg:   #F4F5F7;
  --exn-none-line: #DDE1E7;
  /* held — the layout-change guard fired; publishing is deliberately stopped */
  --exn-held:      #B42318;
  --exn-held-bg:   #FEF0EF;
  --exn-held-line: #F6D2CE;
  /* waiting — a verdict, not a confidence: "announced, not yet happened" */
  --exn-wait:      #1D4ED8;
  --exn-wait-bg:   #EDF4FF;
  --exn-wait-line: #D3E2F9;

  /* the hatch used on `held` surfaces — a second, non-colour signal */
  --exn-hatch: repeating-linear-gradient(45deg,
      rgba(180, 35, 24, .10) 0 6px, transparent 6px 12px);

  --exn-mono-bg: #F4F5F7;
  --exn-sticky-bg: rgba(255, 255, 255, .92);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]), :root:not([data-theme="light"]) .ab-page {
    --exn-ok:        #10B981;
    --exn-ok-bg:     rgba(16, 185, 129, .12);
    --exn-ok-line:   rgba(16, 185, 129, .34);
    --exn-stale:     #F5B942;
    --exn-stale-bg:  rgba(245, 185, 66, .12);
    --exn-stale-line:rgba(245, 185, 66, .34);
    --exn-none:      #B9C5D8;
    --exn-none-bg:   rgba(148, 163, 184, .10);
    --exn-none-line: rgba(148, 163, 184, .26);
    --exn-held:      #FF4D5A;
    --exn-held-bg:   rgba(255, 77, 90, .12);
    --exn-held-line: rgba(255, 77, 90, .34);
    --exn-wait:      #60A5FA;
    --exn-wait-bg:   rgba(96, 165, 250, .12);
    --exn-wait-line: rgba(96, 165, 250, .32);

    --exn-hatch: repeating-linear-gradient(45deg,
        rgba(255, 77, 90, .14) 0 6px, transparent 6px 12px);

    --exn-mono-bg: rgba(148, 163, 184, .10);
    --exn-sticky-bg: rgba(5, 9, 20, .92);
  }
}

:root[data-theme="dark"], :root[data-theme="dark"] .ab-page {
  --exn-ok:        #10B981;
  --exn-ok-bg:     rgba(16, 185, 129, .12);
  --exn-ok-line:   rgba(16, 185, 129, .34);
  --exn-stale:     #F5B942;
  --exn-stale-bg:  rgba(245, 185, 66, .12);
  --exn-stale-line:rgba(245, 185, 66, .34);
  --exn-none:      #B9C5D8;
  --exn-none-bg:   rgba(148, 163, 184, .10);
  --exn-none-line: rgba(148, 163, 184, .26);
  --exn-held:      #FF4D5A;
  --exn-held-bg:   rgba(255, 77, 90, .12);
  --exn-held-line: rgba(255, 77, 90, .34);
  --exn-wait:      #60A5FA;
  --exn-wait-bg:   rgba(96, 165, 250, .12);
  --exn-wait-line: rgba(96, 165, 250, .32);

  --exn-hatch: repeating-linear-gradient(45deg,
      rgba(255, 77, 90, .14) 0 6px, transparent 6px 12px);

  --exn-mono-bg: rgba(148, 163, 184, .10);
  --exn-sticky-bg: rgba(5, 9, 20, .92);
}


/* ============================================================================
   2. SITE CHROME
   ----------------------------------------------------------------------------
   The package's .site-brand expects an <img> monogram. This site ships NO
   images (the 2026-08-29 image freeze is still in force), so the mark is drawn
   in CSS: a gold-ringed square carrying the two initials.
   ========================================================================== */
.exn-mark {
  display: inline-grid;
  place-items: center;
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  border-radius: 14px;
  background: var(--deep-navy-grad);
  border: 1.5px solid var(--gold);
  font-family: var(--font-brand);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--gold-soft);
}

/* breadcrumb — mono, small, above the page heading */
.exn-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.exn-crumb li { display: inline-flex; align-items: center; gap: 10px; }
.exn-crumb li + li::before { content: "/"; color: var(--gold); }
.exn-crumb a { color: var(--muted); text-decoration: none; }
.exn-crumb a:hover, .exn-crumb a:focus-visible {
  color: var(--gold-ink);
  text-decoration: underline;
}
.exn-crumb [aria-current="page"] { color: var(--ink); }

/* The page title on a page that deliberately has NO hero (see DESIGN-NOTES:
   the hero is a browsing device; a page that answers one question skips it). */
.exn-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(27px, 3.6vw, 40px);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--ink);
  margin: 12px 0 4px;
}
.exn-subtitle {
  margin: 0 0 22px;
  font-family: var(--font-nav);
  font-size: 14.5px;
  color: var(--muted);
}

/* The standing line required by MASTER-PLAN §4 rail 5. It appears once per
   page, high up, never only in the footer. */
.exn-verify {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin: 20px 0 0;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--gold);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-size: 14px;
  line-height: 1.6;
  color: var(--body-c);
}
.exn-verify b { color: var(--ink); font-weight: 600; }


/* ============================================================================
   3. THE STATUS SYSTEM  —  .exn-st
   ----------------------------------------------------------------------------
   This is the component the whole site turns on. It appears thousands of times.

   FOUR STATES, and each is distinguished on FOUR INDEPENDENT CHANNELS so that
   none of colour, shape, or text is load-bearing on its own:

     state          word              glyph silhouette      pill border   ink
     confirmed      "Confirmed"       filled disc + tick    solid 1px     green
     stale          "Not re-checked"  half-filled disc      solid 1px     amber
     unconfirmed    "Not announced"   DASHED open ring      DASHED 1px    slate
     held           "On hold"         solid TRIANGLE        solid 2px +   red
                                                            45deg hatch

   Why four channels: ~8% of men have a colour-vision deficiency, the glyphs
   are 12px and a grayscale print or a bad phone screen flattens hue anyway.
   The silhouettes are deliberately different at 12px — disc / half-disc /
   broken ring / triangle are separable even when the colour is gone. The WORD
   is always rendered; it is never a bare dot.

   All glyphs are drawn in CSS. No icon font, no SVG sprite, no images.

   Markup:
     <span class="exn-st exn-st--confirmed">
       <i class="exn-st__mark" aria-hidden="true"></i>Confirmed
     </span>
   ========================================================================== */
.exn-st {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px 4px 9px;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: var(--exn-st-bg, transparent);
  font-family: var(--font-nav);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: .02em;
  white-space: nowrap;
  vertical-align: middle;
}
.exn-st__mark {
  position: relative;
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: currentColor;
}

/* -- confirmed: a solid disc with a white tick cut into it ---------------- */
.exn-st--confirmed { color: var(--exn-ok); --exn-st-bg: var(--exn-ok-bg); border-color: var(--exn-ok-line); }
.exn-st--confirmed .exn-st__mark::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 1.5px;
  width: 3px;
  height: 6px;
  border: solid var(--exn-ok-bg);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(42deg);
}

/* -- stale: a HALF-filled disc — "partly known" reads in silhouette ------- */
.exn-st--stale { color: var(--exn-stale); --exn-st-bg: var(--exn-stale-bg); border-color: var(--exn-stale-line); }
.exn-st--stale .exn-st__mark {
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50% 100%);
  box-shadow: inset 0 0 0 1.6px currentColor;
}

/* -- unconfirmed: a DASHED open ring, and the pill's border goes dashed too */
.exn-st--unconfirmed { color: var(--exn-none); --exn-st-bg: var(--exn-none-bg); border-color: var(--exn-none-line); border-style: dashed; }
.exn-st--unconfirmed .exn-st__mark {
  background: transparent;
  border: 1.6px dashed currentColor;
}

/* -- held: a solid TRIANGLE, a 2px border and a hatched fill -------------- */
.exn-st--held {
  color: var(--exn-held);
  --exn-st-bg: var(--exn-held-bg);
  border-color: var(--exn-held-line);
  border-width: 2px;
  padding: 3px 10px 3px 8px;
  background-image: var(--exn-hatch);
}
.exn-st--held .exn-st__mark {
  border-radius: 0;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* -- large variant, for the verdict block only --------------------------- */
.exn-st--lg { font-size: 13.5px; padding: 6px 15px 6px 12px; gap: 9px; }
.exn-st--lg .exn-st__mark { width: 14px; height: 14px; }
.exn-st--lg.exn-st--confirmed .exn-st__mark::after { left: 4.7px; top: 2px; width: 3.4px; height: 7px; }


/* ============================================================================
   4. FACT ROWS  —  .exn-fact
   ----------------------------------------------------------------------------
   The atom of the exam hub: one field, its value, its state, its source and
   when we last looked. Every fact on this site is rendered through this.

   THE HONESTY RULE, expressed in CSS: a value that was not re-confirmed must
   never be typographically identical to one that was. `--stale` puts a dotted
   amber underline on the VALUE itself, not merely on the chip beside it — the
   reader who skims values and never reads chips still sees the difference.
   An `--unconfirmed` value renders as an em-dash and a muted phrase; it is
   never rendered as "TBA", which reads like a fact.
   ========================================================================== */
.exn-facts {
  margin: 26px 0 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card-surface);
  overflow: hidden;
}
.exn-fact {
  display: grid;
  grid-template-columns: minmax(160px, 210px) 1fr auto;
  gap: 4px 20px;
  align-items: start;
  padding: 16px 20px;
  border-top: 1px solid var(--line-soft);
}
.exn-fact:first-child { border-top: 0; }

.exn-fact__label {
  grid-column: 1;
  grid-row: 1 / span 2;
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 3px;
}
.exn-fact__value {
  grid-column: 2;
  grid-row: 1;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.exn-fact__state { grid-column: 3; grid-row: 1; justify-self: end; }
.exn-fact__prov  { grid-column: 2 / -1; grid-row: 2; margin: 4px 0 0; }

/* stale: mark the value itself */
.exn-fact--stale .exn-fact__value {
  border-bottom: 2px dotted var(--exn-stale);
  padding-bottom: 1px;
  /* width:fit-content + justify-self:start, NOT display:inline-block alone: a grid
     item still fills its column, so the underline would stretch the full width of
     the row and read as a rule rather than as a mark on the value. */
  width: fit-content;
  justify-self: start;
}
/* unconfirmed: no bold, no weight — nothing is being asserted */
.exn-fact--unconfirmed .exn-fact__value { color: var(--muted); font-weight: 400; }
/* held: the row itself carries the hatch, so it cannot be skimmed past */
.exn-fact--held { background-image: var(--exn-hatch); }
.exn-fact--held .exn-fact__value { color: var(--exn-held); }

/* provenance line: hostname + when we last looked. Both always present. */
.exn-prov {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.exn-prov > * { display: inline-flex; align-items: center; gap: 6px; }
.exn-checked::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  flex: 0 0 auto;
}
.exn-prov time { font-variant-numeric: tabular-nums; }

/* the source link — the hostname is shown, because a reader trusts a hostname
   more than the words "official link" */
.exn-src {
  color: var(--gold-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.exn-src::after { content: " \2197"; text-decoration: none; }
.exn-src:hover, .exn-src:focus-visible { color: var(--ink); }
.exn-src--none { color: var(--muted); text-decoration: none; font-style: italic; }
.exn-src--none::after { content: none; }


/* ============================================================================
   5. THE VERDICT BLOCK  —  .exn-verdict
   ----------------------------------------------------------------------------
   The one-screen answer on /result/ and /admit-card/ — the two highest-traffic
   page types. A student who arrives here wants a yes or a no and a link, in
   that order, before any scrolling.

   IT CARRIES TWO DIFFERENT THINGS AND KEEPS THEM APART:
     - the ANSWER   ("Yes, the result is out")  — a fact about the world
     - the STATUS   (the .exn-st chip)          — our confidence in that fact
   These are not the same and must never be collapsed. "Not out yet" can be
   perfectly `confirmed` (the official site says results are due in November)
   or `unconfirmed` (nobody has said anything). The reader is entitled to both.

   Flavours are the ANSWER, not the status:
     --yes    it has happened          green
     --wait   announced, still ahead   blue   (calm — "not yet" is not an error)
     --no     nothing announced        slate
     --held   we have stopped          red + hatch
   ========================================================================== */
.exn-verdict {
  position: relative;
  overflow: hidden;
  margin: 18px 0 0;
  padding: 26px 26px 22px;
  border: 1px solid var(--exn-v-line, var(--line));
  border-left: 6px solid var(--exn-v-ink, var(--gold));
  border-radius: var(--r-lg);
  background: var(--exn-v-bg, var(--paper));
  box-shadow: var(--shadow-soft);
}
.exn-verdict--yes   { --exn-v-ink: var(--exn-ok);    --exn-v-bg: var(--exn-ok-bg);    --exn-v-line: var(--exn-ok-line); }
.exn-verdict--wait  { --exn-v-ink: var(--exn-wait);  --exn-v-bg: var(--exn-wait-bg);  --exn-v-line: var(--exn-wait-line); }
.exn-verdict--no    { --exn-v-ink: var(--exn-none);  --exn-v-bg: var(--exn-none-bg);  --exn-v-line: var(--exn-none-line); }
.exn-verdict--held  { --exn-v-ink: var(--exn-held);  --exn-v-bg: var(--exn-held-bg);  --exn-v-line: var(--exn-held-line); background-image: var(--exn-hatch); }

.exn-verdict__eyebrow {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--exn-v-ink);
}
.exn-verdict__answer {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 4vw, 38px);
  line-height: 1.18;
  letter-spacing: -.01em;
  color: var(--ink);
}
.exn-verdict__when {
  margin: 10px 0 0;
  font-size: var(--fs-1);
  line-height: 1.6;
  color: var(--body-c);
}
.exn-verdict__when b {
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.exn-verdict__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}
.exn-verdict__prov {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--exn-v-line);
}

/* the verdict's own CTA: full width on a phone so it cannot be missed */
@media (max-width: 560px) {
  .exn-verdict__row > .ab-btn { width: 100%; justify-content: center; }
}


/* ============================================================================
   6. LIVE STRIP  —  .exn-strip
   ----------------------------------------------------------------------------
   The home page's first screen. Counts only; every number is a link into the
   list that produced it, so no figure is a dead end.
   ========================================================================== */
.exn-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}
.exn-strip a {
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 100%;
  padding: 14px 16px;
  border: 1px solid var(--exn-s-line, var(--line));
  border-radius: var(--r-sm);
  background: var(--exn-s-bg, var(--card-surface));
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease;
}
.exn-strip a:hover, .exn-strip a:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--shadow-soft);
}
.exn-strip b {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 400;
  line-height: 1.1;
  color: var(--exn-s-ink, var(--ink));
  font-variant-numeric: tabular-nums;
}
.exn-strip span {
  font-family: var(--font-nav);
  font-size: 13px;
  font-weight: 500;
  color: var(--body-c);
}
.exn-strip--ok   { --exn-s-ink: var(--exn-ok);   --exn-s-bg: var(--exn-ok-bg);   --exn-s-line: var(--exn-ok-line); }
.exn-strip--wait { --exn-s-ink: var(--exn-wait); --exn-s-bg: var(--exn-wait-bg); --exn-s-line: var(--exn-wait-line); }
.exn-strip--urg  { --exn-s-ink: var(--exn-held); --exn-s-bg: var(--exn-held-bg); --exn-s-line: var(--exn-held-line); }


/* ============================================================================
   7. EVENT RAIL  —  .exn-rail
   ----------------------------------------------------------------------------
   The six event sub-pages of one exam, always in cycle order, always visible,
   each carrying its own status dot. This is the exam hub's spine and it repeats
   on every event page so a reader can move sideways without going back.
   Sticky below the header on desktop.
   ========================================================================== */
.exn-rail {
  position: sticky;
  top: 0;
  z-index: 30;
  margin: 26px 0 0;
  padding: 10px 0;
  background: var(--exn-sticky-bg);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}
.exn-rail__list {
  display: flex;
  gap: 8px;
  margin: 0;
  padding: 0 0 2px;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.exn-rail__list a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  font-family: var(--font-nav);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color .18s ease, transform .18s ease;
}
.exn-rail__list a:hover, .exn-rail__list a:focus-visible {
  border-color: var(--gold);
  transform: translateY(-1px);
}
.exn-rail__list a[aria-current="page"] {
  border-color: var(--gold);
  background: var(--tint);
}
/* the dot on a rail item is the status glyph again, at 10px */
.exn-rail__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: currentColor;
}
.exn-rail__dot--confirmed   { color: var(--exn-ok); }
.exn-rail__dot--stale       { color: var(--exn-stale); background: linear-gradient(90deg, currentColor 0 50%, transparent 50% 100%); box-shadow: inset 0 0 0 1.4px currentColor; }
.exn-rail__dot--unconfirmed { color: var(--exn-none); background: transparent; border: 1.4px dashed currentColor; }
.exn-rail__dot--held        { color: var(--exn-held); border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }


/* ============================================================================
   8. FEED ITEMS  —  .exn-feed
   ----------------------------------------------------------------------------
   /latest/ and the home page's "what changed". One row per detected change.
   Headline is the change itself; the from -> to pair is shown literally,
   because "what did it say before" is the question a reader actually has.
   ========================================================================== */
.exn-feed { margin: 26px 0 0; padding: 0; list-style: none; }
.exn-feed > li {
  display: grid;
  grid-template-columns: 122px 1fr;
  gap: 4px 22px;
  padding: 20px 0;
  border-top: 1px solid var(--line-soft);
}
.exn-feed > li:first-child { border-top: 0; padding-top: 4px; }
.exn-feed__when {
  grid-row: 1 / span 3;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--muted);
  padding-top: 4px;
  font-variant-numeric: tabular-nums;
}
.exn-feed__head { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 20px; line-height: 1.35; }
.exn-feed__head a { color: var(--ink); text-decoration: none; }
.exn-feed__head a:hover, .exn-feed__head a:focus-visible { text-decoration: underline; text-decoration-color: var(--gold); text-underline-offset: 4px; }
.exn-feed__meta { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; }

/* the literal before -> after pair */
.exn-delta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 10px 0 0;
  padding: 9px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--body-c);
  font-variant-numeric: tabular-nums;
}
.exn-delta del { color: var(--muted); text-decoration-color: var(--exn-held); }
.exn-delta ins { color: var(--ink); font-weight: 600; text-decoration: none; }
.exn-delta__arrow { color: var(--gold-ink); font-weight: 700; }

/* a small neutral tag used across feeds, hubs and vacancy cards */
.exn-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--exn-mono-bg);
  font-family: var(--font-nav);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .03em;
  color: var(--body-c);
  text-decoration: none;
}
a.exn-tag:hover, a.exn-tag:focus-visible { border-color: var(--gold); color: var(--ink); }


/* ============================================================================
   9. VACANCY ENTRIES  —  .exn-vac
   ----------------------------------------------------------------------------
   /vacancy/<date>/. Dense and scannable, sorted by which closes FIRST, because
   that is the reader's real question. Each entry carries the eight required
   fields plus the official notification link.

   THE CLOSING RAIL is the left column: a big days-left number, the last date,
   and a bar showing how much of the application window has already gone. It is
   the reason this page is worth reading rather than a table of names.
   Urgency is shown by number AND bar length AND colour — never colour alone.
   ========================================================================== */
.exn-vac {
  display: grid;
  grid-template-columns: 168px 1fr;
  gap: 0;
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card-surface);
  overflow: hidden;
}
.exn-vac__close {
  padding: 20px 18px;
  border-right: 1px solid var(--line-soft);
  background: var(--exn-c-bg, var(--paper));
  color: var(--exn-c-ink, var(--body-c));
}
.exn-vac--soon   { --exn-c-ink: var(--exn-held);  --exn-c-bg: var(--exn-held-bg); }
.exn-vac--near   { --exn-c-ink: var(--exn-stale); --exn-c-bg: var(--exn-stale-bg); }
.exn-vac--open   { --exn-c-ink: var(--exn-ok);    --exn-c-bg: var(--exn-ok-bg); }
.exn-vac--closed { --exn-c-ink: var(--exn-none);  --exn-c-bg: var(--exn-none-bg); }

.exn-vac__days {
  display: block;
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 1;
  color: var(--exn-c-ink);
  font-variant-numeric: tabular-nums;
}
.exn-vac__daysl {
  display: block;
  margin-top: 2px;
  font-family: var(--font-nav);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--exn-c-ink);
}
.exn-vac__last {
  display: block;
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--body-c);
  font-variant-numeric: tabular-nums;
}
.exn-vac__bar {
  margin-top: 10px;
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.exn-vac__bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--exn-c-ink);
}

.exn-vac__body { padding: 20px 22px; min-width: 0; }
.exn-vac__post { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 22px; line-height: 1.3; color: var(--ink); }
.exn-vac__dept { margin: 4px 0 0; font-family: var(--font-nav); font-size: 13.5px; font-weight: 600; color: var(--gold-ink); }

/* the eight fields, as a definition grid */
.exn-dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px 26px;
  margin: 16px 0 0;
}
.exn-dl > div { min-width: 0; }
.exn-dl dt {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
}
.exn-dl dd {
  margin: 3px 0 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.exn-vac__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}


/* ============================================================================
   10. CALENDAR  —  .exn-cal
   ----------------------------------------------------------------------------
   /calendar/ has to be useful in the weeks when nothing was announced, which is
   most weeks. A month with no confirmed events therefore does NOT render an
   empty box: it renders (a) the next dated event anywhere on the site, and
   (b) what this month has HISTORICALLY carried, from the registry's
   `typical_months` — labelled, loudly, as a pattern and not an announcement.
   The `.exn-cal__typical` block's dashed border is the same visual grammar as
   the `unconfirmed` status: dashed = not asserted.
   ========================================================================== */
.exn-cal { margin-top: 30px; display: grid; gap: 20px; }
.exn-cal__month {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card-surface);
  overflow: hidden;
}
.exn-cal__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--paper);
}
.exn-cal__head h3 { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 23px; color: var(--ink); }
.exn-cal__head a { font-family: var(--font-nav); font-size: 13px; font-weight: 600; color: var(--gold-ink); text-decoration: none; }
.exn-cal__count { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }

.exn-cal__list { margin: 0; padding: 0; list-style: none; }
.exn-cal__list > li {
  display: grid;
  grid-template-columns: 92px 1fr auto;
  gap: 4px 18px;
  align-items: center;
  padding: 12px 20px;
  border-top: 1px solid var(--line-soft);
}
.exn-cal__list > li:first-child { border-top: 0; }
.exn-cal__date {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.exn-cal__what { min-width: 0; font-size: 15px; color: var(--body-c); }
.exn-cal__what a { color: var(--ink); text-decoration: none; font-weight: 600; }
.exn-cal__what a:hover, .exn-cal__what a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

/* the quiet month */
.exn-cal__quiet { padding: 18px 20px; }
.exn-cal__quiet p { margin: 0 0 12px; font-size: 15px; color: var(--body-c); }
.exn-cal__typical {
  margin: 0;
  padding: 14px 16px;
  border: 1.5px dashed var(--exn-none-line);
  border-radius: var(--r-sm);
  background: var(--exn-none-bg);
}
.exn-cal__typical h4 {
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--exn-none);
}
.exn-cal__typical ul { margin: 0; padding-left: 18px; font-size: 14px; color: var(--body-c); }
.exn-cal__typical .exn-cal__caveat {
  margin: 10px 0 0;
  font-size: 13px;
  font-style: italic;
  color: var(--muted);
}

/* the 12-month spark row at the top of /calendar/ — density at a glance */
.exn-cal__spark {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 4px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}
.exn-cal__spark a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .04em;
  color: var(--muted);
  min-height: 60px;
  justify-content: flex-end;
}
.exn-cal__spark a:hover, .exn-cal__spark a:focus-visible { border-color: var(--gold); color: var(--ink); }
.exn-cal__spark i {
  display: block;
  width: 100%;
  border-radius: 3px 3px 0 0;
  background: var(--gold);
  min-height: 3px;
}
.exn-cal__spark a[aria-current="page"] { border-color: var(--gold); background: var(--tint); color: var(--ink); }


/* ============================================================================
   11. FILTER BAR  —  .exn-filter
   ----------------------------------------------------------------------------
   Progressive enhancement only. Every chip is a REAL LINK to a real page, so
   the feed works with JavaScript off; site.js upgrades them to instant
   client-side filtering when it can.
   ========================================================================== */
.exn-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}
.exn-filter__label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 4px;
}
.exn-filter a, .exn-filter button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  font-family: var(--font-nav);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: border-color .18s ease, background .18s ease;
}
.exn-filter a:hover, .exn-filter button:hover,
.exn-filter a:focus-visible, .exn-filter button:focus-visible { border-color: var(--gold); }
.exn-filter [aria-current="page"], .exn-filter [aria-pressed="true"] {
  border-color: var(--gold);
  background: var(--tint);
}

/* the search box on hub pages */
.exn-search {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 22px 0 0;
  padding: 0 16px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  min-height: 52px;
}
.exn-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline-offset: 6px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 16px;          /* 16px stops iOS zooming the page on focus */
  color: var(--ink);
  padding: 12px 0;
}
.exn-search input::placeholder { color: var(--muted); }
.exn-search__hint { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); white-space: nowrap; }

.exn-empty {
  margin: 24px 0 0;
  padding: 26px;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius);
  text-align: center;
  color: var(--muted);
}


/* ============================================================================
   12. DATA TABLES, NOTES, ADMIN
   ========================================================================== */
.exn-tablewrap { margin-top: 24px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.exn-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: 14.5px;
}
.exn-table th, .exn-table td {
  padding: 11px 14px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
.exn-table tbody td { color: var(--body-c); font-variant-numeric: tabular-nums; }
.exn-table tbody th { color: var(--ink); font-weight: 600; }
.exn-table caption {
  caption-side: bottom;
  padding-top: 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  text-align: left;
}

/* numbered "how to" list — the download/check steps */
.exn-steps { counter-reset: exn 0; margin: 20px 0 0; padding: 0; list-style: none; }
.exn-steps > li {
  counter-increment: exn;
  position: relative;
  padding: 0 0 18px 46px;
  border-left: 2px solid var(--line);
  margin-left: 13px;
}
.exn-steps > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.exn-steps > li::before {
  content: counter(exn);
  position: absolute;
  left: -14px;
  top: -2px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--grad-step);
  color: #fff;
  font-family: var(--font-nav);
  font-size: 12.5px;
  font-weight: 700;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
.exn-steps h4 { margin: 0 0 3px; font-family: var(--font-nav); font-size: 15.5px; font-weight: 600; color: var(--ink); }
.exn-steps p { margin: 0; font-size: 14.5px; color: var(--body-c); }

/* an official-link block — repeated on every event page */
.exn-links { display: grid; gap: 10px; margin-top: 20px; padding: 0; list-style: none; }
.exn-links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 56px;
  padding: 12px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  text-decoration: none;
  color: var(--ink);
  font-weight: 600;
  transition: border-color .18s ease, transform .18s ease;
}
.exn-links a:hover, .exn-links a:focus-visible { border-color: var(--gold); transform: translateY(-1px); }
.exn-links small { font-family: var(--font-mono); font-size: 11.5px; font-weight: 400; color: var(--muted); white-space: nowrap; }

/* admin only */
.exn-admin__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-top: 22px; }
.exn-admin__note {
  margin-top: 22px;
  padding: 14px 16px;
  border: 1px solid var(--exn-held-line);
  border-left: 4px solid var(--exn-held);
  border-radius: var(--r-sm);
  background: var(--exn-held-bg);
  font-size: 14px;
  color: var(--body-c);
}
.exn-mono { font-family: var(--font-mono); font-size: 12.5px; background: var(--exn-mono-bg); padding: 2px 7px; border-radius: 5px; }


/* ============================================================================
   13. RESPONSIVE + THE TAP-TARGET FLOOR
   ----------------------------------------------------------------------------
   No horizontal overflow at 375px is a hard requirement. Every wide construct
   above (rail, table, spark row) either scrolls inside its own container or
   collapses to one column here.
   ========================================================================== */
@media (max-width: 900px) {
  .exn-vac { grid-template-columns: 1fr; }
  .exn-vac__close {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    border-right: 0;
    border-bottom: 1px solid var(--line-soft);
    padding: 14px 18px;
  }
  .exn-vac__days { font-size: 30px; }
  .exn-vac__daysl { margin-top: 0; }
  .exn-vac__last { margin-top: 0; }
  .exn-vac__bar { flex: 1 1 100%; margin-top: 4px; }
  .exn-cal__spark { grid-template-columns: repeat(6, 1fr); }
}

@media (max-width: 760px) {
  .exn-fact {
    grid-template-columns: 1fr auto;
    gap: 3px 12px;
    padding: 15px 16px;
  }
  .exn-fact__label { grid-column: 1 / -1; grid-row: 1; padding-top: 0; }
  .exn-fact__value { grid-column: 1; grid-row: 2; font-size: 16px; }
  .exn-fact__state { grid-column: 2; grid-row: 2; align-self: center; }
  .exn-fact__prov  { grid-column: 1 / -1; grid-row: 3; }

  .exn-feed > li { grid-template-columns: 1fr; gap: 6px; }
  .exn-feed__when { grid-row: 1; padding-top: 0; }

  .exn-cal__list > li { grid-template-columns: 1fr; gap: 5px; }

  .exn-verdict { padding: 22px 18px 18px; border-radius: var(--radius); }
  .exn-rail { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }

  /* THE TAP-TARGET FLOOR. Every primary control reaches 44px on a phone.
     Deliberately NOT applied to inline links inside running prose, where a
     44px block would break the paragraph — those keep a 24px hit area via
     line-height, which is the standard trade and is stated in DESIGN-NOTES. */
  .ab-btn { min-height: 44px; padding: 12px 22px; }
  .exn-src, .exn-tag, .exn-crumb a { min-height: 44px; display: inline-flex; align-items: center; }
  .exn-prov { gap: 2px 14px; }
}

@media (max-width: 480px) {
  .exn-strip { grid-template-columns: 1fr 1fr; }
  .exn-strip b { font-size: 26px; }
  .exn-dl { grid-template-columns: 1fr; }
  .exn-cal__spark { grid-template-columns: repeat(4, 1fr); }
  .exn-verdict__row > .ab-btn { width: 100%; justify-content: center; }
}

/* The rail's sticky behaviour is a nuisance on a short phone screen — it eats
   a fifth of the viewport on the exact pages that must answer in one screen. */
@media (max-width: 760px) {
  .exn-rail { position: static; backdrop-filter: none; }
  [id] { scroll-margin-top: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .exn-strip a:hover, .exn-links a:hover, .exn-rail__list a:hover { transform: none; }
}

@media print {
  .exn-rail, .exn-filter, .exn-search, .site-header, .ab-cta { display: none; }
  .exn-verdict { box-shadow: none; }
  .exn-src::after { content: " (" attr(href) ")"; font-size: 10px; }
}


/* ============================================================================
   14. SMALL SHARED PIECES
   ----------------------------------------------------------------------------
   Declared last so they sit after the responsive block; none of them collide
   with anything above, they are simply the leftovers the page templates use.
   ========================================================================== */

/* a card's one-line summary, and the mono kicker above a card title */
.exn-cardline { margin: 6px 0 0; font-size: 14.5px; line-height: 1.55; color: var(--body-c); }
.exn-cardkick {
  margin: 0 0 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--gold-ink);
}
.ab-card__title a { color: var(--ink); text-decoration: none; }
.ab-card__title a:hover, .ab-card__title a:focus-visible {
  text-decoration: underline;
  text-decoration-color: var(--gold);
  text-underline-offset: 4px;
}

/* a quiet aside under a block — smaller and calmer than .ab-callout */
.exn-note {
  margin: 14px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--muted);
}
.exn-sortnote {
  margin: 16px 0 0;
  font-family: var(--font-nav);
  font-size: 13.5px;
  color: var(--body-c);
}
.exn-sortnote b { color: var(--ink); }

/* plain content lists inside cards */
.exn-list { margin: 10px 0 0; padding-left: 20px; font-size: 14.5px; line-height: 1.7; color: var(--body-c); }
.exn-list li + li { margin-top: 4px; }

.exn-inline-dept { display: block; font-size: 13.5px; font-weight: 400; color: var(--muted); margin-top: 2px; }

/* pagination */
.exn-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 34px;
}
.exn-pager__at { font-family: var(--font-mono); font-size: 12.5px; color: var(--muted); }

/* the site link footer (above the Rule 8 credit bar) */
.exn-sitefoot {
  margin-top: clamp(64px, 9vw, 110px);
  padding: 40px 0 10px;
  border-top: 1px solid var(--line);
  background: var(--paper);
}
.exn-footlist { margin: 10px 0 0; padding: 0; list-style: none; }
.exn-footlist li + li { margin-top: 2px; }
.exn-footlist a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  color: var(--body-c);
  text-decoration: none;
  font-size: 14.5px;
}
.exn-footlist a:hover, .exn-footlist a:focus-visible {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* admin-only form bits */
.exn-admin__act { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.exn-admin__input {
  min-width: 0;
  flex: 1 1 150px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
}
.exn-admin__act .ab-btn { padding: 10px 16px; font-size: 13.5px; }

@media (max-width: 760px) {
  .exn-footlist a { min-height: 44px; }
  .exn-sitefoot { padding-top: 30px; }
}


/* ============================================================================
   15. CTA ROW ON NARROW PHONES — a deliberate, documented deviation
   ----------------------------------------------------------------------------
   The AB rulebook says the two CTA buttons stay on ONE ROW at every width, and
   may wrap only below 360px. That rule was tuned on aniketbhardwaj.com, whose
   second button reads "Call +91 92121 49490" inside a wider container.

   MEASURED HERE at a true 375px viewport: the ghost button's right edge lands
   at 380px against a 375px screen, so the phone number is clipped by the CTA
   panel's own overflow:hidden. A clipped phone number on a page whose entire
   purpose is that someone can reach a person is worse than a wrapped button, so
   the row is allowed to wrap below 430px on this site and the buttons go full
   width. Re-measure before narrowing this breakpoint again.
   ========================================================================== */
@media (max-width: 430px) {
  .ab-cta__row { flex-wrap: wrap; justify-content: center; }
  .ab-cta__row > .ab-btn { width: 100%; justify-content: center; }
}
