/* ============================================================================
   HUMAN CONCERN INTERNATIONAL — CONTENT PAGE COMPONENTS
   Adsorse Technologies · September 2026

   The handful of components that Who We Are / Reports / Careers / Contact /
   404 need and that shared.css, styles.css and campaign.css do not already
   provide. Everything else on those pages is composed from existing classes.

   Load order:
       <link rel="stylesheet" href="shared.css">
       <link rel="stylesheet" href="styles.css">
       <link rel="stylesheet" href="campaign.css">
       <link rel="stylesheet" href="pages.css">     <- last

   No tokens are defined here. Every colour, radius, shadow, easing and
   spacing value comes from shared.css's :root. If you find yourself typing a
   hex code below, it belongs in shared.css instead.
   ========================================================================= */


/* ---------------------------------------------------------------- BANNER  */
/* A page-header banner with no photograph. .cbanner already handles the
   fixed-header clearance; this only adds the patterned ground and keeps the
   copy from stretching to the full 1240px shell. */
.cbanner--page {
  background: var(--maroon-2);
}

.cbanner--page .cbanner__copy {
  max-width: 46rem;
}

.cbanner__crumb {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 16px;
  font-size: .78rem;
  color: var(--on-dark-3);
}

.cbanner__crumb a {
  color: var(--on-dark-2);
  text-decoration: none;
  transition: color .18s var(--ease);
}

.cbanner__crumb a:hover {
  color: #fff;
}

.cbanner__crumb svg {
  width: 11px;
  height: 11px;
  opacity: .6;
}


/* -------------------------------------------------------------- TIMELINE  */
/* Vertical rail on narrow screens, horizontal on wide. The connecting line is
   drawn on the list itself so it never breaks between items. */
.timeline {
  position: relative;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

.timeline__list {
  position: relative;
  display: grid;
  gap: 26px;
  padding-left: 30px;
}

.timeline__list::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: linear-gradient(180deg, var(--red) 0%, var(--line-2) 76%, transparent 100%);
  border-radius: var(--r-pill);
}

.timeline__item {
  position: relative;
}

.timeline__item::before {
  content: "";
  position: absolute;
  left: -30px;
  top: 7px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--white);
  border: 3px solid var(--red);
  transition: transform .24s var(--ease), border-color .24s var(--ease);
}

.timeline__item:hover::before {
  transform: scale(1.25);
  border-color: var(--maroon);
}

.timeline__yr {
  display: inline-block;
  margin-bottom: 6px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--red-dark);
  background: var(--red-tint);
  border-radius: 5px;
  padding: 4px 9px;
  font-variant-numeric: tabular-nums;
}

.timeline__item h3 {
  margin: 0 0 6px;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -.012em;
}

.timeline__item p {
  margin: 0;
  font-size: .89rem;
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 46ch;
}

@media (min-width:860px) {
  .timeline__list {
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--gap);
    padding-left: 0;
    padding-top: 34px;
  }

  .timeline__list::before {
    left: 0;
    right: 0;
    top: 5px;
    bottom: auto;
    width: auto;
    height: 2px;
    background: linear-gradient(90deg, var(--red) 0%, var(--line-2) 76%, transparent 100%);
  }

  .timeline__item::before {
    left: 0;
    top: -34px;
  }
}


/* --------------------------------------------------------- REPORT COVERS  */
/* Extends styles.css's .doc into a card with a cover thumbnail. Same hover
   language as .ccard/.xcard: lift, not slide. */
.doc--cover {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  overflow: hidden;
  border-radius: var(--r-md);
  height: 100%;
  margin-bottom: 0;
}

.doc--cover:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-2);
  border-color: #EDD2CF;
}

.doc__cover {
  position: relative;
  aspect-ratio: 3/4;
  background: linear-gradient(150deg, var(--maroon) 0%, var(--maroon-2) 100%);
  display: grid;
  place-items: center;
  padding: 22px;
  overflow: hidden;
}

.doc__cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 13px);
  pointer-events: none;
}

.doc__cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.doc__covermark {
  position: relative;
  z-index: 1;
  text-align: center;
  color: var(--on-dark-2);
}

.doc__covermark svg {
  width: 34px;
  height: 34px;
  color: var(--accent-dark);
  transform: none;
}

.doc--cover:hover .doc__covermark svg {
  transform: none;
  color: var(--accent-dark);
}

.doc__covermark span {
  display: block;
  margin-top: 10px;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.doc__cbody {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 15px 16px 16px;
  flex: 1;
}

.doc__cbody .doc__yr {
  align-self: flex-start;
}

.doc__cbody .doc__t {
  flex: 1;
  font-size: .92rem;
  line-height: 1.4;
}

.doc__go {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: .8rem;
  font-weight: 700;
  color: var(--red-dark);
}

.doc__go svg {
  width: 13px;
  height: 13px;
  color: currentColor;
}

.doc--cover:hover .doc__go svg {
  transform: translateX(4px);
}

/* The cover grid itself — .docs is a link list, this is a card grid. */
.covers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--gap);
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

