/* ============================================================================
   site.css - the design system.

   Binding source: docs/DESIGN-SPEC.md. Every rule below traces to a numbered
   section of that document; the numbers in comments are its section numbers.

   Load order (spec 2), and it is load-bearing:
       1. /vendor/bootstrap/bootstrap.min.css   reset + reboot only
       2. /css/site.css                         this file
       3. /css/legacy.css                       2011 compat, last

   What this file refuses (spec 0): no box-shadow used as elevation, no
   gradients except the two table scroll-shadows, no radius above 4px, no
   status pills, no icon fonts, no hero images, no serif, no webfont or
   font import, no vertical rules inside tables, no fourth rule weight, and
   no JavaScript required to read anything. The host is never typed here - it is
   read from app/config.php at render time.

   !important appears in three places and never for convenience: the mobile
   table tiers (spec 11.8), where it is the only thing that can beat 1,302
   inline width attributes and 490 inline margins; the print block (spec 19),
   where it un-clips the scroll wrappers and drops the chrome; and the
   .visually-hidden utility, copied verbatim from Bootstrap. Nowhere else.
   ============================================================================ */


/* ============================================================================
   1. TOKENS                                                          (spec 3)

   One state. Light is the only theme: the bare :root block below carries the
   COMPLETE palette, and the only other block that redefines a token is the
   print override at spec 19. No component rule may live inside a media query
   - a colour whose only definition sits behind a media gate never applies to
   the default state, which is what every viewer gets.

   Formatting note: token blocks put the opening brace on its own line. The
   spec-20 gate that polices --rb-text-faint reads the nearest brace-bearing
   line as the ruleset selector; Allman braces here keep that check honest
   without distorting the cascade.
   ============================================================================ */

:root
{
  color-scheme:light;

  /* -- 3.1 blue ramp. EU flag blue is the primary; the ramp is generated
        from it. Every step is measured against a white or a blue ground. */
  --rb-blue-25:#f7f8fa;    /* reserved. NOT the zebra - see correction 4      */
  --rb-blue-50:#eef2fb;    /* th ground, row hover, active rail ground        */
  --rb-blue-100:#dbe3f5;   /* legacy far5 remap ground, data-row hover 1.29 on
                              --rb-surface / 1.17 on --rb-zebra              */
  --rb-blue-200:#b8c7ea;   /* decorative dividers on tint                     */
  --rb-blue-300:#8aa2db;   /* breadcrumb separators                           */
  --rb-blue-400:#4d6ec4;   /* reserved mid-light step                         */
  --rb-blue-500:#2b52b0;   /* reserved mid-step                               */
  --rb-blue-600:#1b3f9e;   /* link hover, 9.33:1                              */
  --rb-blue-700:#003399;   /* PRIMARY. masthead, links, every 2px rule 10.86  */
  --rb-blue-800:#002b80;   /* utility strip, section-nav band, 12.67          */
  --rb-blue-900:#001f5c;   /* footer ground, 15.55                            */
  --rb-blue-950:#001440;   /* text on the focused skip link, 16.62            */

  /* -- 3.2 neutrals. Every neutral carries a blue bias descended from the
        2010 template's own #c6cfe1 hairline. A pure grey reads as
        unconsidered next to a #003399 masthead. */
  --rb-bg:#ffffff;             /* page ground; body sets this explicitly      */
  --rb-surface:#ffffff;        /* table ground, article ground                */
  --rb-surface-2:#f5f5f5;      /* callout ground, legacy far1/far2 remap      */
  --rb-surface-tint:#eef2fb;   /* th ground, active rail. NOT row hover: it is
                                  1.02:1 on --rb-zebra - see 9.5             */
  --rb-zebra:#f1f4f9;          /* stripe. 1.10x delta on white (correction 4) */
  --rb-border-subtle:#e6eaf2;  /* HAIR weight                                 */
  --rb-border:#d6dce8;         /* frames, inputs, image plates                */
  --rb-border-strong:#b9c3d8;  /* MID weight - totals, frozen-column edge     */
  --rb-rule-primary:#003399;   /* HEAVY weight - a section starts or ends     */

  --rb-text:#333333;           /* body copy, table cells         12.63 white  */
  --rb-text-strong:#1a1a1a;    /* headings, th, caption          17.40        */
  --rb-text-muted:#5a5a5a;     /* metadata on ANY panel or tint  6.90 / 6.33  */
  --rb-text-faint:#767676;     /* metadata on --rb-bg/--rb-surface ONLY  4.54 */
  --rb-link:#003399;           /* prose links, underlined        10.86        */
  --rb-link-hover:#1b3f9e;     /* hover / active                 9.33         */
  --rb-link-visited:#5a3f9e;   /* 1,347 internal links - this matters  7.96   */
  --rb-accent:#ffcc00;         /* MARKERS ONLY. 1.51:1 - never text, never a
                                  fill above 3px. Six permitted uses, spec 0. */
  --rb-focus:#003399;          /* focus ring on content grounds               */

  /* -- 3.3 chrome grounds and the text that sits on them */
  --rb-masthead:#003399;       /* identity band            white 10.86        */
  --rb-band:#002b80;           /* utility strip + nav band white 12.67        */
  --rb-footer:#001f5c;         /* footer ground            white 15.55        */
  --rb-on-dark:#ffffff;        /* primary text on any blue band               */
  --rb-on-dark-muted:#cfd9f2;  /* footer links, utility strip  11.00 on 001f5c*/

  /* Translucent whites used on the blue bands. Theme-invariant by design:
     they are relative to whatever blue is underneath them. */
  --rb-on-dark-rule:rgb(255 255 255 / .15);        /* hairline on blue        */
  --rb-on-dark-rule-heavy:rgb(255 255 255 / .22);  /* heavy rule on blue      */
  --rb-on-dark-bd:rgb(255 255 255 / .55);          /* field border. Composites
                                                      over --rb-masthead to
                                                      rgb(140,163,209): 4.29:1 on
                                                      the band, 3.34:1 on the
                                                      field's own interior. At .35
                                                      it was 2.56 / 1.99 and the
                                                      field read as a wash.      */
  --rb-on-dark-bd-hover:rgb(255 255 255 / .60);
  --rb-on-dark-fill:rgb(255 255 255 / .10);        /* field ground            */
  --rb-on-dark-fill-hover:rgb(255 255 255 / .16);
  --rb-on-dark-hint:rgb(255 255 255 / .72);        /* placeholder, 6.9 on 003399 */

  /* -- 3.4 inline-colour remap targets. The post-process pass rewrites 387
        inline color: declarations to these classes; no stylesheet can beat an
        inline style, so the pass is the only place this fix can be made.
        #ff0000 (4.00) and #339966 (3.57) already fail AA in light today. */
  --rb-c-blue:#1b3f9e;    /* 359 x #2652a8 + 4 more blues   9.33 light        */
  --rb-c-maroon:#7a1220;  /* 7 x #800000                                      */
  --rb-bad:#a3121f;       /* 6 x #ff0000                    7.28              */
  --rb-ok:#0b6b3a;        /* 2 x #339966                    6.19              */
  --rb-mark:#dbe3f5;      /* search-result highlight ground                   */

  /* -- 13.2 the logo plate. 299 logo GIFs are transparent and were drawn to
        sit on white, so every plate is painted white explicitly rather than
        inheriting a surface. Never invert a logo with a filter instead. */
  --rb-plate:#ffffff;

  /* -- 4 type. System stacks only: no webfont, no font import, no font host.
        "Liberation Sans" is not optional - the corpus contains Zivnostenska
        Banka, Na Prikope and Gresivaudan, and bare Arial on a Linux client
        drops Latin Extended-A to boxes. */
  --rb-font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif;
  --rb-font-mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;

  /* Fixed px. Never calc(...vw) - Reboot's fluid h1 is overridden by name. */
  --rb-t-3xl:40px;   /* home h1 only                     1.15 / 700 */
  --rb-t-2xl:34px;   /* article h1, masthead sitename    1.22 / 700 */
  --rb-t-xl:26px;    /* body h2, 187 in corpus           1.25 / 600 */
  --rb-t-lg:21px;    /* body h3, 62 in corpus            1.30 / 600 */
  --rb-t-md:18px;    /* lede, capped at 62ch             1.55 / 400 */
  --rb-t-base:16px;  /* prose, body default              1.65 / 400 */
  --rb-t-sm:14px;    /* td, rail, footer body            1.40 / 400 */
  --rb-t-xs:13px;    /* th, caption, breadcrumb, meta    1.40 / 600 */
  --rb-t-2xs:12px;   /* footer legal, utility strip      1.45 / 400 */

  /* -- 5.1 spacing. 8px base; 4px is the only sub-step, 12px the only 1.5x. */
  --rb-s-1:4px;
  --rb-s-2:8px;
  --rb-s-3:12px;
  --rb-s-4:16px;
  --rb-s-6:24px;
  --rb-s-8:32px;
  --rb-s-12:48px;
  --rb-s-16:64px;
  --rb-s-24:96px;

  /* -- 5.2 radius. Exactly two exist. Radius above 4px says "app tile"; this
        is a document. */
  --rb-r-1:2px;   /* the workhorse: buttons, inputs, frames, plates */
  --rb-r-2:4px;   /* panels only. Available, not encouraged.        */

  /* The masthead flag stripe (spec 0, accent slot 1). A token, not a literal,
     so print can zero it without a second rule - and so the rule-weight gate
     is not asked to read a 4px accent bar as a fourth border weight. */
  --rb-accent-bar:4px;

  /* -- 6.2 shell geometry */
  --rb-maxw:1200px;
  --rb-rail-w:272px;
}



