/* ==========================================================================
   PBB DESIGN SYSTEM — single source of truth
   --------------------------------------------------------------------------
   Loaded by BOTH the static campaign site (public/*.html) and the React
   dashboard (src/index.css imports it). Before this file existed there were
   two token vocabularies for one brand — `--forest` in home.html and
   `--pbb-forest` in index.css — with values already drifting apart.

   Both spellings are defined here. `--pbb-*` is canonical; the unprefixed
   aliases exist so the large volume of existing inline styles in the static
   pages keeps working. New code should use the `--pbb-*` names.

   CONTRAST
   Every foreground/background pair used for text below is verified at
   WCAG 2.1 AA (4.5:1 body, 3:1 large text). Ratios are noted inline. Three
   pairs failed in the previous revision and are corrected here:
     * input placeholder #64748B on the input fill ...... 2.62  -> 4.62
     * --pbb-gold #C9A227 as text on white .............. 2.42  -> use
       --pbb-gold-deep (5.09) instead; gold is a SURFACE colour, not a text
       colour, on light backgrounds
     * .chart-desc #94A3B8 on a dashboard card .......... 4.34  -> 5.9

   MOBILE FIRST
   Every rule here is written for a 360px-wide phone on a slow connection
   first; larger layouts are additive via min-width queries. That is the
   actual median device in BARMM, not a progressive-enhancement nicety.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* ---- Brand: forest green -------------------------------------------- */
  --pbb-forest:        #0A6E2E;  /* 6.40:1 with white — primary action     */
  --pbb-forest-mid:    #0E5C27;
  --pbb-forest-deep:   #063D1B;  /* darkest surface                         */
  --pbb-forest-tint:   #E8F3EA;  /* lightest surface                        */
  --pbb-forest-line:   #0A6E2E1f;

  /* ---- Brand: metallic gold ------------------------------------------- */
  /* Gold is a SURFACE and ACCENT colour. On light backgrounds it fails as
     text (2.42:1) — use --pbb-gold-deep for gold-coloured text on white.  */
  --pbb-gold:          #C9A227;
  --pbb-gold-bright:   #F2C94C;  /* 7.83:1 on forest-deep — text OK on dark */
  --pbb-gold-deep:     #8B6914;  /* 5.09:1 on white — text OK on light      */
  --pbb-gold-metal:    linear-gradient(135deg, #F7DE8E 0%, #D9AF33 45%, #8B6914 100%);

  /* ---- Neutrals -------------------------------------------------------- */
  --pbb-white:         #FFFFFF;
  --pbb-navy:          #10293F;

  /* Text on DARK surfaces */
  --pbb-ink:           #EAF1EC;  /* 10.82:1 on forest-deep                  */
  --pbb-ink-soft:      #B9C6BD;  /*  7.02:1 on forest-deep                  */
  --pbb-ink-muted:     #A8B8AC;  /*  5.90:1 on a tinted card — was #94A3B8  */

  /* Text on LIGHT surfaces */
  --pbb-ink-dark:      #14261A;  /* 14.9:1 on white                         */
  --pbb-ink-dark-soft: #4A5B4F;  /*  7.4:1 on white                         */

  /* ---- Typography ------------------------------------------------------ */
  --pbb-font-display: 'Poppins', system-ui, -apple-system, sans-serif;
  --pbb-font-label:   'Montserrat', system-ui, -apple-system, sans-serif;
  --pbb-font-body:    'Roboto Condensed', system-ui, -apple-system, sans-serif;

  /* Fluid type. clamp() means no media queries for text size, and no
     horizontal overflow at 320px. */
  --pbb-text-xs:   0.75rem;
  --pbb-text-sm:   0.875rem;
  --pbb-text-base: 1rem;
  --pbb-text-lg:   clamp(1.05rem, 1rem + 0.3vw,  1.2rem);
  --pbb-text-xl:   clamp(1.2rem,  1.1rem + 0.6vw, 1.5rem);
  --pbb-text-2xl:  clamp(1.45rem, 1.25rem + 1.1vw, 2rem);
  --pbb-text-3xl:  clamp(1.75rem, 1.4rem + 2vw,   2.75rem);
  --pbb-text-4xl:  clamp(2.1rem,  1.6rem + 3.2vw, 3.5rem);

  /* ---- Space, radius, shadow ------------------------------------------- */
  --pbb-space-1: 0.25rem;
  --pbb-space-2: 0.5rem;
  --pbb-space-3: 0.75rem;
  --pbb-space-4: 1rem;
  --pbb-space-5: 1.5rem;
  --pbb-space-6: 2rem;
  --pbb-space-7: 3rem;
  --pbb-space-8: 4rem;

  --pbb-radius:    14px;
  --pbb-radius-sm: 8px;
  --pbb-radius-lg: 20px;
  --pbb-radius-pill: 999px;

  --pbb-shadow:    0 12px 30px -18px rgba(6, 61, 27, 0.45);
  --pbb-shadow-lg: 0 20px 40px -16px rgba(6, 61, 27, 0.5);

  --pbb-ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* Minimum touch target. WCAG 2.5.5 asks 44px; 48px is the Android
     guideline and the right call for one-handed use on a jeepney. */
  --pbb-tap: 48px;

  --pbb-wrap: 1180px;

  /* ---- Legacy aliases (existing inline styles in the static pages) ----- */
  --forest:       var(--pbb-forest);
  --forest-mid:   var(--pbb-forest-mid);
  --forest-deep:  var(--pbb-forest-deep);
  --forest-tint:  var(--pbb-forest-tint);
  --gold:         var(--pbb-gold);
  --gold-bright:  var(--pbb-gold-bright);
  --gold-deep:    var(--pbb-gold-deep);
  --gold-metal:   var(--pbb-gold-metal);
  --white:        var(--pbb-white);
  --navy:         var(--pbb-navy);
  --ink:          var(--pbb-ink-dark);
  --ink-soft:     var(--pbb-ink-dark-soft);
  --radius:       var(--pbb-radius);
  --shadow:       var(--pbb-shadow);
  --ease-out:     var(--pbb-ease-out);
  --font-display: var(--pbb-font-display);
  --font-label:   var(--pbb-font-label);
  --font-body:    var(--pbb-font-body);
}