.covers__h {
  grid-column: 1/-1;
  margin: 0;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.covers__h:not(:first-child) {
  margin-top: clamp(14px, 2vw, 22px);
}


/* ------------------------------------------------------------- JOB ROWS  */
.joblist {
  display: grid;
  gap: 14px;
}

.jobrow {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 18px;
  padding: 22px 24px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}

.jobrow:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-2);
  border-color: #EDD2CF;
}

.jobrow h3 {
  margin: 0 0 8px;
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: -.018em;
}

.jobrow p {
  margin: 10px 0 0;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 66ch;
}

.jobrow__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jobrow__meta li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: var(--r-pill);
  background: var(--sand);
  border: 1px solid var(--line);
  font-size: .75rem;
  font-weight: 600;
  color: var(--ink-2);
}

.jobrow__meta svg {
  width: 12px;
  height: 12px;
  color: var(--red);
  flex: none;
}

.jobrow__go {
  flex: none;
}

.joblist__empty {
  padding: 34px 24px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-lg);
  text-align: center;
  font-size: .92rem;
  color: var(--ink-3);
}

@media (max-width:720px) {
  .jobrow {
    grid-template-columns: 1fr;
    align-items: start;
  }

  .jobrow__go {
    justify-self: stretch;
    text-align: center;
  }
}


/* ---------------------------------------------------------------- CONTACT */
.contact-grid {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

@media (max-width:900px) {
  .contact-grid {
    grid-template-columns: 1fr;
  }
}

/* The form card itself is campaign.css's .donate-form — a white card plus the
   light-on-sand field re-theme, which is exactly what a contact form needs.
   .contact-card only adds the heading typography on top of it. */
.contact-card h2 {
  margin: 0 0 6px;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -.02em;
}

.contact-card__sub {
  margin: 0 0 24px;
  font-size: .92rem;
  line-height: 1.55;
  color: var(--ink-3);
}

/* Contact channels — one card per way of reaching HCI. */
.channels {
  display: grid;
  gap: 12px;
}

.channel {
  display: flex;
  gap: 14px;
  padding: 18px 20px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-decoration: none;
  box-shadow: var(--sh-1);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}

a.channel:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-2);
  border-color: #EDD2CF;
}

.channel .icon {
  width: 26px;
  height: 26px;
  color: var(--red);
  flex: none;
  margin-top: 2px;
}

a.channel:hover .icon {
  animation: draw 1.6s cubic-bezier(.33, .9, .28, 1) both;
}

.channel__l {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 5px;
}

/* Direct child only — a nested <b> inside the description (e.g. a cheque payee
   name) must stay inline rather than breaking onto its own line. */
.channel > div > b {
  display: block;
  font-size: .98rem;
  font-weight: 700;
  letter-spacing: -.01em;
  word-break: break-word;
}

.channel span:not(.channel__l) {
  display: block;
  margin-top: 4px;
  font-size: .83rem;
  line-height: 1.5;
  color: var(--ink-3);
}

/* Static map card. Deliberately not an iframe — the prototype ships with no
   API key and an embed would be the only external request on the page. */
.mapcard {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-1);
  background: var(--white);
}

.mapcard__art {
  position: relative;
  aspect-ratio: 16/10;
  background:
    radial-gradient(circle at 62% 46%, rgba(227, 34, 38, .10) 0 14%, transparent 14.5%),
    linear-gradient(0deg, rgba(216, 201, 193, .5) 0 1px, transparent 1px),
    linear-gradient(90deg, rgba(216, 201, 193, .5) 0 1px, transparent 1px),
    var(--sand);
  background-size: 100% 100%, 100% 34px, 34px 100%, 100% 100%;
}

/* Two "roads" so the block reads as a map rather than graph paper. */
.mapcard__art::before,
.mapcard__art::after {
  content: "";
  position: absolute;
  background: var(--white);
  border-block: 1px solid var(--line);
}

.mapcard__art::before {
  left: -10%;
  right: -10%;
  top: 44%;
  height: 16px;
  transform: rotate(-6deg);
}

.mapcard__art::after {
  top: -10%;
  bottom: -10%;
  left: 61%;
  width: 14px;
  border-block: 0;
  border-inline: 1px solid var(--line);
}

.mapcard__pin {
  position: absolute;
  left: 62%;
  top: 46%;
  transform: translate(-50%, -100%);
  z-index: 1;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50% 50% 50% 4px;
  rotate: -45deg;
  background: var(--red);
  box-shadow: var(--sh-2);
}

.mapcard__pin svg {
  width: 17px;
  height: 17px;
  color: #fff;
  rotate: 45deg;
}

.mapcard__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 16px 20px 18px;
  border-top: 1px solid var(--line);
}

.mapcard__body b {
  display: block;
  font-size: .92rem;
}

.mapcard__body span {
  display: block;
  margin-top: 3px;
  font-size: .82rem;
  color: var(--ink-3);
}