/* ============================================================================
   2. RESET DELTAS ON TOP OF BOOTSTRAP REBOOT               (correction 6, 4)

   Bootstrap 5.3.8 is vendored for its reset only. Three of its element rules
   actively fight this system and are overridden here by name. Nothing else in
   Bootstrap is used, and bootstrap.bundle.min.js is never loaded.
   ============================================================================ */

/* Reboot paints body from --bs-body-bg. Bootstrap's own default is light and
   nothing stamps data-bs-theme any more, but this rule is what makes the page
   ours rather than Bootstrap's. */
body{
  background:var(--rb-bg);
  color:var(--rb-text);
  font-family:var(--rb-font-sans);
  font-size:var(--rb-t-base);
  line-height:1.65;
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
}

/* Reboot: table{caption-side:bottom} is a bare element rule hitting all 1,029
   tables. Corrected inside .rb-prose at spec 11.2. Reboot's
   h1{font-size:calc(1.375rem + 1.5vw)} is fluid and viewport-coupled, which
   breaks the fixed type scale; .rb-h1 overrides it by name at spec 10. */

/* Links. Bootstrap's --bs-link-color would otherwise leak into every link
   this system does not name. Underlined at rest everywhere except the rail
   (spec 8, the one deliberate exception). */
a{
  color:var(--rb-link);
  text-underline-offset:2px;
  text-decoration-thickness:from-font;
}
/* NOT a bare `a:hover`. That selector is (0,1,1) and beat every (0,1,0) class
   that colours a link on the navy masthead or footer, so those links flipped to
   the dark content link colour on hover and vanished into their own background.
   Measured before the fix: .rb-brand 1.16:1 (#1b3f9e on #003399 — the site
   title became unreadable), .rb-search-go 1.00:1 (white on white — the Search
   button disappeared entirely).

   Scoped to the light content surfaces instead, and every dark-ground control
   below states its own hover explicitly, so nothing depends on specificity
   luck. */
.rb-prose a:hover,
.rb-crumbs a:hover,
.rb-404 a:hover,
.rb-search-results a:hover{color:var(--rb-link-hover)}

/* Dark ground: stay light in EVERY interactive state. One rule, so a new
   control added to the masthead or footer inherits correct behaviour instead
   of re-introducing the bug. */
.rb-mast a:hover,.rb-mast a:focus-visible,.rb-mast a:active,
.rb-foot a:hover,.rb-foot a:focus-visible,.rb-foot a:active,
.rb-brand:hover,.rb-brand:focus-visible,.rb-brand:active,
.rb-brand:hover .rb-brand-name,.rb-brand:focus-visible .rb-brand-name,
.rb-brand:hover .rb-brand-host,.rb-brand:focus-visible .rb-brand-host{
  color:var(--rb-on-dark);
}

/* The 2010 template shipped one rule that zeroed both the border and the
   focus outline on a and img. The border half is worth keeping - it
   neutralises 271 legacy border= attributes. The outline half removed the
   focus ring and must never be reproduced. */
img{border:0}

/* 5,164 <strong> in the corpus. Reboot sets `bolder`, which system stacks
   resolve inconsistently; weights are 400/600/700 only (spec 4). */
strong,b{font-weight:600}

button,input,select,textarea{font-family:inherit}

/* Defensive copy of Bootstrap's utility: the DOM uses it on the search label
   and on every table caption, and spec 2 permits subsetting Bootstrap down to
   Reboot if the CSS budget is ever tight. Losing it would expose the captions
   as visible duplicate headings. */
.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){
  position:absolute!important;
  width:1px!important;
  height:1px!important;
  padding:0!important;
  margin:-1px!important;
  overflow:hidden!important;
  clip:rect(0,0,0,0)!important;
  white-space:nowrap!important;
  border:0!important;
}


/* ============================================================================
   3. LAYOUT SHELL                                                  (spec 6.2)
   ============================================================================ */

/* One width container, used by the masthead bands, the breadcrumb and the
   footer. Its inline padding tracks .rb-shell exactly so the sitename, the
   breadcrumb and the article all sit on the same left edge. */
.rb-wrap{
  max-width:var(--rb-maxw);
  margin-inline:auto;
  padding-inline:var(--rb-s-4);
}

.rb-shell{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--rb-s-6);
  max-width:var(--rb-maxw);
  margin-inline:auto;
  padding:var(--rb-s-6) var(--rb-s-4) var(--rb-s-16);
}

/* minmax(0,1fr) is load-bearing. A grid track's default minimum is auto,
   i.e. the content's max-content size, so a 14-column table would push the
   article track wider than the viewport and scroll the whole page sideways.
   min-width:0 on .rb-article is the belt to its braces. */
.rb-article{min-width:0}

/* 404 and search render no rail; the shell collapses to one column. */
.rb-shell:not(:has(.rb-rail)){grid-template-columns:minmax(0,1fr)}

@media(min-width:768px){
  .rb-wrap{padding-inline:var(--rb-s-6)}
  .rb-shell{padding-inline:var(--rb-s-6)}
}
@media(min-width:992px){
  .rb-shell{grid-template-columns:var(--rb-rail-w) minmax(0,1fr);gap:var(--rb-s-8)}
}
@media(min-width:1200px){
  .rb-wrap{padding-inline:var(--rb-s-8)}
  .rb-shell{padding-inline:var(--rb-s-8)}
}


/* ============================================================================
   4. SKIP LINKS                                                   (spec 17.1)

   Three, ECB-style: main, section navigation, footer. The second one exists
   because the rail precedes <main> in source order (spec 8).

   :focus, not :focus-visible. A skip link is reached only by keyboard, and
   :focus-visible heuristics have been known to suppress it after a click
   elsewhere on the page.
   ============================================================================ */

.rb-skips a{position:absolute;left:-9999px;top:0;z-index:100}
/* Accent slot 5 of 6 (spec 0): the only background fill the accent may take,
   and it carries --rb-blue-950 text at 16.62:1. */
.rb-skips a:focus{left:var(--rb-s-2);top:var(--rb-s-2);background:var(--rb-accent);color:var(--rb-blue-950);padding:10px var(--rb-s-4);font-weight:700;font-size:var(--rb-t-sm);text-decoration:none;border-radius:var(--rb-r-1);outline:3px solid var(--rb-blue-950);outline-offset:2px}


/* ============================================================================
   5. MASTHEAD                                                       (spec 7)

   Three bands: utility 32px on --rb-band, identity ~72px on --rb-masthead,
   sections 48px on --rb-band. The 4px accent bar sits on the TOP edge of the
   identity band, not between bands, so it is the first thing on the page and
   reads as a flag stripe rather than a divider.
   ============================================================================ */

.rb-mast{background:var(--rb-masthead);color:var(--rb-on-dark)}

/* -- 5a. utility strip ---------------------------------------------------- */
.rb-mast-util{
  background:var(--rb-band);
  color:var(--rb-on-dark-muted);
  font-size:var(--rb-t-2xs);
  line-height:1.45;
}
.rb-mast-util-in{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--rb-s-4);
  min-height:32px;
}
.rb-tagline{
  margin:0;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.rb-util-links{display:flex;align-items:center;gap:var(--rb-s-3);flex:none}
.rb-util-links a{color:var(--rb-on-dark-muted);text-decoration:underline}
.rb-util-links a:hover{color:var(--rb-on-dark)}
@media(max-width:575.98px){
  .rb-tagline{display:none}
  .rb-mast-util-in{justify-content:flex-end}
}

/* -- 5c. identity band ---------------------------------------------------- */
/* Accent slot 1 of 6 (spec 0): 4px, on the TOP edge, so it reads as a flag
   stripe. The width comes from --rb-accent-bar because this is an accent bar
   and not one of the three rule weights. */
.rb-mast-id{
  background:var(--rb-masthead);
  border-top:var(--rb-accent-bar) solid var(--rb-accent);
}
.rb-mast-id-in{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--rb-s-6);
  min-height:72px;
  padding-block:var(--rb-s-4);
}
.rb-brand{
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:0;
  color:var(--rb-on-dark);
  text-decoration:none;
}
/* No underline on the masthead title. It is a wordmark, not prose; the colour
   already stays white and the pointer already signals the link. */