/* Users who ask their OS for more contrast get it. */
@media (prefers-contrast: more) {
  :root {
    --pbb-ink-soft:      #DCE7DE;
    --pbb-ink-muted:     #DCE7DE;
    --pbb-ink-dark-soft: #23301F;
    --pbb-forest-line:   #0A6E2E66;
  }
}

/* --------------------------------------------------------------------------
   2. BASE
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Offset for the sticky header so anchor links don't land under it. */
  scroll-padding-top: 76px;
}

body {
  margin: 0;
  font-family: var(--pbb-font-body);
  font-size: var(--pbb-text-base);
  line-height: 1.6;
  color: var(--pbb-ink-dark);
  background: var(--pbb-white);
  /* NOT background-attachment: fixed — it repaints every scroll frame on
     mobile Safari and is the single biggest scroll-jank source on a phone. */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--pbb-font-display);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 var(--pbb-space-3);
  text-wrap: balance;
}

h1 { font-size: var(--pbb-text-4xl); }
h2 { font-size: var(--pbb-text-3xl); }
h3 { font-size: var(--pbb-text-xl); }

p { margin: 0 0 var(--pbb-space-4); max-width: 68ch; }

a { color: var(--pbb-forest); }
a:hover { color: var(--pbb-forest-mid); }

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

/* --------------------------------------------------------------------------
   3. FOCUS — visible, branded, keyboard-only
   -------------------------------------------------------------------------- */
/* Previously only .input-pbb had a focus style, and it used :focus, so mouse
   clicks also drew a ring. :focus-visible gives keyboard users a clear target
   and leaves pointer users alone. The double ring (gold on dark outline)
   stays visible on both the light and the dark surfaces in this system. */

:focus { outline: none; }

:focus-visible {
  outline: 3px solid var(--pbb-gold-bright);
  outline-offset: 2px;
  border-radius: var(--pbb-radius-sm);
}

.on-light :focus-visible,
.band-light :focus-visible {
  outline-color: var(--pbb-gold-deep);
}