/* Consent / checkbox row inside the contact form. */
.checkrow {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink-2);
  cursor: pointer;
}

.checkrow input {
  width: 18px;
  height: 18px;
  flex: none;
  margin: 1px 0 0;
  accent-color: var(--red);
}

.formnote {
  margin: 18px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: .8rem;
  color: var(--ink-3);
}

/* Success state after a valid submit. */
.formdone {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  margin-top: 18px;
  padding: 16px 18px;
  border-radius: var(--r-md);
  background: #F0F7F1;
  border: 1px solid #CDE4D2;
  font-size: .88rem;
  line-height: 1.55;
  color: #23572F;
}

.formdone svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 2px;
  color: #2E7D3D;
}


/* -------------------------------------------------------------------- 404 */
.nf {
  text-align: center;
  max-width: 54ch;
  margin-inline: auto;
}

.nf__code {
  display: block;
  font-family: var(--serif);
  font-size: clamp(5rem, 17vw, 10.5rem);
  line-height: .9;
  font-weight: 500;
  letter-spacing: -.04em;
  color: var(--accent-dark);
  opacity: .9;
}

.nf h1 {
  margin: 18px 0 12px;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  line-height: 1.12;
  letter-spacing: -.028em;
  color: #fff;
  text-wrap: balance;
}

.nf h1 em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
}

.nf p {
  margin: 0 0 26px;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--on-dark-2);
}

.nf__actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}


/* ------------------------------------------------------------- UTILITIES  */
/* A tighter grid than .grid--3 for 4-across value/benefit cards. */
.grid--4up {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: var(--gap);
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

/* Sample-content tag under a section heading. .sample-tag is a <p>, so without
   this it stretches the full width of the head block and reads as a banner
   rather than a tag. Scoped to .c-head so the homepage's own usage — where it
   already sits in a flex row — is untouched. */
.c-head .sample-tag {
  display: inline-block;
  margin-top: 14px;
}

/* .ltab tuned for a page-level filter bar rather than a giving-level switch:
   left-aligned, scrollable on narrow screens instead of wrapping to 3 rows. */
.filterbar {
  display: flex;
  gap: 8px;
  justify-content: flex-start;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 2px clamp(18px, 4vw, 32px) 4px;
  margin-bottom: clamp(22px, 3vw, 32px);
}

.filterbar::-webkit-scrollbar {
  display: none;
}

.filterbar .ltab {
  white-space: nowrap;
  flex: none;
}


/* .levels__where re-used as an intro note above a job list. Its original home
   is a centred giving-level block, so it carries no max-width and runs the full
   1240px shell here. */
.joblist__intro {
  max-width: 74ch;
  text-align: left;
  margin-bottom: clamp(20px, 2.5vw, 28px);
}


/* .spine carries its own 18–32px page gutter so it can stand alone on a band.
   Nested inside a column of .xsell or .story it double-inserts that gutter and
   the prose sits visibly indented from its own heading. Same reset campaign.css
   already applies for .crisis-lead. */
.xsell .spine,
.story .spine {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
}


/* ==========================================================================
   FLIPBOOK — the PDF viewer on reports.html
   Behaviour lives in flipbook.js. Everything below is chrome; the pages
   themselves are <img> elements holding canvases rendered by pdf.js.
   ========================================================================= */
.fb {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  opacity: 0;
  transition: opacity .24s var(--ease);
}

.fb.is-on {
  opacity: 1;
}

.fb[hidden] {
  display: none;
}

body.fb-open {
  overflow: hidden;
}

.fb__scrim {
  position: absolute;
  inset: 0;
  background: rgba(26, 5, 6, .88);
  backdrop-filter: blur(6px);
}

.fb__panel {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: clamp(10px, 1.6vh, 18px);
  width: 100%;
  height: 100%;
  padding: clamp(12px, 2vh, 22px) clamp(14px, 3vw, 30px) clamp(14px, 2vh, 24px);
  min-width: 0;
  min-height: 0;
  transform: translateY(10px) scale(.99);
  transition: transform .28s var(--ease);
}

.fb.is-on .fb__panel {
  transform: none;
}

/* ---------------------------------------------------------------- top bar */
.fb__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.fb__title {
  margin: 0;
  font-size: clamp(.98rem, 1.6vw, 1.15rem);
  font-weight: 700;
  letter-spacing: -.015em;
  color: #fff;
}

.fb__meta {
  margin: 3px 0 0;
  font-size: .78rem;
  color: var(--on-dark-3);
}

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

.fb__tool {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .07);
  color: #fff;
  font-size: .82rem;
  font-weight: 700;
  text-decoration: none;
  transition: background-color .18s var(--ease), border-color .18s var(--ease);
}

.fb__tool:hover {
  background: rgba(255, 255, 255, .15);
  border-color: rgba(255, 255, 255, .4);
}

.fb__tool svg {
  width: 15px;
  height: 15px;
}

.fb__tool--icon {
  padding: 9px;
}

.fb__tool--icon svg {
  width: 17px;
  height: 17px;
}