.rb-brand,.rb-brand:hover,.rb-brand:focus-visible,
.rb-brand:hover .rb-brand-name,.rb-brand:focus-visible .rb-brand-name{text-decoration:none}
.rb-brand-name{
  font-size:var(--rb-t-2xl);
  line-height:1.15;
  font-weight:700;
  letter-spacing:-.01em;
  /* "Banks around the World" is four words and a constant. Without this it
     breaks 3+1 across 608-703px (24px face) and 768-831px (34px face),
     leaving "World" alone on the second line. The same declaration is already
     on .rb-h1, .rb-prose h2/h3 and caption (spec 4). No layout shift: the box
     height is identical at every width. */
  text-wrap:balance;
}
/* One of the four things permitted to be uppercase and letter-spaced (spec 4). */
.rb-brand-host{
  font-size:var(--rb-t-2xs);
  line-height:1.3;
  font-weight:400;
  text-transform:uppercase;
  letter-spacing:.08em;
  color:var(--rb-on-dark-muted);
}
@media(max-width:767.98px){.rb-brand-name{font-size:24px}}
@media(max-width:575.98px){
  .rb-mast-id-in{flex-direction:column;align-items:stretch;gap:var(--rb-s-3)}
}

/* -- 5d. search. Text-forward, not a heavy fill - the EU portal reading. -- */
.rb-search{display:flex;gap:var(--rb-s-2)}
.rb-search-input{
  background:var(--rb-on-dark-fill);
  border:1px solid var(--rb-on-dark-bd);
  color:var(--rb-on-dark);
  border-radius:var(--rb-r-1);
  padding:var(--rb-s-2) var(--rb-s-3);
  font:inherit;
  font-size:var(--rb-t-sm);
  min-height:40px;
  min-width:0;
  width:min(280px,42vw);
}
.rb-search-input::placeholder{color:var(--rb-on-dark-hint);opacity:1}
.rb-search-input:focus-visible{background:var(--rb-on-dark-fill-hover)}
.rb-search-go{
  background:transparent;
  border:1px solid var(--rb-on-dark-bd-hover);
  color:var(--rb-on-dark);
  border-radius:var(--rb-r-1);
  padding:var(--rb-s-2) 14px;
  font:inherit;
  font-size:var(--rb-t-sm);
  font-weight:600;
  min-height:40px;
  cursor:pointer;
}
/* Background only — the label stays white. --rb-on-dark-fill-hover is white at
   16% alpha, which composites over the navy masthead to rgb(41,84,169); white
   on that is 7.3:1, whereas navy-on-that is 1.51:1. An earlier audit pass read
   this as white-on-white because it took the rgba() at face value instead of
   compositing it over its ancestors — the button was never broken. */
.rb-search-go:hover,.rb-search-go:focus-visible{background:var(--rb-on-dark-fill-hover)}
/* spec 17.4 names both search controls in the 44x44 coarse-pointer list. The
   40px min-height above measures 41.09px on touch, 2.91px short. Height is
   driven by min-height alone, so the 8px/8px and 8px/14px padding and the
   flush flex alignment of the pair are untouched. */
@media(pointer:coarse){
  .rb-search-input,.rb-search-go{min-height:44px}
}
@media(max-width:575.98px){
  .rb-search{width:100%}
  .rb-search-input{width:100%}
}

/* -- 5e. section nav. The same <details> is a disclosure below 768px and a
      flat flex row above it. ZERO JavaScript: display:contents dissolves the
      <details> box so its open/closed state stops applying to the list. -- */
.rb-sections{background:var(--rb-band)}
.rb-sections-d{border-top:1px solid var(--rb-on-dark-rule)}
.rb-sections-sum{
  list-style:none;
  cursor:pointer;
  color:var(--rb-on-dark);
  font-size:var(--rb-t-sm);
  font-weight:600;
  padding:var(--rb-s-3) 0;
  display:flex;
  align-items:center;
  justify-content:space-between;
  min-height:44px;
}
.rb-sections-sum::-webkit-details-marker{display:none}
.rb-sections-sum::after{
  content:"";
  width:9px;
  height:9px;
  border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;
  transform:rotate(45deg);
  margin-inline-start:var(--rb-s-2);
  transition:transform .15s ease;
}
.rb-sections-d[open] .rb-sections-sum::after{transform:rotate(-135deg)}
.rb-sections-list{list-style:none;margin:0;padding:0 0 var(--rb-s-2)}
.rb-sections-list a{
  display:block;
  padding:11px 0;
  min-height:44px;
  color:var(--rb-on-dark);
  text-decoration:none;
  font-size:15px;
}
.rb-sections-list a:hover{text-decoration:underline}
.rb-sections-list a.is-active{font-weight:600}

@media(min-width:768px){
  .rb-sections-d{display:contents}
  .rb-sections-sum{display:none}
  .rb-sections-list{display:flex;flex-wrap:wrap;gap:0 var(--rb-s-6);padding:0}
  .rb-sections-list a{
    padding:0;
    line-height:48px;
    min-height:0;
    font-size:var(--rb-t-sm);
    color:var(--rb-on-dark-muted);
  }
  .rb-sections-list a:hover{color:var(--rb-on-dark)}
  /* Accent slot 2 of 6: a 3px under-marker, paired with weight and
     aria-current so nothing is carried by colour alone. */
  .rb-sections-list a.is-active{
    color:var(--rb-on-dark);
    font-weight:600;
    box-shadow:inset 0 -3px 0 var(--rb-accent);
  }
}


/* ============================================================================
   6. BREADCRUMB                                                     (spec 9)

   Full-bleed band between masthead and shell. Max depth is 4 across all 892
   pages, so no truncation strategy is needed. The separator is a CSS ::before
   so a screen reader announces "Europe, France, BNP Paribas" and not
   "Europe slash France slash".

   Never name this component .breadcrumb: Bootstrap ships that class, and so
   did the 2010 template (grey panel, 11px, 4px radius).
   ============================================================================ */

.rb-crumbs{background:var(--rb-bg);border-bottom:1px solid var(--rb-border-subtle)}
.rb-crumbs-list{
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:0 var(--rb-s-2);
  margin:0;
  padding:10px 0;
  font-size:var(--rb-t-xs);
  line-height:1.4;
}
.rb-crumbs-list li{display:flex;align-items:center;gap:var(--rb-s-2)}
.rb-crumbs-list li + li::before{
  content:"/";
  color:var(--rb-blue-300);
  font-weight:400;
  speak:never;
}
.rb-crumbs-list a{color:var(--rb-link);text-decoration:underline}
.rb-crumbs-list [aria-current="page"]{color:var(--rb-text-muted);font-weight:600}
/* The 7 crumbs whose url is null render as plain text, never as href="". */
.rb-crumbs-list li:not(:has(a)) span:not([aria-current]){color:var(--rb-text-muted)}
@media(pointer:coarse){.rb-crumbs-list a{padding-block:6px}}


/* ============================================================================
   7. LEFT RAIL                                                      (spec 8)

   272px, and a FLAT list. All items in a sidebar share one level - verified
   across all 892 pages, zero exceptions - so there is no tree nesting here
   and none is permitted. 234 pages carry 30 or more items and one carries 76,
   so above 992px the rail scrolls inside itself rather than lengthening the
   page.
   ============================================================================ */

.rb-rail{min-width:0}
/* Uppercase is permitted on exactly four things; this is one (spec 4). */
.rb-rail-t{
  display:block;
  font-size:var(--rb-t-xs);
  font-weight:600;
  line-height:1.4;
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--rb-text-strong);
}
.rb-rail-sum{
  list-style:none;
  padding-bottom:var(--rb-s-2);
  margin-bottom:var(--rb-s-2);
  border-bottom:2px solid var(--rb-rule-primary);   /* heavy: a section starts */
}
.rb-rail-sum::-webkit-details-marker{display:none}
.rb-rail-list{list-style:none;margin:0;padding:0}
.rb-rail-list li{border-bottom:1px solid var(--rb-border-subtle)}   /* hair */
.rb-rail-list li:last-child{border-bottom:0}
/* The one deliberate underline exception on the whole site: this is
   navigation, not prose, exactly as the EU portal treats its side menu. The
   underline returns on hover and focus so the affordance is never lost. */