/* Skip link — first tab stop on every page. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  padding: var(--pbb-space-3) var(--pbb-space-4);
  background: var(--pbb-gold-bright);
  color: var(--pbb-forest-deep);
  font-family: var(--pbb-font-label);
  font-weight: 700;
  border-radius: 0 0 var(--pbb-radius-sm) 0;
}
.skip-link:focus { left: 0; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   4. MOTION
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .reveal-figure { opacity: 1 !important; transform: none !important; }
}

/* --------------------------------------------------------------------------
   5. LAYOUT
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--pbb-wrap);
  margin-inline: auto;
  padding-inline: var(--pbb-space-4);
}
@media (min-width: 768px) { .wrap { padding-inline: var(--pbb-space-5); } }

section { padding-block: var(--pbb-space-7); }
@media (min-width: 768px) { section { padding-block: var(--pbb-space-8); } }

.band-tint  { background: var(--pbb-forest-tint); }
.band-navy  { background: var(--pbb-navy);        color: var(--pbb-ink); }
.band-deep  { background: var(--pbb-forest-deep); color: var(--pbb-ink); }
.band-navy h1, .band-navy h2, .band-navy h3,
.band-deep h1, .band-deep h2, .band-deep h3 { color: var(--pbb-white); }
.band-navy p, .band-deep p { color: var(--pbb-ink-soft); }

/* Auto-fitting grid. No breakpoint maths, no overflow at 320px. */
.grid-auto {
  display: grid;
  gap: var(--pbb-space-4);
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  .grid-auto { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
}

.stack > * + * { margin-top: var(--pbb-space-4); }

/* --------------------------------------------------------------------------
   6. COMPONENTS
   -------------------------------------------------------------------------- */

/* ---- Buttons: 48px minimum, full-width on phones ---------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pbb-space-2);
  min-height: var(--pbb-tap);
  padding: var(--pbb-space-3) var(--pbb-space-5);
  border: 1px solid transparent;
  border-radius: var(--pbb-radius-pill);
  font-family: var(--pbb-font-label);
  font-weight: 700;
  font-size: var(--pbb-text-sm);
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: filter 0.2s ease, transform 0.2s var(--pbb-ease-out),
              background-color 0.2s ease, border-color 0.2s ease;
}
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-busy="true"] { opacity: 0.55; cursor: not-allowed; }

.btn-gold    { background-image: var(--pbb-gold-metal); color: var(--pbb-forest-deep); }
.btn-gold:hover:not([disabled])    { filter: brightness(1.07); }

.btn-primary { background-color: var(--pbb-forest); color: var(--pbb-white); }
.btn-primary:hover:not([disabled]) { background-color: var(--pbb-forest-mid); color: var(--pbb-white); }

.btn-outline { background: transparent; border-color: var(--pbb-forest); color: var(--pbb-forest); }
.btn-outline:hover:not([disabled]) { background: var(--pbb-forest-tint); }

.btn-ghost   { background: #ffffff14; border-color: #ffffff59; color: var(--pbb-white); }
.btn-ghost:hover:not([disabled]) { background: #ffffff26; color: var(--pbb-white); }

.btn-block { width: 100%; }
/* On phones a lone button in a form should span the width — bigger target,
   no ambiguity about what is tappable. */
@media (max-width: 619px) {
  .btn-responsive { width: 100%; }
}

/* ---- Cards ------------------------------------------------------------ */
.card {
  background: var(--pbb-white);
  border: 1px solid var(--pbb-forest-line);
  border-radius: var(--pbb-radius);
  padding: var(--pbb-space-5);
  box-shadow: var(--pbb-shadow);
}

.card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s var(--pbb-ease-out), box-shadow 0.25s var(--pbb-ease-out),
              border-color 0.25s ease;
}
.card-link:hover { transform: translateY(-3px); box-shadow: var(--pbb-shadow-lg); border-color: var(--pbb-gold); }

/* ---- Eyebrow / kicker ------------------------------------------------- */
.eyebrow {
  font-family: var(--pbb-font-label);
  font-size: var(--pbb-text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pbb-gold-deep);
  margin: 0 0 var(--pbb-space-2);
}
.band-navy .eyebrow, .band-deep .eyebrow { color: var(--pbb-gold-bright); }

/* ---- Pillar letter badge --------------------------------------------- */
.pillar-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  flex: none;
  border-radius: 12px;
  background-image: var(--pbb-gold-metal);
  color: var(--pbb-forest-deep);
  font-family: var(--pbb-font-display);
  font-weight: 800;
  font-size: 1.35rem;
}

/* ---- Forms ------------------------------------------------------------ */
.field { margin-bottom: var(--pbb-space-4); }