/* ------------------------------------------------------------------ stage */
.fb__stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 2vw, 22px);
  min-width: 0;
  min-height: 0;
}

.fb__nav {
  flex: none;
  z-index: 5;
}

.fb__status {
  position: absolute;
  inset-inline: 0;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  text-align: center;
  font-size: .92rem;
  color: var(--on-dark-2);
}

/* ------------------------------------------------------------------- book
   Two page slots, always both present — a cover with nothing facing it sits
   on the right of an empty left slot, which is how a book actually opens.
   --fb-ar is set from the PDF's own first page by flipbook.js. */
/* --fb-h is the book's height in px, computed by flipbook.js from the stage
   box and the PDF's own page ratio. Doing it in JS rather than CSS is the one
   reliable way to fit a fixed-ratio object inside a box that is constrained on
   BOTH axes — `aspect-ratio` alone resolves against one axis and overflows the
   other. */
.fb__book {
  position: relative;
  display: flex;
  height: var(--fb-h, 60vh);
  /* Far enough back that a turning leaf stays roughly inside the stage — a
     shorter distance exaggerates the lift until the page clips the viewport. */
  perspective: 3600px;
  perspective-origin: 50% 50%;
}

.fb__book[hidden] {
  display: none;
}

.fb__page {
  position: relative;
  height: 100%;
  aspect-ratio: var(--fb-ar, .773);
  background: var(--white);
  box-shadow: 0 10px 40px rgba(0, 0, 0, .45);
  overflow: hidden;
}

.fb__page img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Hidden, not removed — the empty slot keeps the spread's geometry (and the
   turning leaf's alignment) identical on every spread. */
.fb__page.is-blank {
  visibility: hidden;
}

.fb__page--l {
  border-radius: var(--r-sm) 0 0 var(--r-sm);
}

.fb__page--r {
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

/* The gutter shadow. Purely decorative — it is what makes two flat images
   read as one bound object. */
.fb__spine {
  position: absolute;
  inset-block: 0;
  left: 50%;
  width: 46px;
  transform: translateX(-50%);
  z-index: 4;
  pointer-events: none;
  background: linear-gradient(90deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, .13) 40%,
      rgba(0, 0, 0, .24) 50%,
      rgba(0, 0, 0, .13) 60%,
      rgba(0, 0, 0, 0) 100%);
}

.fb__book.is-cover .fb__spine {
  opacity: 0;
}

/* ------------------------------------------------------------------- leaf
   One sheet pivoting on the spine. Front face = the page you are leaving,
   back face = the page arriving. Both are already-rendered images, so the
   turn never waits on pdf.js. */
.fb__leaf {
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
  z-index: 6;
  transform-style: preserve-3d;
  transform-origin: left center;
  transform: rotateY(0deg);
}

.fb__leaf[hidden] {
  display: none;
}

.fb__leaf.is-turning {
  /* Duration is mirrored by TURN_MS in flipbook.js — change both. */
  transition: transform .62s cubic-bezier(.36, .06, .2, 1);
  transform: rotateY(-176deg);
}

.fb__leaf--back {
  right: auto;
  left: 0;
  transform-origin: right center;
}

.fb__leaf--back.is-turning {
  transform: rotateY(176deg);
}

.fb__leaf-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  background: var(--white);
  overflow: hidden;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .45);
}

.fb__leaf-face img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.fb__leaf-face--back {
  transform: rotateY(180deg);
}

/* Shading towards the spine. A page lifting off a book is darker where it is
   still bound; without this the sheet reads as a flat rectangle sliding
   around rather than paper bending away from you. */
.fb__leaf-face::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(0, 0, 0, .17) 0%, rgba(0, 0, 0, .04) 14%, transparent 34%);
}

.fb__leaf--back .fb__leaf-face--front::after,
.fb__leaf:not(.fb__leaf--back) .fb__leaf-face--back::after {
  background: linear-gradient(270deg, rgba(0, 0, 0, .17) 0%, rgba(0, 0, 0, .04) 14%, transparent 34%);
}

/* ----------------------------------------------------------------- footer */
.fb__foot {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 760px;
  width: 100%;
  margin-inline: auto;
}

.fb__count {
  margin: 0;
  flex: none;
  font-size: .8rem;
  font-weight: 600;
  color: var(--on-dark-2);
  font-variant-numeric: tabular-nums;
}

.fb__range {
  flex: 1;
  appearance: none;
  height: 4px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .22);
  cursor: pointer;
}

.fb__range::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--red);
  border: 2px solid #fff;
  cursor: pointer;
}

.fb__range::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--red);
  cursor: pointer;
}

/* Below the spread breakpoint flipbook.js serves one page at a time, so the
   left slot is never used and the nav buttons move under the page. */
@media (max-width:819px) {
  .fb__page--l,
  .fb__spine {
    display: none;
  }

  .fb__page--r {
    border-radius: var(--r-sm);
  }

  .fb__nav {
    position: absolute;
    bottom: 4px;
    z-index: 7;
  }

  .fb__nav--prev {
    left: 4px;
  }

  .fb__nav--next {
    right: 4px;
  }
}