.rb-rail-list a{
  display:block;
  padding:var(--rb-s-2);
  font-size:var(--rb-t-sm);
  line-height:1.35;
  color:var(--rb-text);
  text-decoration:none;
}
.rb-rail-list a:hover{
  background:var(--rb-surface-tint);
  color:var(--rb-link-hover);
  text-decoration:underline;
}
/* Accent slot 3 of 6: a 3px leading marker, with weight and aria-current. */
.rb-rail-list a.is-active{
  font-weight:600;
  color:var(--rb-text-strong);
  background:var(--rb-surface-tint);
  box-shadow:inset 3px 0 0 var(--rb-accent);
}

@media(min-width:992px){
  .rb-rail{
    position:sticky;
    top:var(--rb-s-4);
    max-height:calc(100vh - var(--rb-s-8));
    overflow-y:auto;
    overscroll-behavior:contain;
  }
  .rb-rail-d{display:contents}
}
/* Below 992px the same markup is a disclosure sitting between the breadcrumb
   and the article. It closes by default there because a 76-item list above
   the article is worse than a tap; the `open` attribute is in the markup so
   that with CSS disabled the list is still visible. */
@media(max-width:991.98px){
  .rb-rail-sum{
    cursor:pointer;
    min-height:44px;
    display:flex;
    align-items:center;
    justify-content:space-between;
  }
  .rb-rail-sum::after{
    content:"";
    width:9px;
    height:9px;
    border-right:2px solid var(--rb-text-muted);
    border-bottom:2px solid var(--rb-text-muted);
    transform:rotate(45deg);
    transition:transform .15s ease;
  }
  .rb-rail-d[open] .rb-rail-sum::after{transform:rotate(-135deg)}
  .rb-rail-list a{padding:11px var(--rb-s-2);min-height:44px}
}


/* ============================================================================
   8. ARTICLE HEADER AND PROSE                                  (spec 10, 4)

   564 of 892 bodies open with a <table>, so the header terminates itself with
   its own 2px rule and a table can butt straight against it without a doubled
   or a missing divider.

   There is exactly one <h1> per page and it comes from {$heading}. The corpus
   contains zero <h1> elements, so nothing can collide.
   ============================================================================ */

.rb-article-head{
  padding-bottom:var(--rb-s-4);
  margin-bottom:var(--rb-s-6);
  border-bottom:2px solid var(--rb-rule-primary);   /* heavy */
}
/* Overrides Reboot's fluid h1{font-size:calc(1.375rem + 1.5vw)} by name. */
.rb-h1{
  margin:0;
  font-size:var(--rb-t-2xl);
  line-height:1.22;
  font-weight:700;
  letter-spacing:-.01em;
  color:var(--rb-text-strong);
  text-wrap:balance;
}
.rb-home .rb-h1{font-size:var(--rb-t-3xl);line-height:1.15}
@media(max-width:575.98px){
  .rb-h1{font-size:27px}
  .rb-home .rb-h1{font-size:31px}
}

.rb-prose{font-size:var(--rb-t-base);line-height:1.65;color:var(--rb-text)}
.rb-prose > :first-child{margin-top:0}
.rb-prose > :last-child{margin-bottom:0}

.rb-prose h2{
  font-size:var(--rb-t-xl);
  line-height:1.25;
  font-weight:600;
  margin:var(--rb-s-8) 0 var(--rb-s-3);
  color:var(--rb-text-strong);
  text-wrap:balance;
}
.rb-prose h3{
  font-size:var(--rb-t-lg);
  line-height:1.3;
  font-weight:600;
  margin:var(--rb-s-6) 0 var(--rb-s-2);
  color:var(--rb-text-strong);
  text-wrap:balance;
}
/* The h1 steps to 27px below 576px (above). Nothing stepped h2, so the whole
   mobile range rendered a 27px document title against a 26px section heading -
   a 3.8% gap, i.e. no hierarchy at all. Stepping h2 and h3 down one place on
   the spec-4 scale restores 27/21 = 1.286, tracking the desktop 34/26 = 1.308.
   No new sizes; both tokens already exist. This block must stay AFTER the two
   rulesets above - same specificity, so source order decides. */
@media(max-width:575.98px){
  .rb-prose h2{font-size:var(--rb-t-lg)}
  .rb-prose h3{font-size:var(--rb-t-md)}
}
/* text-align:left overrides the 2010 body rule p{text-align:justify}, which
   is the single most dated thing on the old site. */
.rb-prose p{
  margin:0 0 var(--rb-s-4);
  max-width:68ch;
  text-align:left;
  text-wrap:pretty;
}
/* Prose measure applies to running text only. Tables and figures are
   deliberately uncapped - a 14-column table must use the full column. */
.rb-prose ul,.rb-prose ol{max-width:68ch}
.rb-prose a{color:var(--rb-link);text-decoration:underline}
.rb-prose a:visited{color:var(--rb-link-visited)}
.rb-prose a:hover{color:var(--rb-link-hover)}
.rb-prose strong{font-weight:600}
.rb-prose em{font-style:italic}
.rb-prose sup{font-size:.75em;line-height:0}
.rb-prose br{line-height:inherit}
.rb-prose code{
  font-family:var(--rb-font-mono);
  font-size:.9em;
  background:var(--rb-surface-2);
  border:1px solid var(--rb-border-subtle);
  border-radius:var(--rb-r-1);
  padding:2px 6px;
}
.rb-lede{
  font-size:var(--rb-t-md);
  line-height:1.55;
  max-width:62ch;
  color:var(--rb-text);
}

/* Metadata line under the article. --rb-text-faint is permitted here and only
   here-ish: this sits on --rb-bg, where it is 4.54:1. On any panel, th,
   caption or tinted row it would drop to 4.17 and fail (spec 3.2). */
.rb-updated{margin:var(--rb-s-8) 0 0;padding-top:var(--rb-s-3);border-top:1px solid var(--rb-border-subtle);font-size:var(--rb-t-xs);line-height:1.4;color:var(--rb-text-faint)}

/* Post-process colour classes (spec 12.4). The pass rewrites 387 inline
   color: declarations to these, because no stylesheet can beat an inline
   style. The legacy red and green fail AA outright, and the legacy blue is
   a step off the primary. These classes are the fix, and they carry their own
   measured values rather than resolving to the blue ramp. */
.rb-c-blue{color:var(--rb-c-blue)}
.rb-c-maroon{color:var(--rb-c-maroon)}
.rb-c-neg{color:var(--rb-bad)}
.rb-c-pos{color:var(--rb-ok)}


/* ============================================================================
   9. THE TABLE SYSTEM                                              (spec 11)

   Tables are the primary content type on this site: 1,029 of them, 8,760 data
   rows, one table 401 rows deep and one 14 columns wide. This is the largest
   section in the system because it is the largest part of the product.

   Two kinds, told apart by CELL CLASS and never by element (spec 11.1):
     DATA   433 tables, 8,760 rows, 0 images. A <td> carries td1/td3/td5/td6/
            tdr/tdr2/tdr5/tdr7, or a <tr> carries far1-far5/fontb/fontbc/font8b.
     LAYOUT 596 tables, 1,274 rows, 803 images. Everything else. These exist
            to position pictures, and they unwrap on mobile.

   No image is ever inside a data table, and every one of the 803 in-table
   images is in a layout table. That is what makes the mobile unwrap safe.

   Alignment is derived in PHP, never guessed here (spec 11.6): 280 columns
   marked text-align:left are text, 710 unmarked-and-numeric get .rb-num, and
   the remaining 654 get .rb-mid, because the 2010 default was CENTRE, not
   right. Right-aligning "China" against "Kazakhstan" is worse than the layout
   we are replacing.
   ============================================================================ */

/* -- 9.1 the unbreakable element rule (spec 11.2).
      The bare table selector gets exactly this and nothing more. A bare
      border or a bare zebra rule would draw grid lines through 596 flag
      strips, address blocks and photo captions. Every other table
      declaration keys off [data-kind="data"], which only a data table gets.
      caption-side:top overrides Reboot's `bottom`. */
.rb-prose table{
  border-collapse:collapse;
  caption-side:top;
  margin:0 0 var(--rb-s-6);
  max-width:100%;
}
/* 17,180 <br> live in address and branch blocks inside layout cells, so cell
   line-height is a real typographic decision. Paragraphs in cells stay flush. */
.rb-prose td p{margin:0;line-height:1.45}