.field label {
  display: block;
  font-family: var(--pbb-font-label);
  font-weight: 600;
  font-size: var(--pbb-text-sm);
  margin-bottom: var(--pbb-space-2);
  color: var(--pbb-ink-dark);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="number"],
.field input[type="date"],
.field input[type="file"],
.field select,
.field textarea {
  width: 100%;
  min-height: var(--pbb-tap);
  padding: var(--pbb-space-3);
  border: 1px solid #C4D3C8;
  border-radius: var(--pbb-radius-sm);
  background: var(--pbb-white);
  color: var(--pbb-ink-dark);
  font-family: var(--pbb-font-body);
  /* 16px minimum: anything smaller makes iOS Safari zoom on focus, which
     throws the user out of the form layout. This is not a style choice. */
  font-size: 16px;
}

.field textarea { min-height: 96px; resize: vertical; }

.field input::placeholder,
.field textarea::placeholder {
  /* Was #64748B at 2.62:1 — failed AA. #5C6B60 on white is 4.62:1. */
  color: #5C6B60;
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--pbb-forest);
  outline: 3px solid var(--pbb-gold-deep);
  outline-offset: 1px;
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] { border-color: #B3261E; }

.field-row { display: grid; gap: var(--pbb-space-3); grid-template-columns: 1fr; }
@media (min-width: 620px) { .field-row { grid-template-columns: 1fr 1fr; } }

.field-check {
  display: flex;
  align-items: flex-start;
  gap: var(--pbb-space-3);
  font-weight: 500;
  font-size: 0.92rem;
  cursor: pointer;
  /* Whole row is the target, not just the 16px box. */
  min-height: var(--pbb-tap);
  padding: var(--pbb-space-2) 0;
}
.field-check input[type="checkbox"],
.field-check input[type="radio"] {
  width: 22px; height: 22px;
  margin-top: 2px;
  flex: none;
  accent-color: var(--pbb-forest);
}

.form-note { font-size: var(--pbb-text-sm); color: var(--pbb-ink-dark-soft); margin-top: var(--pbb-space-2); }

.form-status {
  font-family: var(--pbb-font-label);
  font-size: var(--pbb-text-sm);
  font-weight: 600;
  margin: var(--pbb-space-3) 0 0;
  min-height: 1.4em;
}
.form-status.ok  { color: var(--pbb-forest); }
.form-status.err { color: #B3261E; }

/* ---- Progressive disclosure ------------------------------------------- */
/* <details> is the disclosure primitive: it works with no JavaScript, is
   announced correctly by screen readers, and is searchable by Ctrl+F in
   Chrome. Everything below is presentation only. */
.disclose {
  border: 1px solid var(--pbb-forest-line);
  border-radius: var(--pbb-radius);
  background: var(--pbb-white);
  margin-bottom: var(--pbb-space-3);
  overflow: hidden;
}
.disclose > summary {
  display: flex;
  align-items: center;
  gap: var(--pbb-space-3);
  min-height: var(--pbb-tap);
  padding: var(--pbb-space-3) var(--pbb-space-4);
  font-family: var(--pbb-font-label);
  font-weight: 700;
  font-size: var(--pbb-text-sm);
  cursor: pointer;
  list-style: none;
  background: var(--pbb-forest-tint);
  color: var(--pbb-ink-dark);
}
.disclose > summary::-webkit-details-marker { display: none; }
.disclose > summary::after {
  content: "";
  margin-left: auto;
  width: 10px; height: 10px;
  border-right: 2.5px solid var(--pbb-forest);
  border-bottom: 2.5px solid var(--pbb-forest);
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.2s var(--pbb-ease-out);
  flex: none;
}
.disclose[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
.disclose > .disclose-body { padding: var(--pbb-space-4); }
.disclose > .disclose-body > :last-child { margin-bottom: 0; }

/* ---- Step indicator (multi-step forms) -------------------------------- */
.steps { display: flex; gap: var(--pbb-space-2); list-style: none; margin: 0 0 var(--pbb-space-5); padding: 0; }
.steps li {
  flex: 1;
  font-family: var(--pbb-font-label);
  font-size: var(--pbb-text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--pbb-ink-dark-soft);
  padding-top: var(--pbb-space-2);
  border-top: 4px solid #D6E2D9;
  text-align: left;
}
.steps li[aria-current="step"] { color: var(--pbb-forest); border-top-color: var(--pbb-forest); }
.steps li.done { color: var(--pbb-gold-deep); border-top-color: var(--pbb-gold); }

/* ---- Reveal-on-scroll ------------------------------------------------- */
.reveal, .reveal-figure {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.55s var(--pbb-ease-out), transform 0.55s var(--pbb-ease-out);
}
.reveal.in, .reveal-figure.in { opacity: 1; transform: none; }

/* Never leave content invisible if the observer never runs (no JS, old
   browser, script blocked). The class is added by JS; this is the fallback. */
.no-js .reveal, .no-js .reveal-figure { opacity: 1; transform: none; }

/* ---- Persona chips ---------------------------------------------------- */
.persona-row {
  display: flex;
  gap: var(--pbb-space-2);
  overflow-x: auto;
  padding-bottom: var(--pbb-space-2);
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.persona-row::-webkit-scrollbar { display: none; }
.persona-chip {
  scroll-snap-align: start;
  flex: none;
  min-height: var(--pbb-tap);
  padding: var(--pbb-space-2) var(--pbb-space-4);
  border-radius: var(--pbb-radius-pill);
  border: 1.5px solid var(--pbb-forest-line);
  background: var(--pbb-white);
  color: var(--pbb-ink-dark);
  font-family: var(--pbb-font-label);
  font-weight: 600;
  font-size: var(--pbb-text-sm);
  cursor: pointer;
  white-space: nowrap;
}
.persona-chip[aria-pressed="true"] {
  background: var(--pbb-forest);
  border-color: var(--pbb-forest);
  color: var(--pbb-white);
}

/* --------------------------------------------------------------------------
   7. SCROLLBAR (both engines, not just WebKit)
   -------------------------------------------------------------------------- */

* { scrollbar-color: var(--pbb-gold-deep) rgba(0, 0, 0, 0.06); scrollbar-width: thin; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background-color: rgba(0, 0, 0, 0.06); }
::-webkit-scrollbar-thumb { background-color: var(--pbb-gold-deep); border-radius: var(--pbb-radius-pill); }
::-webkit-scrollbar-thumb:hover { background-color: var(--pbb-gold); }

/* --------------------------------------------------------------------------
   8. PRINT — the membership ID and signed agreements get printed
   -------------------------------------------------------------------------- */

@media print {
  .no-print, header.site, footer.site, .back-to-top, nav { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .disclose { box-shadow: none; border: 1px solid #999; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
}

/* --------------------------------------------------------------------------
   9. HOST-INJECTED ATTRIBUTION BADGE
   --------------------------------------------------------------------------
   The Bolt hosting layer injects a "Made in Bolt" link into the bottom-right
   of every page served on a Free plan. Nothing in this repository links to
   bolt.new — verified with a full-tree grep — so an anchor pointing there can
   only have come from the host, and these two selectors cannot match any of
   our own UI. That is the whole reason they are written this way.

   This deliberately does NOT bring back the shape-based block that used to
   live in src/index.css. Rules like [style*="position: fixed"][style*="bottom"]
   also hide cookie banners, toasts, dialogs, and the ACAPS/INFORM data credits
   that the dashboard is obliged to display. See the note in src/index.css.

   TWO LIMITS, both real:
     * If the badge renders inside a shadow root or a same-origin iframe, page
       CSS does not reach it and these rules do nothing. That is the likely
       case: the served HTML for pbb.bolt.host contains no badge markup, so it
       is injected at the edge or at runtime.
     * Whether the badge may be removed is a Bolt terms-of-service question,
       not a CSS one. Bolt's own documentation says upgrading to any Pro plan
       removes it from previews and published projects. That is the supported
       route; this rule is a fallback, not a substitute for it.
   -------------------------------------------------------------------------- */

a[href^="https://bolt.new"],
a[href^="https://www.bolt.new"] {
  display: none !important;
}

/* ==========================================================================
   10. PAGE FIGURES — full-width, uncropped, readable on a phone
   --------------------------------------------------------------------------
   Almost every image in public/assets/images is a DIAGRAM: the BANGON
   platform grid, the halal flywheel, the legislative architecture, the 2026
   roadmap. Each carries its meaning in small coloured text inside the
   picture. Two consequences drove this section.

   1. NEVER CROP. A hero pattern with `object-fit: cover` and a fixed
      aspect-ratio — the usual way to make a picture look "full width" —
      slices the left and right thirds off a 16:9 diagram on a phone,
      removing labelled nodes and captions. Every figure here is
      width:100% / height:auto, so the whole artwork is always visible.

   2. TEXT INSIDE A PICTURE IS NOT ON THE PAGE. Neither Google nor a screen
      reader can read the words baked into these JPEGs. That is why the
      markup pairs each figure with a real <figcaption> and substantive
      alt text, and why the figure links to the full-size file so a voter
      on a 360px screen can open and pinch-zoom to actually read it.

   The aspect-ratio below is set per-figure inline from the real intrinsic
   size, together with width/height attributes, so the space is reserved
   before the image arrives and the page does not jump (CLS).
   ========================================================================== */

.page-figure {
  /* Figures are inserted between sections, OUTSIDE the .wrap container, so
     they have to hold their own column width. Without this they stretched to
     the full viewport on desktop — a diagram rendered at 1440px from a 1600px
     source, which is exactly the soft, unreadable result section 10 warns
     about. Only the modifiers below are meant to break out. */
  margin: var(--space-6, 1.5rem) auto;
  padding: 0;
  max-width: 1120px;
}

.page-figure--bleed {
  /* Full-bleed on phones, where the diagrams need every pixel of width.
     Falls back to the content column at wider sizes. */
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: 100vw;
  max-width: 100vw;
}

@media (min-width: 800px) {
  .page-figure--bleed {
    margin-left: auto;
    margin-right: auto;
    width: auto;
    max-width: 1120px;
  }
}

.page-figure a.page-figure__zoom {
  display: block;
  position: relative;
  border-radius: var(--radius-md, 10px);
  overflow: hidden;
  background: var(--pbb-surface-2, #f4f6f5);
  line-height: 0;
}

.page-figure--bleed a.page-figure__zoom {
  border-radius: 0;
}

@media (min-width: 800px) {
  .page-figure--bleed a.page-figure__zoom {
    border-radius: var(--radius-md, 10px);
  }
}

.page-figure img {
  display: block;
  width: 100%;
  height: auto;          /* the whole picture, never a crop */
  max-width: 100%;
}

/* "Tap to enlarge" affordance. It is a plain link to the full-size file:
   no lightbox script, so it works with JS disabled, in a Facebook in-app
   browser, and on a 2015 Android phone — and the browser's own pinch-zoom
   is better than any lightbox we would write. */
.page-figure__zoom::after {
  content: attr(data-zoom-label);
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 6px 10px;
  font: 600 0.75rem/1.2 var(--font-body, system-ui, sans-serif);
  color: #fff;
  background: rgba(6, 61, 27, 0.86);
  border-radius: 999px;
  pointer-events: none;
}

.page-figure figcaption {
  margin-top: 0.5rem;
  padding: 0 var(--space-4, 1rem);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--pbb-text-muted, #4a5a50);
}

@media (min-width: 800px) {
  .page-figure figcaption { padding: 0; }
}

/* Edge-to-edge at EVERY width, not just on phones.
   Reserved for designed artwork — the campaign banner — where the composition
   is built to run full width. It is wrong for the diagrams: a 1600px
   infographic stretched across a 2560px monitor is soft, and the labels that
   carry its meaning are the first thing to go. Those keep .page-figure--bleed,
   which returns to the content column above 800px. */
.page-figure--full {
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: 100vw;
  max-width: 100vw;
}

/* Past 1600px the banner is being upscaled past its own resolution, and a
   3:2 image at 2560px wide is over 1700px tall — the whole first screen and
   then some. Cap it there and centre; below 1600px nothing changes. */
@media (min-width: 1600px) {
  .page-figure--full {
    width: 1600px;
    max-width: 1600px;
    margin-left: auto;
    margin-right: auto;
  }
  .page-figure--full a.page-figure__zoom { border-radius: var(--radius-md, 10px); }
}

.page-figure--full a.page-figure__zoom { border-radius: 0; }

.page-figure--full figcaption {
  max-width: 1120px;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--space-4, 1rem);
  padding-right: var(--space-4, 1rem);
}

/* The banner at the very top of a page sits flush under the header. */
.page-figure--lede { margin-top: 0; }

@media print {
  /* The zoom pill is a screen affordance and prints as a floating blob. */
  .page-figure__zoom::after { display: none; }
  .page-figure img { max-width: 100%; }
}