@media (prefers-reduced-motion:reduce) {

  .fb,
  .fb__panel,
  .fb__leaf {
    transition: none;
  }
}


/* ==========================================================================
   LIGHT FORM FIELDS
   shared.css styles .field for a dark ground (the donate bar and header).
   campaign.css re-themes it for light grounds twice, each time scoped to one
   component (.donate-form, .demo). This is the same re-theme as a reusable
   class so a new light form does not need a third copy. Declared here, after
   campaign.css, so it also wins inside those components.
   ========================================================================= */
.form-light .field {
  background-color: var(--white);
  border: 1.5px solid var(--line);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(21, 19, 18, .04);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}

.form-light .field:hover {
  border-color: var(--line-2);
}

.form-light .field::placeholder {
  color: var(--ink-3);
}

.form-light .field:focus-visible {
  outline: none;
  border-color: var(--red);
  box-shadow: 0 0 0 4px var(--red-tint);
}

.form-light .field--select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.form-light .amount__sym {
  color: var(--ink-3);
}

/* A button that is present but not yet usable — the Zakat "pay" action before
   anything has been entered. Deliberately still focusable and readable; it
   explains itself rather than vanishing. */
.btn--disabled {
  opacity: .45;
  pointer-events: none;
}


/* ==========================================================================
   ZAKAT CALCULATOR
   ========================================================================= */
.zcalc {
  display: grid;
  grid-template-columns: 1.35fr .65fr;
  gap: clamp(24px, 3vw, 44px);
  align-items: start;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

@media (max-width:960px) {
  .zcalc {
    grid-template-columns: 1fr;
  }
}

.zgroups {
  display: grid;
  gap: 16px;
}

.zgroup {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(20px, 2.4vw, 28px);
  box-shadow: var(--sh-1);
}

.zgroup__head {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-bottom: 6px;
}

.zgroup__head .icon {
  width: 26px;
  height: 26px;
  color: var(--red);
  flex: none;
}

.zgroup__head h3 {
  margin: 0;
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: -.015em;
}

.zgroup__hint {
  margin: 0 0 18px;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink-3);
}

.zgroup--minus .zgroup__head .icon {
  color: var(--ink-3);
}

/* One row per figure. Label and input sit on one line on desktop so a long
   list of them stays scannable, and stack on narrow screens. */
.zrow {
  display: grid;
  grid-template-columns: 1fr 190px;
  align-items: center;
  gap: 14px;
  padding: 11px 0;
  border-top: 1px solid var(--line);
}

.zrow:first-of-type {
  border-top: 0;
}

.zrow label {
  font-size: .92rem;
  color: var(--ink-2);
}

.zrow .amount {
  width: 100%;
}

.zrow .field {
  width: 100%;
  padding-left: 26px;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

@media (max-width:560px) {
  .zrow {
    grid-template-columns: 1fr;
    gap: 7px;
  }

  .zrow .field {
    text-align: left;
  }
}

/* ------------------------------------------------------------- summary  */
.zsum {
  position: sticky;
  top: calc(var(--header-h, 86px) + 16px);
  background: var(--maroon);
  color: var(--on-dark-2);
  border-radius: var(--r-lg);
  padding: clamp(22px, 2.4vw, 30px);
  box-shadow: var(--sh-3);
}

.zsum h2 {
  margin: 0 0 4px;
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
}

.zsum__sub {
  margin: 0 0 22px;
  font-size: .8rem;
  color: var(--on-dark-3);
}

.zsum__rows {
  margin: 18px 0 0;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, .16);
  display: grid;
  gap: 12px;
}

.zsum__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: .9rem;
}

.zsum__row dt {
  color: var(--on-dark-3);
}

.zsum__row dd {
  margin: 0;
  font-weight: 700;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.zsum__rule {
  height: 1px;
  background: rgba(255, 255, 255, .16);
  margin: 18px 0;
}

.zsum__total {
  display: block;
  margin: 0;
}

.zsum__total dt {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-dark);
  margin-bottom: 6px;
}

.zsum__total dd {
  margin: 0;
  font-size: clamp(2rem, 4vw, 2.7rem);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.zsum__note {
  margin: 16px 0 20px;
  font-size: .8rem;
  line-height: 1.55;
  color: var(--on-dark-3);
}

/* Draw the eye to the figure the moment it moves. Without this the number
   changes silently somewhere the reader is not looking, which is exactly the
   complaint: you type into the form and nothing tells you where the answer
   appeared. */
@keyframes zsumPulse {
  0% { transform: scale(1); }
  28% { transform: scale(1.045); }
  100% { transform: scale(1); }
}

.zsum__total dd {
  transform-origin: left center;
}

.zsum__total dd.is-changed {
  animation: zsumPulse .42s var(--ease);
}

@media (prefers-reduced-motion:reduce) {
  .zsum__total dd.is-changed {
    animation: none;
  }
}

/* Fold for the workings. Desktop shows them permanently, so the control is
   hidden there and only appears where space actually forces the choice. */
.zsum__payfull {
  display: inline;
}

.zsum__more {
  display: none;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  padding: 0;
  font-size: .78rem;
  font-weight: 700;
  color: var(--accent-dark);
}

.zsum__more .caret {
  width: 11px;
  height: 11px;
  transition: transform .2s var(--ease);
}

.zsum__more[aria-expanded="true"] .caret {
  transform: rotate(180deg);
}

.zsum.is-due .zsum__note {
  color: var(--accent-dark);
}

.zsum__actions {
  display: grid;
  gap: 9px;
}

.zsum__actions .btn {
  justify-content: center;
}

.zsum__policy {
  margin: 18px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .16);
  font-size: .8rem;
}