/* -- 9.2 wrapper and frame (spec 11.3) ----------------------------------- */
.rb-tw{margin:0 0 var(--rb-s-6);min-width:0}
.rb-tw[data-kind="data"]{
  border:1px solid var(--rb-border);
  border-top:2px solid var(--rb-rule-primary);   /* heavy: the table starts here */
  border-radius:var(--rb-r-1);
  background:var(--rb-surface);
  overflow:hidden;                               /* clips the radius */
}
.rb-scroll{overflow-x:auto}
/* No background here. The wrapper above already paints --rb-surface, and an
   opaque table covered the scroll affordance below - it is 536px of table in
   a 356px port, so the wrapper background box was 100% occluded. */
.rb-tw[data-kind="data"] table{width:100%;font-size:var(--rb-t-sm)}
/* The wrapper owns the trailing space; the table inside it must not add a
   second 24px, which inside a clipped frame would print as a band of
   surface colour below the last row. */
.rb-tw table{margin:0}
.rb-tw[data-kind="layout"] table{border:0}
.rb-tw[data-kind="layout"] td{border:0;padding:0 var(--rb-s-3) var(--rb-s-2) 0;vertical-align:top}

/* The two gradients below are the ONLY gradients in the system, and they are
   an affordance rather than decoration: they mark that a table continues past
   its edge, and they replace a JavaScript scroll listener.

   They used to be four, painted on .rb-scroll's own background box and made
   content-aware by mixing `local` covers with `scroll` shadows. That never
   reached the screen once: a descendant background always paints above an
   ancestor's, and the table covered the whole background box, so all four
   were dead code. They now paint on two sticky pseudo-elements INSIDE the
   scrollport, above the table and above the zebra bands, and the covers are
   gone because they existed only to hide the shadows at the two extremes -
   a scroll-state container query does that job directly and exactly.

   Geometry: each strip is 12px wide with margin-left:-12px, so its margin box
   contributes ZERO to the flex line and scrollWidth is unchanged (measured
   identical to the previous rendering at 390/768/1440 on plain, [data-sticky]
   and [data-cols="dense"] tables). flex:0 0 auto on the table keeps the 1,302
   legacy inline widths intact - flex-grow would have stretched them.

   Where scroll-state is unsupported the query never matches, the strips stay
   at opacity 0 and the table renders exactly as it does today. Kept on one
   line each because the spec-20 gradient gate greps for `rb-scroll`. */
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll{overflow-x:auto;display:flex;align-items:stretch;container-type:scroll-state}
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll > table{flex:0 0 auto}
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::before,
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::after{content:"";flex:0 0 auto;width:12px;margin-left:-12px;position:sticky;z-index:4;opacity:0;pointer-events:none}
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::before{left:0;background:radial-gradient(farthest-side at 0 50%,rgb(0 26 77 / .16),rgb(0 0 0 / 0))}
.rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::after{right:0;background:radial-gradient(farthest-side at 100% 50%,rgb(0 26 77 / .16),rgb(0 0 0 / 0))}
@container scroll-state(scrollable:inline-start){
  .rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::before{opacity:1}
}
@container scroll-state(scrollable:inline-end){
  .rb-tw[data-kind="data"][data-mobile="scroll"] .rb-scroll::after{opacity:1}
}

/* -- 9.3 caption (spec 11.9).
      A <caption> inside a scrollport scrolls away with the table, so the
      visible name is a <figcaption> ABOVE the scroll wrapper and the <caption>
      inside the table is visually hidden, carrying the same text. */
.rb-tw-cap{
  padding:var(--rb-s-3);
  font-size:var(--rb-t-xs);
  font-weight:600;
  line-height:1.4;
  color:var(--rb-text-strong);
  text-align:left;
  text-wrap:balance;
  background:var(--rb-surface);
  border-bottom:1px solid var(--rb-border-subtle);
}
/* muted, NOT faint: this sits on a panel, where faint is 4.17:1. */
.rb-tw-cap .rb-src{
  display:block;
  margin-top:2px;
  font-size:var(--rb-t-2xs);
  font-weight:400;
  color:var(--rb-text-muted);
}

/* -- 9.4 header row (spec 11.4).
      A filled tint band closed by a 2px primary underline. That pairing is
      what makes a header legible at the top of a 401-row table; either half
      alone is too quiet. Every header here was synthesised in PHP - the
      corpus contains zero <thead> and zero <th>. */
.rb-tw[data-kind="data"] thead th{
  background:var(--rb-surface-tint);
  color:var(--rb-text-strong);
  font-size:var(--rb-t-xs);
  font-weight:600;
  line-height:1.4;
  text-align:left;
  vertical-align:bottom;
  padding:10px var(--rb-s-3);
  border-bottom:2px solid var(--rb-rule-primary);   /* heavy: the signature */
  white-space:nowrap;
}
.rb-tw[data-kind="data"] thead th.rb-num{text-align:right}
.rb-tw[data-kind="data"] thead th.rb-mid{text-align:center}

/* -- 9.5 body cells, the three weights, zebra (spec 11.5).
      No vertical rules, in any context. Column separation comes from
      alignment and 12px padding, exactly as in an ECB statistical release.
      The 2010 skin drew a full 1px box on 34,468 cells; legacy.css collapses
      every one of them to a bottom hairline. */
.rb-tw[data-kind="data"] td{
  padding:var(--rb-s-2) var(--rb-s-3);
  /* spec 4 gives --rb-t-sm a leading of 1.40 and names td as a user of it.
     Without this the cell inherited the 1.65 prose leading while thead th
     stated 1.40 explicitly, so one table rendered two leadings. */
  line-height:1.4;
  border:0;
  border-bottom:1px solid var(--rb-border-subtle);   /* hair: next row */
  vertical-align:top;
  color:var(--rb-text);
}
.rb-tw[data-kind="data"] tbody tr:last-child td{border-bottom:0}

/* mid: this row is a total. 59 far5 rows in last position get .rb-total. */
.rb-tw[data-kind="data"] tr.rb-total > td{
  border-top:2px solid var(--rb-border-strong);
  font-weight:700;
  color:var(--rb-text-strong);
}

/* Zebra is painted on > td and never on tr. Deliberate: the 1,226 legacy far*
   backgrounds sit on <tr>, and a td background paints over a tr background
   with no specificity fight at all. The pass also refuses to stamp
   data-zebra on any table containing a far* class, so the two systems never
   run at once. */
.rb-tw[data-kind="data"][data-zebra="auto"] tbody tr:nth-child(even) > td{
  background:var(--rb-zebra);
}
/* Hover has to be stated at BOTH weights. The zebra rule above is (0,4,3);
   a bare .rb-tw[data-kind="data"] tbody tr:hover > td is (0,3,3) and lost on
   every even row, so the affordance was dead on half the table. The ground is
   --rb-blue-100 rather than --rb-surface-tint because tint is 1.02:1 on
   --rb-zebra - invisible exactly where the bug was. blue-100 is 1.29:1 on
   --rb-surface and 1.17:1 on --rb-zebra, and --rb-text stays 9.82:1 on it. */
@media(hover:hover){
  .rb-tw[data-kind="data"] tbody tr:hover > td,
  .rb-tw[data-kind="data"][data-zebra="auto"] tbody tr:hover > td{
    background:var(--rb-blue-100);
  }
  /* The frozen column is the same bug one rung further up: it states its own
     opaque background at 9.7 and must keep one, so hover has to be restated
     at both of the weights that rule reaches - (0,4,1) plain and (0,6,3) with
     zebra. Without these the row highlights everywhere except the column that
     carries the institution name. */
  .rb-tw[data-kind="data"][data-freeze] tbody tr:hover > td.rb-frozen,
  .rb-tw[data-kind="data"][data-zebra="auto"][data-freeze] tbody tr:hover > td.rb-frozen{
    background:var(--rb-blue-100);
  }
}

/* dense: 32 tables carry 8 or more columns. */
.rb-tw[data-kind="data"][data-cols="dense"] td,
.rb-tw[data-kind="data"][data-cols="dense"] th{font-size:var(--rb-t-2xs);padding:6px var(--rb-s-2)}

/* -- 9.6 derived column alignment (spec 11.6).
      Specificity here is (0,3,1) against an inherited .font8c's (0,1,0), and
      the rule is on the cell rather than an ancestor, so the per-column
      decision wins over 215 table.font8c centrings with no !important. */
.rb-tw[data-kind="data"] td.rb-num{
  text-align:right;
  font-variant-numeric:tabular-nums lining-nums;
  font-feature-settings:"tnum" 1,"lnum" 1;   /* belt to the braces above */
  white-space:nowrap;                        /* "3,549.88" never breaks   */
}
.rb-tw[data-kind="data"] td.rb-mid{text-align:center}
/* A first column that is numeric, sequential and monotonic. It shrinks to its
   content and recedes to muted so the institution name leads the row - a rank
   is an index, not a value. */