/* Below 960px the summary stops being a sidebar and becomes a compact bar
   pinned above the donate bar. The running total has to stay visible while you
   are still filling the form — that is the whole point of it — and a 600px
   panel cannot do that on a phone, so the breakdown rows collapse and only the
   figure, the explanation and the actions remain.

   .zcalc also drops to `display:block` here. A sticky grid ITEM is confined to
   its own grid area, which is only as tall as the panel itself, so it would
   never actually stick; as a block child of the form its containing block is
   the whole form and it travels the full scroll. */
/* Below 960px the summary stops being a sidebar and becomes a bar pinned above
   the fold's bottom edge. It has to stay SMALL: this is a form, and a bar that
   eats a third of the screen is a bar that hides the fields you are filling in.
   Collapsed it is one line of figure plus a button — everything else (the
   explanation, the four workings rows, Clear) lives behind the chevron.

   .zcalc also drops to `display:block` here. A sticky grid ITEM is confined to
   its own grid area, which is only as tall as the panel itself, so it would
   never actually stick; as a block child of the form its containing block is
   the whole form and it travels the full scroll. */
@media (max-width:960px) {
  .zcalc {
    display: block;
  }

  .zsum {
    position: sticky;
    top: auto;
    bottom: 10px;
    z-index: 20;
    margin-top: 18px;
    padding: 11px 14px 12px;
    border: 1px solid rgba(255, 255, 255, .18);
    box-shadow: 0 -6px 28px rgba(74, 14, 16, .28), var(--sh-3);

    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    column-gap: 12px;
  }

  .zsum h2,
  .zsum__sub,
  .zsum__policy {
    display: none;
  }

  .zsum__total {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
  }

  .zsum__total dt {
    font-size: .6rem;
    letter-spacing: .12em;
    margin-bottom: 1px;
  }

  .zsum__total dd {
    font-size: clamp(1.55rem, 7vw, 1.95rem);
  }

  /* The toggle is a chevron tucked beside the figure, not a labelled row of
     its own — a whole line for "Show the workings" is a line this bar cannot
     spare. The label stays in the DOM for screen readers. */
  .zsum__more {
    display: inline-flex;
    grid-column: 1;
    grid-row: 2;
    margin: 2px 0 0;
    padding: 2px 0;
    font-size: .68rem;
    font-weight: 600;
    color: var(--on-dark-3);
  }

  .zsum__more .caret {
    width: 9px;
    height: 9px;
  }

  .zsum__actions {
    grid-column: 2;
    grid-row: 1 / span 2;
    grid-auto-flow: row;
    justify-items: end;
    gap: 4px;
  }

  .zsum__actions .btn--lg {
    padding: 11px 18px;
    font-size: .88rem;
  }

  /* Clear is a text link, and only once there is something to clear. */
  .zsum__actions #zReset {
    padding: 0;
    border: 0;
    background: none;
    font-size: .72rem;
    font-weight: 600;
    color: var(--on-dark-3);
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .zsum:not(.is-due):not(.is-under) .zsum__actions #zReset {
    visibility: hidden;
  }

  /* Everything that only matters once you go looking. */
  .zsum__note,
  .zsum__rows {
    display: none;
    grid-column: 1 / -1;
  }

  /* The note stays out on the two states where the number cannot speak for
     itself: nothing entered yet (it says where the answer will appear) and
     below the Nisab (it says why the answer is zero). Once real Zakat is due,
     the figure is the message and the note folds away to keep the bar short. */
  .zsum:not(.is-due) .zsum__note,
  .zsum.is-open .zsum__note {
    display: block;
    margin: 9px 0 0;
    font-size: .74rem;
    line-height: 1.45;
  }

  .zsum.is-open .zsum__rows {
    display: grid;
    margin-top: 10px;
    padding-top: 10px;
    gap: 8px;
  }

  .zsum.is-open .zsum__row {
    font-size: .8rem;
  }

  /* Two stacked bars is too much of a small screen, and on this page the Zakat
     bar IS the donate call to action — "Pay $300.00" beats the generic
     quick-donate strip. So the site bar stands down here, and the body padding
     that reserved room for it goes with it. The class is added by zakat.js, so
     no other page is affected. */
  body.has-zakat-bar {
    padding-bottom: 0;
  }

  body.has-zakat-bar .donatebar {
    display: none;
  }
}

/* On a phone the button drops "my Zakat" and keeps the amount, which is the
   half that matters. */
@media (max-width:520px) {
  .zsum__payfull {
    display: none;
  }
}


/* ==========================================================================
   POLICY PAGES
   One layout, used by every legal/policy document — privacy, donation, Zakat,
   the Donor Bill of Rights. A sticky contents rail beside a single measured
   column of prose. To add another policy page, copy privacy-policy.html and
   change the <h2 id> anchors, the TOC list and the prose. Nothing here is
   privacy-specific.
   ========================================================================= */
.policy {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: start;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

@media (max-width:900px) {
  .policy {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------------------- toc */
.policy__toc {
  position: sticky;
  top: calc(var(--header-h, 86px) + 20px);
}

.policy__toc h2 {
  margin: 0 0 14px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.policy__toc ol {
  counter-reset: toc;
  display: grid;
  gap: 2px;
}

.policy__toc a {
  display: block;
  padding: 7px 12px 7px 0;
  border-left: 2px solid var(--line);
  padding-left: 14px;
  font-size: .86rem;
  line-height: 1.4;
  color: var(--ink-2);
  text-decoration: none;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}

.policy__toc a:hover,
.policy__toc a.is-on {
  color: var(--red-dark);
  border-left-color: var(--red);
}

/* Below the two-column breakpoint the rail becomes a plain block of links at
   the top of the document — a sticky sidebar has nowhere to sit. */
@media (max-width:900px) {
  .policy__toc {
    position: static;
    padding: 20px 22px;
    background: var(--sand);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
  }

  .policy__toc ol {
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  }
}

/* ------------------------------------------------------------------ prose
   A policy is read, not skimmed, so this is a single measured column with
   generous leading — not the 68ch .spine used for marketing copy. */
.policy__body {
  max-width: 74ch;
}

.policy__body h2 {
  margin: clamp(38px, 5vw, 56px) 0 14px;
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  font-weight: 700;
  letter-spacing: -.02em;
  scroll-margin-top: calc(var(--header-h, 86px) + 24px);
}

.policy__body h2:first-child {
  margin-top: 0;
}

.policy__body h3 {
  margin: 26px 0 10px;
  font-size: 1rem;
  font-weight: 700;
}

.policy__body p {
  margin: 0 0 1.05em;
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink-2);
}

.policy__body strong {
  color: var(--ink);
  font-weight: 700;
}

.policy__body ul {
  margin: 0 0 1.3em;
  display: grid;
  gap: 9px;
}

.policy__body li {
  position: relative;
  padding-left: 22px;
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-2);
}

.policy__body li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 7px;
  height: 2px;
  background: var(--red);
}

.policy__body a:not(.btn) {
  color: var(--red-dark);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

/* Contact / "who to write to" block that closes most policies. */
.policy__contact {
  margin-top: clamp(34px, 4vw, 48px);
  padding: clamp(22px, 2.6vw, 30px);
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

.policy__contact h2 {
  margin-top: 0;
}

.policy__contact p:last-child {
  margin-bottom: 0;
}

/* The "last updated" line under a policy banner. Sits on the page's own
   (light) background — not inside the banner itself, unlike the prototype's
   original placement — so it uses sand/ink tones rather than on-dark ones. */
.policy__stamp {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 clamp(20px, 3vw, 32px);
  padding: 7px 15px;
  border-radius: var(--r-pill);
  background: var(--sand);
  border: 1px solid var(--line);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink-2);
}

.policy__stamp svg {
  width: 14px;
  height: 14px;
  color: var(--red-dark);
}

/* Sibling policies, listed at the foot of each one. */
.policy__siblings {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: var(--gap);
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}


/* ==========================================================================
   EVENTS
   ========================================================================= */
.efeature {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(24px, 4vw, 52px);
  align-items: center;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

@media (max-width:820px) {
  .efeature {
    grid-template-columns: 1fr;
  }
}

/* Event posters are portrait 4:5 creatives, not landscape banners. */
.eposter {
  position: relative;
  aspect-ratio: 4/5;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--maroon-2);
  box-shadow: var(--sh-3);
}

.eposter img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Date block, over the poster on the feature and inline on the cards. */
.edate {
  display: inline-grid;
  justify-items: center;
  gap: 1px;
  padding: 9px 14px;
  border-radius: var(--r-md);
  background: var(--red);
  color: #fff;
  line-height: 1;
}

.edate b {
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.edate span {
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: .92;
}

/* .eplate is absolutely positioned, so it paints over any static sibling —
   the badge has to be positioned too, or it disappears behind the poster. */
.eposter .edate,
.ecard__media .edate {
  position: absolute;
  z-index: 1;
  top: 12px;
  left: 12px;
  box-shadow: var(--sh-2);
}

.eposter .edate {
  top: 14px;
  left: 14px;
}

.ecard__media .edate {
  padding: 7px 11px;
}

.ecard__media .edate b {
  font-size: 1.15rem;
}

.efeature h3 {
  margin: 14px 0 12px;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.12;
  letter-spacing: -.026em;
}

.emeta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}

.emeta li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: var(--white);
  border: 1px solid var(--line);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink-2);
}