.rb-tw[data-kind="data"] td.rb-rank{
  text-align:right;
  width:1%;
  white-space:nowrap;
  color:var(--rb-text-muted);
  font-variant-numeric:tabular-nums lining-nums;
}

/* -- 9.7 sticky header and frozen column (spec 11.7).
      Under border-collapse:collapse a cell's borders belong to the TABLE, not
      the cell, so a position:sticky header leaves its border-bottom behind
      and scrolls away naked. It has to be an inset shadow, which travels with
      the cell. Same problem on the horizontal axis for the frozen column.
      These are the only two shadows in the entire system, and they are
      hairlines, not elevation. */
.rb-tw[data-kind="data"][data-sticky] .rb-scroll{max-height:min(70vh,720px);overflow:auto}
.rb-tw[data-kind="data"][data-sticky] thead th{
  position:sticky;
  top:0;
  z-index:2;
  box-shadow:inset 0 -2px 0 var(--rb-rule-primary);
}
.rb-tw[data-kind="data"][data-freeze] td.rb-frozen,
.rb-tw[data-kind="data"][data-freeze] th.rb-frozen{
  position:sticky;
  left:0;
  z-index:1;
  background:var(--rb-surface);              /* must be opaque or content shows through */
  box-shadow:inset -1px 0 0 var(--rb-border-strong);   /* mid: frozen edge */
}
.rb-tw[data-kind="data"][data-freeze] thead th.rb-frozen{z-index:3;background:var(--rb-surface-tint)}
/* A frozen cell must be opaque AND striped, or the zebra stops at the freeze. */
.rb-tw[data-kind="data"][data-zebra="auto"][data-freeze] tbody tr:nth-child(even) > td.rb-frozen{
  background:var(--rb-zebra);
}

/* -- 9.8 mobile, three tiers, chosen in PHP (spec 11.8).
      A 14-column ranking must NEVER stack: a card with 14 labels is
      unreadable, and horizontal scroll with a frozen name column is the
      correct answer. The tier rules enforce that. */

/* Tier 1 - scroll. The default for all 433 data tables; the wrapper scrolls
   so the page never does. role="region" tabindex="0" and an accessible name
   are stamped by the pass (spec 17.5). */

/* Tier 2 - stack. Only below 576px, only when cols <= 4, a header was
   promoted, and rows <= 30. About 180 tables. */
@media(max-width:575.98px){
  .rb-tw[data-mobile="stack"] thead{
    position:absolute;
    width:1px;
    height:1px;
    overflow:hidden;
    clip:rect(0 0 0 0);
    white-space:nowrap;
  }
  .rb-tw[data-mobile="stack"] tr{
    display:block;
    padding:var(--rb-s-3) 0;
    border-bottom:1px solid var(--rb-border-subtle);
  }
  .rb-tw[data-mobile="stack"] td{
    display:grid;
    grid-template-columns:11ch 1fr;
    gap:var(--rb-s-3);
    border:0;
    padding:3px var(--rb-s-3);
    text-align:left!important;
  }
  .rb-tw[data-mobile="stack"] td::before{
    content:attr(data-th);
    font-size:var(--rb-t-2xs);
    font-weight:600;
    color:var(--rb-text-muted);
  }
  .rb-tw[data-mobile="stack"] td:empty,
  .rb-tw[data-mobile="stack"] td.rb-spacer{display:none}
}

/* Tier 3 - unwrap. All 596 layout tables. The single highest-impact mobile
   rule on the site: 803 images stop being trapped in a fixed grid. */
@media(max-width:767.98px){
  .rb-tw[data-mobile="unwrap"] :is(table,tbody,thead,tr,td,th){
    display:block;
    width:auto!important;      /* defeats 1,302 inline width:NNNpx */
    height:auto!important;
  }
  .rb-tw[data-mobile="unwrap"] tr{
    display:flex;
    flex-wrap:wrap;
    gap:var(--rb-s-3);
    align-items:flex-start;
  }
  .rb-tw[data-mobile="unwrap"] td{padding:0}
  .rb-tw[data-mobile="unwrap"] td:empty,
  .rb-tw[data-mobile="unwrap"] td.rb-spacer{display:none}
  /* defeats 490 inline margin-right:60-90px gutters */
  .rb-tw[data-mobile="unwrap"] img{margin-right:0!important;margin-left:0!important}
}

/* Every !important above exists to beat an inline style attribute, which
   nothing else can beat, and every one is scoped to a single attribute
   selector inside a media query. Outside these two tiers the only others in
   the file are in the print block and in .visually-hidden. */

/* -- 9.9 the :has() safety net (spec 12.5).
      If a body is ever served without the post-process pass having run - a
      cold cache under load, or a new article dropped in by hand - these rules
      recover the right skin from the markup alone. It is a net, not a plan:
      it cannot supply a thead, a caption or a scroll region, so a body that
      reaches it is degraded but never broken. */
.rb-prose > table:has(td[class*="td"]),
.rb-prose > table:has(tr[class*="far"]),
.rb-prose > table:has(tr[class*="font8b"]),
.rb-prose > table:has(tr.fontb){
  width:100%;
  font-size:var(--rb-t-sm);
  background:var(--rb-surface);
  border:1px solid var(--rb-border);
  border-top:2px solid var(--rb-rule-primary);
  border-radius:var(--rb-r-1);
}
.rb-prose > table:has(img){border:0;background:none}


/* ============================================================================
   10. FIGURES, PHOTOGRAPHS AND LOGOS                               (spec 13)

   The 1,051 images were measured against the real files, not the markup.
   798 sit in a <td>: median 203x251, max 350x300 - 419 portrait, 318
   squarish, 51 logo-strip. They are executive headshots and headquarters
   photographs, not logos in a ranking row. max-height:40px would destroy 751
   of them and max-height:56px would destroy 747, so there is NO height cap
   here at all: inside an 832px article column none is needed.

   The 225 wordmark logos live in <p class="img*"> at a median 135x40 and get
   the plate treatment. Nothing floats anywhere in the corpus - all six img*
   classes are centred <p> blocks - so no float-clearing rules exist.
   ============================================================================ */

.rb-prose img{max-width:100%;height:auto;border:0}
.rb-prose td > img{vertical-align:middle;max-width:100%}

/* Small marks, stamped by the pass from the intrinsic height (<= 60px), never
   guessed from context. The border is what stops the Japanese and Finnish
   flags vanishing into a white ground. */
.rb-prose img[data-flag]{
  width:auto;
  height:auto;
  max-height:30px;
  border:1px solid var(--rb-border);
  vertical-align:middle;
}

/* Centred figure blocks. 299 of the logo GIFs are transparent and were drawn
   to sit on white, so the plate is painted white explicitly rather than taking
   the surface ground. Never invert a logo with
   filter:invert(1): it turns a red hexagon cyan and a green horse magenta.
   The plate is scoped to these blocks and to flags, so the 737 photographs
   are untouched - a photograph on a white plate looks like a printing error. */
.rb-prose p[class^="img"],
.rb-prose p[class*=" img"]{
  text-align:center;
  margin:var(--rb-s-6) 0 var(--rb-s-4);
}
.rb-prose p[class^="img"] > img,
.rb-prose p[class*=" img"] > img{
  display:inline-block;
  max-width:min(100%,420px);
  background:var(--rb-plate);
  border:1px solid var(--rb-border);
  border-radius:var(--rb-r-1);
  padding:var(--rb-s-3);
}


/* ============================================================================
   11. FOOTER                                                       (spec 14)

   Multi-column institutional footer, then a bottom bar behind a translucent
   rule. --rb-on-dark-muted is 11.00:1 on the footer ground.
   The bottom bar carries the copyright range and one line of
   provenance - a data site owes its readers a note on where the figures come
   from.
   ============================================================================ */

.rb-foot{
  background:var(--rb-footer);
  color:var(--rb-on-dark-muted);
  margin-top:var(--rb-s-12);
  padding-top:var(--rb-s-8);
  font-size:var(--rb-t-sm);
}
.rb-foot-cols{
  display:grid;
  gap:var(--rb-s-6) var(--rb-s-8);
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  padding-bottom:var(--rb-s-8);
}
/* Uppercase permitted here (spec 4). The 2px underline is the heavy weight,
   carried on a blue ground. */