.emeta svg {
  width: 12px;
  height: 12px;
  color: var(--red);
  flex: none;
}

/* ------------------------------------------------------------ event cards */
.ecards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  gap: var(--gap);
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

.ecard {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-decoration: none;
  box-shadow: var(--sh-1);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}

.ecard:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-3);
  border-color: #EDD2CF;
}

.ecard__media {
  position: relative;
  aspect-ratio: 4/5;
  background: var(--maroon-2);
  overflow: hidden;
}

.ecard__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease);
}

.ecard:hover .ecard__media img {
  transform: scale(1.04);
}

.ecard__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px 18px;
  flex: 1;
}

.ecard__when {
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--red-dark);
}

.ecard h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -.012em;
  flex: 1;
}

.ecard__where {
  font-size: .82rem;
  color: var(--ink-3);
}

/* A past event is documentation, not an invitation — muted, and it says so. */
.ecard--past .ecard__media {
  filter: saturate(.55);
}

.ecard--past:hover .ecard__media {
  filter: none;
}

.ecard--past .ecard__when {
  color: var(--ink-3);
}

/* Poster stand-in: the prototype ships no event creatives, so cards render a
   patterned maroon plate with the event's initials instead of a broken image. */
.eplate {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(135deg, rgba(255, 190, 185, .07) 0 1px, transparent 1px 14px),
    linear-gradient(160deg, var(--maroon) 0%, var(--maroon-2) 100%);
  color: var(--accent-dark);
  font-family: var(--serif);
  font-size: 2.4rem;
  letter-spacing: .04em;
}


/* Inline code, for the handful of places a path or command has to appear in
   body copy (the file:// notice on reports.html). */
code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88em;
  padding: 1px 6px;
  border-radius: 5px;
  background: rgba(74, 14, 16, .07);
  border: 1px solid var(--line);
  color: var(--maroon);
  white-space: nowrap;
}


/* `hidden` must actually hide.
   The attribute's UA rule is `display:none` at zero specificity, so ANY class
   that sets display beats it — .ecard{display:flex}, .jobrow{display:grid},
   .doc--cover{display:flex} all silently ignored it, which is why the pager
   appeared to do nothing. Anything toggled with el.hidden depends on this. */
[hidden] {
  display: none !important;
}


/* ==========================================================================
   PAGER
   Built by pager.js into an empty <nav class="pager">. Without JS the nav
   stays empty and every item renders — the right fallback for a listing.
   ========================================================================= */
.pager__status {
  margin: clamp(20px, 2.4vw, 28px) 0 0;
  text-align: center;
  font-size: .82rem;
  color: var(--ink-3);
}

.band--maroon .pager__status,
.band--dark .pager__status,
.band--lattice .pager__status,
.band--contour .pager__status {
  color: var(--on-dark-3);
}

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 12px;
}

.pager:empty {
  display: none;
}

.pager__pages {
  display: flex;
  align-items: center;
  gap: 6px;
}

.pager__btn {
  min-width: 38px;
  height: 38px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--line-2);
  background: var(--white);
  font-size: .88rem;
  font-weight: 700;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  transition: border-color .18s var(--ease), background-color .18s var(--ease), color .18s var(--ease);
}

.pager__btn:hover {
  border-color: var(--red);
  color: var(--red-dark);
}

.pager__btn.is-on {
  background: var(--maroon);
  border-color: var(--maroon);
  color: #fff;
}

/* .rnd already carries the round-button chrome; this only sizes it down to
   match the numbered buttons beside it. */
.pager__nav {
  width: 38px;
  height: 38px;
  flex: none;
}

.pager__nav svg {
  width: 15px;
  height: 15px;
}

/* A card given focus by the pager must not draw a focus ring — the user
   clicked a page number, they did not tab to a card. */
.ecard[tabindex="-1"]:focus,
.ccard[tabindex="-1"]:focus,
.doc[tabindex="-1"]:focus {
  outline: none;
}

@media (max-width:480px) {
  .pager {
    gap: 6px;
  }

  .pager__btn {
    min-width: 34px;
    height: 34px;
    font-size: .82rem;
  }

  .pager__nav {
    width: 34px;
    height: 34px;
  }
}


/* A small label dividing one band into parts — "Also coming up" above the
   events grid that follows the featured event. Shell width, so it lines up
   with the grid beneath it. */
.c-subhead {
  max-width: var(--shell);
  margin: clamp(30px, 4vw, 44px) auto clamp(14px, 1.8vw, 20px);
  padding-inline: clamp(18px, 4vw, 32px);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.band--maroon .c-subhead,
.band--dark .c-subhead,
.band--lattice .c-subhead,
.band--contour .c-subhead {
  color: var(--on-dark-3);
}