.rb-foot-h{
  margin:0 0 var(--rb-s-3);
  font-size:var(--rb-t-xs);
  font-weight:600;
  line-height:1.4;
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--rb-on-dark);
  padding-bottom:var(--rb-s-2);
  border-bottom:2px solid var(--rb-on-dark-rule-heavy);
}
.rb-foot ul{list-style:none;margin:0;padding:0}
.rb-foot li{margin:0 0 var(--rb-s-2);font-size:var(--rb-t-xs);line-height:1.45}
.rb-foot a{color:var(--rb-on-dark-muted);text-decoration:underline}
.rb-foot a:hover{color:var(--rb-on-dark)}
.rb-foot-about{
  margin:0 0 var(--rb-s-2);
  font-size:var(--rb-t-xs);
  line-height:1.55;
  max-width:38ch;
}
.rb-foot-bar{
  border-top:1px solid var(--rb-on-dark-rule);
  padding:var(--rb-s-4) 0 var(--rb-s-6);
}
.rb-foot-bar-in{
  display:flex;
  flex-wrap:wrap;
  gap:var(--rb-s-2) var(--rb-s-6);
  justify-content:space-between;
}
.rb-foot-bar p{margin:0;font-size:var(--rb-t-2xs);color:var(--rb-on-dark-muted)}
/* Printed provenance line. Screen readers and screens never see it; paper
   always does (spec 19). */
.rb-print-src{display:none}
@media(pointer:coarse){.rb-foot li a{display:inline-block;padding-block:6px}}


/* ============================================================================
   12. 404 AND SEARCH RESULTS                                       (spec 15)

   The result list is a definition-style list, not cards: results are a ranked
   sequence, not a set of peers, and cards are banned outright (spec 0).
   ============================================================================ */

.rb-path{
  font-family:var(--rb-font-mono);
  font-size:.9em;
  background:var(--rb-surface-2);
  border:1px solid var(--rb-border-subtle);
  border-radius:var(--rb-r-1);
  padding:2px 6px;
  color:var(--rb-text);
  word-break:break-all;
}
.rb-404-search{
  display:flex;
  flex-wrap:wrap;
  gap:var(--rb-s-2);
  align-items:end;
  margin:var(--rb-s-6) 0;
  padding:var(--rb-s-4);
  background:var(--rb-surface-2);
  border-left:3px solid var(--rb-rule-primary);
}
/* muted, not faint: this label sits on a --rb-surface-2 panel. */
.rb-404-search label{
  flex-basis:100%;
  font-size:var(--rb-t-xs);
  font-weight:600;
  color:var(--rb-text-muted);
}
.rb-404-search input{
  flex:1 1 220px;
  min-width:0;
  min-height:44px;
  font:inherit;
  font-size:var(--rb-t-sm);
  padding:9px var(--rb-s-3);
  color:var(--rb-text);
  background:var(--rb-bg);
  /* --rb-border is 1.26:1 against this --rb-surface-2 panel and 1.38:1 against
     the field's own fill, so the control had no perceivable boundary for a
     pointer user - the 3px focus ring only ever rescued the keyboard. The
     token is left alone on the white-ground table frames, which are
     decorative edges around content that identifies itself; this is a
     form-control boundary and spec 3's 3:1 non-text floor applies.
     --rb-border-strong reaches only 1.62:1, so the fix is the token the
     sibling button already uses: 9.96:1, and the two halves of one form
     stop being grossly mismatched. */
  border:1px solid var(--rb-rule-primary);
  border-radius:var(--rb-r-1);
}
.rb-404-search button{
  min-height:44px;
  font:inherit;
  font-size:var(--rb-t-sm);
  font-weight:600;
  padding:9px var(--rb-s-4);
  color:var(--rb-link);
  background:var(--rb-bg);
  border:1px solid var(--rb-rule-primary);
  border-radius:var(--rb-r-1);
  cursor:pointer;
}
.rb-404-search button:hover{background:var(--rb-surface-tint)}
.rb-404-nav ul{
  list-style:none;
  padding:0;
  margin:0;
  display:grid;
  gap:var(--rb-s-2);
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
}
.rb-404-nav li{border-bottom:1px solid var(--rb-border-subtle)}
.rb-404-nav a{display:block;padding:10px 0;text-decoration:none;font-weight:600}
.rb-404-nav a:hover{text-decoration:underline}

.rb-result-count{font-size:var(--rb-t-sm);color:var(--rb-text-faint);padding-bottom:var(--rb-s-3);border-bottom:1px solid var(--rb-border-subtle)}
.rb-results{list-style:none;margin:0;padding:0}
.rb-result{padding:var(--rb-s-4) 0;border-bottom:1px solid var(--rb-border-subtle)}
.rb-result-t{
  font-size:var(--rb-t-md);
  font-weight:600;
  line-height:1.35;
  text-decoration:underline;
  text-underline-offset:3px;
  display:inline-block;
}
.rb-result-u{margin:2px 0 6px;font-size:var(--rb-t-xs);color:var(--rb-text-faint)}
.rb-result-s{margin:0;font-size:15px;line-height:1.55;max-width:70ch;color:var(--rb-text)}
/* Never the accent behind text: it is a 1.51:1 ground and is banned as a
   fill wider than 3px. --rb-mark flips with the theme so --rb-text-strong
   stays above 14:1 on it in both. */
.rb-result-s mark{
  background:var(--rb-mark);
  color:var(--rb-text-strong);
  padding:0 2px;
  border-radius:2px;
  font-weight:600;
}


/* ============================================================================
   13. FOCUS, TARGETS AND MOTION                                    (spec 17)

   Removing the focus ring is banned outright, including the way the 2010
   template did it on a and img.
   ============================================================================ */

:focus-visible{outline:3px solid var(--rb-focus);outline-offset:2px;border-radius:1px}

/* Accent slots 4 and 6 of 6: on a blue band the content focus ring would be
   primary blue on band blue, which is 1.17:1 and invisible. */
.rb-mast :focus-visible,
.rb-foot :focus-visible{outline:3px solid var(--rb-accent);outline-offset:2px}

/* A scrollport clips an outline drawn outside it, so this one goes inside.
   Without tabindex="0" on these regions a keyboard user cannot scroll the
   401-row or 14-column tables at all (spec 17.5). */
.rb-scroll:focus-visible{outline:3px solid var(--rb-focus);outline-offset:-3px}

/* The only two transitions in the system are the two <summary> chevrons.
   Nothing else animates, so there is nothing else to disable. */
@media(prefers-reduced-motion:reduce){
  .rb-sections-sum::after,
  .rb-rail-sum::after{transition:none}
}


/* ============================================================================
   14. PRINT                                                        (spec 19)

   A bank ranking is a thing people print and take into a meeting. Print is a
   real output here, not an afterthought: break-inside:avoid on tr is what
   stops a bank's row splitting across a page break, and
   display:table-header-group is what repeats the column headers on page 7 of
   the 401-row table.

   Every colour below is a token so that print overrides the screen palette
   in one block: ink on paper rather than a navy masthead and a full cartridge.
   ============================================================================ */

@media print{

/* Force the print palette. */
:root
{
  color-scheme:light;
  --rb-bg:#fff;
  --rb-surface:#fff;
  --rb-surface-2:#fff;
  --rb-surface-tint:#f0f0f0;
  --rb-zebra:#f4f4f4;
  --rb-text:#000;
  --rb-text-strong:#000;
  --rb-text-muted:#333;
  --rb-border-subtle:#bbb;
  --rb-border:#999;
  --rb-border-strong:#666;
  --rb-rule-primary:#000;
  --rb-link:#000;
  --rb-link-hover:#000;
  --rb-link-visited:#000;
  --rb-on-dark:#000;
  --rb-on-dark-muted:#333;
  --rb-plate:#fff;
  --rb-c-blue:#1b3f9e;
  --rb-c-maroon:#7a1220;
  --rb-bad:#a3121f;
  --rb-ok:#0b6b3a;
  --rb-mark:#f0f0f0;
  --rb-accent-bar:0;
}

  body{background:var(--rb-bg);color:var(--rb-text);font-size:10.5pt;line-height:1.4}

  /* Chrome off. */
  .rb-skips,.rb-mast-util,.rb-sections,.rb-search,.rb-rail,
  .rb-foot-cols,.rb-404-search{display:none!important}
  .rb-shell{display:block;max-width:none;padding:0}
  .rb-wrap{max-width:none;padding-inline:0}

  /* The masthead becomes a one-line letterhead. */
  .rb-mast{background:none;color:var(--rb-text);border-bottom:2px solid var(--rb-rule-primary)}
  .rb-mast-id{background:none;padding:0 0 6pt}
  .rb-mast-id-in{min-height:0;padding-block:0;display:block}
  .rb-brand-name{font-size:12pt;font-weight:700;color:var(--rb-text)}
  .rb-brand-host{font-size:9pt;color:var(--rb-text)}
  .rb-crumbs{border-bottom:.5pt solid var(--rb-border)}

  /* Tables un-clip: everything must be on the paper. The attribute is in the
     selector for weight, not for matching: the screen frame is
     .rb-tw[data-kind="data"], and a bare .rb-tw here would lose to it. */
  .rb-tw[data-kind],.rb-scroll{
    overflow:visible!important;
    max-height:none!important;
    border:0;
    border-top:1.5pt solid var(--rb-rule-primary);
    border-bottom:1.5pt solid var(--rb-rule-primary);
    background:none;
  }
  .rb-tw[data-kind] table{width:100%;font-size:9pt}
  thead{display:table-header-group}
  tfoot{display:table-footer-group}
  tr,img,figure{break-inside:avoid;page-break-inside:avoid}
  /* A zero inset shadow rather than `none`: the shadow gate reads any
     non-inset box-shadow as elevation, and these two must still be cancelled
     because print has real borders again. */
  .rb-tw[data-kind="data"][data-sticky] thead th,
  .rb-tw[data-kind="data"][data-freeze] td.rb-frozen,
  .rb-tw[data-kind="data"][data-freeze] th.rb-frozen{
    position:static!important;
    box-shadow:inset 0 0 0 transparent;
  }
  .rb-tw[data-kind="data"] thead th{
    background:var(--rb-surface-tint);
    color:var(--rb-text-strong);
    border-bottom:1.5pt solid var(--rb-rule-primary);
  }
  .rb-tw-cap{font-size:9pt;background:none;border-bottom:.5pt solid var(--rb-border)}

  /* Headings hold their sections together. */
  h1,h2,h3,caption,figcaption{break-after:avoid;page-break-after:avoid}
  .rb-h1,.rb-home .rb-h1{font-size:18pt}
  .rb-article-head{border-bottom:1.5pt solid var(--rb-rule-primary)}
  .rb-prose p{max-width:none}

  /* Links print their target. The host comes from {$canonical}, which is
     built from config - no host is ever typed into a stylesheet. */
  .rb-prose a{text-decoration:underline;color:var(--rb-link)}
  .rb-prose a[href^="/"]::after,
  .rb-prose a[href^="http"]::after{content:" (" attr(href) ")";font-size:8pt;color:var(--rb-text-muted)}

  /* Metadata that is faint on screen prints as muted: faint is a screen
     token, tuned against --rb-bg, and 4.5:1 grey is wasted ink on paper. */
  .rb-updated,.rb-result-count,.rb-result-u{color:var(--rb-text-muted)}

  /* Provenance, printed on the page rather than the screen. */
  .rb-foot{
    background:none;
    color:var(--rb-text);
    margin:0;
    padding:8pt 0 0;
    border-top:.5pt solid var(--rb-border);
    font-size:8pt;
  }
  .rb-foot-bar{border:0;padding:0}
  .rb-foot-bar p{color:var(--rb-text)}
  .rb-print-src{display:block}
}

@page{margin:16mm 14mm}

/* ---------------------------------------------------------------------------
 * .table-scroll — the server-side table wrapper (docs/REMEDIATION.md R1).
 *
 * tools/export.php wraps all 1029 tables in <div class="table-scroll"> so the
 * scroll container exists in the HTML itself. Without a rule here that div is
 * inert, and with JS disabled a 14-column ranking table pushed the whole page
 * to 453px inside a 390px viewport (measured). The JS enhancement adopts this
 * same element rather than nesting its own, so these declarations are the
 * no-JS floor and the enhanced path builds on top of them.
 * ------------------------------------------------------------------------- */
.rb-prose .table-scroll{
  max-width:100%;
  overflow-x:auto;
  overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
  /* Keep a focus ring when the JS pass makes this a focusable scroll region. */
  scrollbar-width:thin;
}
/* Inset, not outset. This ruleset is (0,2,0) and sits AFTER the identical
   .rb-scroll:focus-visible rule at spec 17.5, so it won and put the ring 4px
   OUTSIDE .rb-tw's overflow:hidden clip box, where every pixel of it was
   clipped away - a WCAG 2.4.7 failure on the table's only keyboard control.
   Now it says the same thing as the rule it used to override. */
.rb-prose .table-scroll:focus-visible{
  outline:3px solid var(--rb-focus);
  outline-offset:-3px;
}
/* An inline width wider than the column would defeat the scroller by forcing
   the wrapper itself wide; the table may exceed the wrapper, the wrapper may
   not exceed the column. */
.rb-prose .table-scroll > table{ max-width:none; }

/* ---------------------------------------------------------------------------
 * Hub link-grids and stale inline table sizing.
 *
 * `data-grid="links"` is set by tools/export.php on the 14 tables whose every
 * cell is a link and which have no header row — the navigation grids on
 * /worlds-top-banks, /rankings and the other hub pages.
 *
 * Four of them carry a 2011 inline `width:NNNpx` (670px on /worlds-top-banks)
 * that is narrower than today's 832px article column, so the browser squeezed
 * the columns and every label broke onto two lines. One also carries
 * `height:370px`, which stretched each row to ~120px. Both are inline styles,
 * so overriding them needs !important — that is the whole reason it is used
 * here and nowhere else.
 *
 * `width:auto` rather than `100%`: auto lets each column take the width its
 * label actually needs, which stops the wrapping without spreading a three-item
 * row across the full column.
 * ------------------------------------------------------------------------- */
.rb-prose table[data-grid="links"]{
  width:auto!important;
  height:auto!important;
  border-collapse:collapse;
}
.rb-prose table[data-grid="links"] > tbody > tr,
.rb-prose table[data-grid="links"] > tbody > tr > td{
  height:auto!important;
}
.rb-prose table[data-grid="links"] > tbody > tr > td{
  padding:var(--rb-s-2, 8px) var(--rb-s-6, 24px) var(--rb-s-2, 8px) 0;
  vertical-align:baseline;
  /* The labels are short proper nouns; breaking "Top Banks by Market Cap 2018"
     mid-phrase is what the fixed width was forcing. */
  white-space:normal;
  text-wrap:pretty;
}

/* An inline `height` on a table is always a 2011 artefact: it stretches every
   row to fill a height the content never needed. 5 tables carry one. */
.rb-prose table[style*="height"],
.rb-prose table[style*="height"] > tbody > tr,
.rb-prose table[style*="height"] > tbody > tr > td{height:auto!important}

/* `.sub` is a 2011 sub-heading: legacy.css renders it display:block, 18px,
   margin-top:24px. That is right where it introduces a section, but the hub
   grids reuse the same class as a plain link LABEL — so every cell became an
   18px block heading with a 24px margin above it. That is what pushed
   "Top Banks by assets 2017" onto two lines and made the rows ~120px tall.
   Inside a link grid it is a label, so make it behave like one. */
.rb-prose table[data-grid="links"] .sub,
.rb-prose table[data-grid="links"] .sub1{
  display:inline;
  font-size:inherit;
  line-height:inherit;
  font-weight:inherit;
  margin:0;
  padding:0;
}

/* ---------------------------------------------------------------------------
 * Search pagination. search.php has always computed `pager`, `prev_url` and
 * `next_url`; search.tpl rendered none of it, so a query matching 789 documents
 * left 779 of them unreachable at 10 per page.
 * ------------------------------------------------------------------------- */
.rb-pager{
  display:flex;align-items:center;gap:var(--rb-s-4,16px);flex-wrap:wrap;
  margin-top:var(--rb-s-8,32px);padding-top:var(--rb-s-4,16px);
  border-top:1px solid var(--rb-border,#d8dde5);
}
.rb-pager-list{display:flex;gap:var(--rb-s-1,4px);list-style:none;margin:0;padding:0}
.rb-pager-n,.rb-pager-step{
  display:inline-block;min-width:2.25rem;padding:.35rem .6rem;
  text-align:center;text-decoration:none;
  /* --rb-border is a hairline for separating content and is 1.36:1 on white.
     These are text-decoration:none boxed controls, so the box IS the control's
     visible boundary and WCAG 1.4.11 wants 3:1 for it. --rb-blue-400 (an
     existing, previously unused step) measures 4.84:1 on white and 4.31:1 on
     the hover tint. */
  border:1px solid var(--rb-blue-400,#4d6ec4);
  font-variant-numeric:tabular-nums;
}
.rb-pager-n:hover,.rb-pager-step:hover{background:var(--rb-surface-tint,#f1f4f9);text-decoration:underline}
.rb-pager-n.is-current{
  background:var(--rb-masthead,#003399);border-color:var(--rb-masthead,#003399);
  color:#fff;font-weight:600;
}
.rb-pager-status{margin-top:var(--rb-s-2,8px);color:var(--rb-text-muted,#5a6472);font-size:.875rem}
@media(max-width:479.98px){
  .rb-pager{gap:var(--rb-s-2,8px)}
  .rb-pager-step{width:100%}
}
