/* ==================================================== type ========== */
/* IBM Plex, self-hosted.
 *
 * Before this, the stylesheet asked for Montserrat and shipped nothing, so
 * the application looked one way on a machine that happened to have it and
 * another way everywhere else — three officers, three different-looking
 * systems. A font the deployment does not carry is not a design decision,
 * it is a guess about the reader's computer.
 *
 * One family in three roles: text and headings separated by weight rather
 * than by typeface, and Plex Mono for member numbers, dates and money, where
 * figures must line up in a column. Plex was drawn for an engineering
 * company and reads that way, which is the right voice for a federation of
 * aeronautical information specialists.
 *
 * latin-ext is shipped alongside latin and is not optional here: Kovačič,
 * Çaltepe, Nowostawska, Fröhlich and Associação all live outside latin, and
 * a board member whose own name renders in a fallback face has been told
 * something about how carefully this was built. unicode-range means a reader
 * who needs no accents never downloads the file.
 */
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/fonts/ibm-plex-sans-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* =====================================================================
   IFAIMA platform — visual system
   Palette from "A More Unified, Recognizable Look for IFAIMA" (July 2026).

   The guide's recommendation is a two-layer system, not one palette:

     Core (always)   Federation Navy / IFAIMA Blue / Sky + neutrals.
     Digital range   Cyan and Signal Teal, for web, data and technical
                     material — which is what this application is.
     Event accent    One warm colour per Global AIM host city, never two at
                     once. Not part of the admin chrome.

   The rule it gives is the one this file follows:
   BLUE LEADS, NEUTRALS CARRY, ONE ACCENT POPS.

   TWO DELIBERATE DEPARTURES, both applying the guide's own principles
   rather than overriding them.

   1. Steel #64788C clears AA on white (4.56:1) but falls to 4.24:1 on
      Cloud, and in a register almost every small label sits on Cloud. So
      Steel stays the border colour and small secondary text uses --muted,
      Steel darkened one step, which clears AA on both grounds.

   2. Chart marks use darker steps than the UI chips. Run through the
      palette validator, the brand gold #FBB800 fails the lightness band
      (0.82) and sits at 1.71:1 against a light surface; teal and coral are
      also under 3:1. One step darker — #0E8F6E / #B8860B / #C6402B — passes
      every check: lightness band, CVD separation (worst adjacent ΔE 9.1
      deutan), normal-vision floor (16.3) and 3:1 contrast. The bright brand
      values stay where the guide intends them: as grounds carrying dark
      text, never as small marks or light text.
   ===================================================================== */

:root {
  /* ---- Core ------------------------------------------------------- */
  --navy:  #002B5C;
  --navy-2:#013A78;        /* one step up, for gradients and hovers      */
  --blue:  #0072BC;
  --sky:   #00AEEF;

  /* ---- Neutrals --------------------------------------------------- */
  --ink:   #12212E;
  --steel: #64788C;
  --muted: #556779;
  --cloud: #F4F7FA;
  --page:  #F7F9FB;
  --white: #FFFFFF;
  --line:  #DFE6EC;
  --line-2:#EDF1F5;

  /* ---- Digital range ---------------------------------------------- */
  --cyan:  #12B5CB;
  --teal:  #17B890;

  /* ---- Event accent ----------------------------------------------- */
  --gold:  #FBB800;
  --coral: #FF6B57;

  /* ---- Chart & status marks (validated darker steps) --------------- */
  --mark-good: #0E8F6E;
  --mark-warn: #B8860B;
  --mark-bad:  #C6402B;
  --mark-none: #E1E8EE;
  --mark-blue: #0072BC;

  /* Tints — grounds that still take ink text. */
  --navy-tint:#E7EFF6; --blue-tint:#E3F0FA; --teal-tint:#E4F5EF;
  --gold-tint:#FDF3DA; --coral-tint:#FEEBE7;

  /* ---- Type ------------------------------------------------------- */
  /* One family, separated by weight. Served from /fonts by this application
     itself, never from a CDN: the deployment host may have no outbound
     network, and a webfont that silently fails is worse than one never
     requested. The fallbacks are the reader's own system faces, so a missing
     file degrades to something decent rather than to Times New Roman. */
  --display: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --r: 8px;            /* the one radius, used everywhere               */
  --r-sm: 5px;
  --shadow: 0 1px 2px rgba(16,33,46,.05), 0 4px 14px rgba(16,33,46,.05);
  --shadow-lg: 0 12px 40px rgba(0,43,92,.16);
  --sidebar: 232px;
}

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--page); color: var(--ink); font: 14.5px/1.55 var(--body); -webkit-font-smoothing: antialiased; }
h1,h2,h3,h4 { font-family: var(--display); font-weight: 600; letter-spacing: -.01em; margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--blue); }
.hidden { display: none !important; }
:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; border-radius: 3px; }

/* ==================================================== sign in ======= */
#login { min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: linear-gradient(150deg, var(--navy) 0%, #00203F 55%, #001832 100%); }
#login .box { background: var(--white); border-radius: var(--r); padding: 38px 36px 34px; width: 100%; max-width: 396px; box-shadow: var(--shadow-lg); }
/* The mark, as supplied: a white roundel carrying the globe and wordmark,
   derived from the master by masking away the black export canvas. Never
   recoloured, stretched or knocked out — all three are on the guide's
   don't list. It carries its own white ground, so one file serves both the
   navy chrome and a white card. */
#login .logo { display: block; width: 148px; height: 148px; margin: -10px 0 8px -12px; }
#login .sub { margin: 0 0 26px; color: var(--muted); font-size: 13.5px; }
#login label { display: block; font-size: 11.5px; font-weight: 600; margin: 16px 0 6px; letter-spacing: .01em; }
#login input { width: 100%; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--white); }
#login input:focus { border-color: var(--blue); }
#login button[type=submit] { width: 100%; margin-top: 24px; padding: 12px; background: var(--blue); color: #fff; border: 0; border-radius: var(--r-sm); font-family: var(--display); font-weight: 700; }
#login button[type=submit]:hover { background: var(--navy); }
#login button[type=submit]:disabled { opacity: .55; cursor: default; }
/* The way back when a password has gone. Quiet — it is the second thing
   anybody wants from this card, not the first — but present, because the
   alternative is a telephone call to the Secretariat. */
#login .linkline { margin: 18px 0 0; text-align: center; font-size: 13px; }
#login .linkline a { color: var(--blue); text-decoration: none; }
#login .linkline a:hover { text-decoration: underline; }

/* Tinted ground with ink text — never light text on a bright accent, which
   is the guide's main legibility warning. */
.msg { margin-top: 16px; padding: 10px 13px; font-size: 13.5px; border-radius: var(--r-sm); background: var(--coral-tint); border-left: 3px solid var(--coral); }
.msg.warn { background: var(--gold-tint); border-left-color: var(--gold); }
.msg.good { background: var(--teal-tint); border-left-color: var(--teal); }

/* ==================================================== shell ========= */
#app { display: grid; grid-template-columns: var(--sidebar) 1fr; min-height: 100vh; }

/* The rail is a fixed-height column: brand at the top, navigation in the
   middle, identity and sign-out pinned to the bottom. The navigation is the
   part that scrolls.
   Before this it relied on a flexible spacer to push the footer down, which
   works only while everything fits. At a 700px-tall window the content came
   to 775px and the sign-out button was simply below the edge of a pane that
   could not scroll — present in the markup, unreachable by the reader. */
aside.rail { background: var(--navy); color: #fff; display: flex; flex-direction: column; gap: 4px; padding: 18px 14px; position: sticky; top: 0; height: 100vh; overflow: hidden; }
.rail .brand { display: flex; align-items: center; gap: 11px; padding: 4px 8px 20px; }
.rail .brand img { width: 34px; height: 34px; }
.rail .brand b { font-family: var(--display); font-size: 16px; letter-spacing: .02em; display: block; }
.rail .brand small { font-size: 11px; opacity: .66; display: block; margin-top: 1px; }
.rail nav { display: flex; flex-direction: column; gap: 2px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.28) transparent; }
.rail nav::-webkit-scrollbar { width: 6px; }
.rail nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.28); border-radius: 3px; }
/* Section labels: the sidebar of a governing body's system should read as an
   organisation chart, not a list of screens. */
.rail .navlabel { font-family: var(--display); font-size: 9.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; opacity: .45; padding: 16px 12px 5px; }
.rail nav button { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: transparent; border: 0; color: #fff; opacity: .76; padding: 9px 12px; border-radius: var(--r-sm); font-size: 14px; text-align: left; font-family: var(--display); font-weight: 600; }
.rail nav button:hover { opacity: 1; background: rgba(255,255,255,.09); }
.rail nav button.on { opacity: 1; background: var(--blue); }
.rail nav .tag { font-family: var(--mono); font-size: 11px; background: rgba(255,255,255,.18); padding: 1px 6px; border-radius: 20px; }
/* A count of nothing is not a count. An empty pill reads as a dash and
   makes a reader wonder what it is hiding. */
.rail nav .tag:empty { display: none; }
.rail .spacer { display: none; }
.rail .foot { flex: none; padding: 10px 12px; border-top: 1px solid rgba(255,255,255,.14); font-size: 12px; opacity: .7; }
.rail .foot b { display: block; font-weight: 600; opacity: 1; font-size: 12.5px; margin-bottom: 2px; overflow-wrap: anywhere; }
.rail .foot .signout { display: block; width: 100%; margin-top: 10px; padding: 8px;
  background: transparent; border: 1px solid rgba(255,255,255,.22); color: #fff;
  border-radius: var(--r-sm); font-family: var(--display); font-weight: 600;
  font-size: 12.5px; opacity: .85; }
.rail .foot .signout:hover { background: rgba(255,255,255,.1); opacity: 1; }
.rail .foot .signout:disabled { opacity: .5; }
.rail .add { flex: none; margin: 14px 0 6px; background: var(--sky); color: var(--ink); border: 0; border-radius: var(--r-sm); padding: 10px; font-family: var(--display); font-weight: 700; font-size: 13.5px; }
.rail .add:hover { background: #2ABEF5; }

main { padding: 26px 30px 70px; max-width: 1560px; }
.page-head { display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap; margin-bottom: 22px; }
.page-head h1 { font-size: 25px; }
.page-head p { margin: 4px 0 0; color: var(--muted); font-size: 14px; }
.page-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* ==================================================== cards ========= */
.card { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); }
.card > header { padding: 15px 18px 0; }
.card > header h3 { font-size: 14.5px; }
.card > header p { margin: 3px 0 0; color: var(--muted); font-size: 12.5px; }
.card .body { padding: 16px 18px 18px; }

/* North-star figure, top-left, per the F-pattern. */
.hero { display: grid; grid-template-columns: minmax(260px, 1.15fr) repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 16px; }
.hero .headline { background: linear-gradient(145deg, var(--navy) 0%, var(--navy-2) 100%); color: #fff; border-radius: var(--r); padding: 20px 22px; box-shadow: var(--shadow); }
.hero .headline .k { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; opacity: .72; }
.hero .headline .v { font-family: var(--display); font-size: 40px; font-weight: 700; letter-spacing: -.03em; line-height: 1.05; margin: 8px 0 2px; font-variant-numeric: tabular-nums; }
.hero .headline .sub { font-size: 13px; opacity: .8; }
.tile { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); padding: 15px 17px; box-shadow: var(--shadow); border-left: 3px solid transparent; }
.tile .v { font-family: var(--display); font-size: 25px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.tile .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em; color: var(--muted); margin-top: 5px; }
.tile .cap { font-size: 12px; color: var(--muted); margin-top: 6px; }
.tile.warn { border-left-color: var(--gold); }
.tile.bad  { border-left-color: var(--coral); }
.tile.good { border-left-color: var(--teal); }

.grid-2 { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 1180px) { .grid-2 { grid-template-columns: 1fr; } }

/* ==================================================== charts ======== */
.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); margin: 2px 0 14px; }
.legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; margin-right: 6px; vertical-align: -1px; }

/* Stacked columns: collected + outstanding per year. A 2px surface gap
   separates the two fills, and data-ends are rounded 4px. */
.bars { display: flex; align-items: flex-end; gap: 5px; height: 190px; }
.bars .col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; height: 100%; position: relative; min-width: 0; }
.bars .seg { border-radius: 2px; min-height: 2px; }
.bars .seg.top { border-radius: 4px 4px 2px 2px; }
.bars .col .xl { position: absolute; bottom: -20px; left: 0; right: 0; text-align: center; font-size: 10px; color: var(--muted); font-family: var(--mono); white-space: nowrap; }
/* A label is wider than its column, so it overhangs both sides. At the two
   ends there is nothing to overhang into and the text is clipped away — which
   is how the most recent year, the one that matters, went missing. */
/* left:0;right:0 pins the box to a 13px column, so a five-character label
   overhangs its own box and the scroll container clips whatever leaves the
   chart. At the ends, let the box size to its text and grow inwards. */
.bars .col:first-child .xl { text-align: left;  left: 0; right: auto; width: max-content; }
.bars .col:last-child  .xl { text-align: right; right: 0; left: auto; width: max-content; }
.bars-wrap { padding-bottom: 24px; }
.bars .col:hover .seg { filter: brightness(1.08); }

/* Ranked horizontal bars: one hue, sorted, value labelled at the end. */
.hbars { display: grid; gap: 9px; }
.hbar { display: grid; grid-template-columns: 74px 1fr auto; align-items: center; gap: 11px; font-size: 13px; }
/* Region codes are four characters; country names are not. When the breakdown
   is by country the label column widens and the name wraps rather than being
   squeezed into a stack of one word per line. */
.hbars.wide .hbar { grid-template-columns: minmax(96px, 132px) 1fr auto; }
.hbars.wide .hbar .lbl { font-family: var(--body); font-size: 12.5px; line-height: 1.25; overflow-wrap: anywhere; }
.hbar .lbl { color: var(--ink); font-family: var(--mono); font-size: 12px; }
.hbar .track { display: block; background: var(--cloud); border-radius: 4px; height: 16px; overflow: hidden; }
.hbar .fill { display: block; height: 100%; background: var(--mark-blue); border-radius: 4px; min-width: 3px; }
.hbar .val { font-family: var(--mono); font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--ink); }

/* ======================================= the history sparkline ====== */
/* Eighteen financial years as a win/loss sparkline — Tufte's form, and the
   canonical answer for a categorical series inside a table row.
 *
 * POSITION IS THE ENCODING. Settled years sit ABOVE the baseline; part-paid
 * and unpaid years hang BELOW it. Colour only confirms what position already
 * said, which is why thirty of these read as a page of shapes rather than as
 * the wall of red and green a full-height stoplight strip produces.
 *
 * FIVE RULES THIS LAYOUT DEPENDS ON.
 *
 * 1. The columns flex (flex: 1 1 0; min-width: 0), so eighteen years fit a
 *    176px table cell and the same markup fills a 900px card. Nothing here has
 *    a fixed width, which is why it never wraps and never overflows — 1fr
 *    would have stretched to min-content and pushed the row sideways.
 * 2. Each column is FULL HEIGHT even though its mark is 7px, so the hit target
 *    for a fingertip is the whole column, not the mark.
 * 3. The baseline is one hairline behind the marks (z-index 0 under 1), drawn
 *    once on the container rather than per year — a per-year rule would show
 *    the gaps as breaks in the axis.
 * 4. Colour is never the only encoding: position carries the state, a standing
 *    pill beside it says it in words, every column has a tooltip on hover and
 *    on tap, and the whole sparkline reports itself to a screen reader as one
 *    sentence.
 * 5. Only the member's own page carries labels under it — the two end years.
 *    On a list all thirty rows span the same eighteen years, so a caption on
 *    each is thirty pieces of furniture saying one thing. */
.histcell { display: block; width: 100%; min-width: 0; }

.wl { position: relative; display: flex; gap: 1px; align-items: center;
      height: 22px; width: 100%; min-width: 0; }
.wl::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--line); z-index: 0;
}
.wl i { flex: 1 1 0; min-width: 0; height: 100%; display: block; position: relative; z-index: 1; }
.wl i::after { content: ""; position: absolute; left: 0; right: 0; border-radius: 1px; background: var(--mark-good); }

/* Above the line: the federation was paid. */
.wl i.settled::after { bottom: 50%; height: 7px; margin-bottom: 1px; }
/* Below it: it was not. Part-paid is drawn shorter than unpaid, so the depth
   of the mark is itself a rough measure of how much is still owed. */
.wl i.part::after  { top: 50%; height: 5px; margin-top: 1px; background: var(--mark-warn); }
.wl i.owing::after { top: 50%; height: 7px; margin-top: 1px; background: var(--mark-bad); }

/* A recognised year with no invoice against it. A small neutral tick ON the
   line rather than empty space: 145 members were missed for 26/27, and that
   gap is a finding the register should show, not a blank. */
.wl i.none::after { top: 50%; height: 3px; margin-top: -1px; background: var(--mark-none); border-radius: 0; }
/* A set-aside year with no invoice is genuinely nothing. Leave it empty. */
.wl i.none.aside::after { display: none; }

/* Years before the recognition line. Faded rather than hidden — the federation
   has decided not to pursue EUR 87,185 of them, so they must not shout in the
   same red as a live debt, but a set-aside debt is not a debt that never
   happened. */
.wl i.aside::after { opacity: .4; }

/* Where recognition begins: a hairline down the full height of the column. */
.wl i.from { border-left: 1px solid var(--steel); }

.wl.lg { height: 34px; gap: 2px; }
.wl.lg i.settled::after,
.wl.lg i.owing::after { height: 11px; }
.wl.lg i.part::after  { height: 8px; }
.wl.lg i.none::after  { height: 4px; margin-top: -2px; }

/* The two ends of the timeline, named. Member page only. */
.hsum {
  display: flex; justify-content: space-between; gap: 8px; margin-top: 8px;
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* The key has to teach POSITION, so each swatch is a miniature of the mark it
   stands for, sitting above or below its own baseline. A coloured square would
   quietly teach the reader that colour is what carries the meaning. */
.legend.mk i.mark {
  width: 13px; height: 14px; border-radius: 0; background: none;
  position: relative; margin-right: 7px; vertical-align: -3px;
}
.legend.mk i.mark::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--line);
}
.legend.mk i.mark::after { content: ""; position: absolute; left: 1px; right: 1px; border-radius: 1px; }
.legend.mk i.mark.settled::after { bottom: 50%; height: 6px; margin-bottom: 1px; background: var(--mark-good); }
.legend.mk i.mark.part::after    { top: 50%; height: 4px; margin-top: 1px; background: var(--mark-warn); }
.legend.mk i.mark.owing::after   { top: 50%; height: 6px; margin-top: 1px; background: var(--mark-bad); }
.legend.mk i.mark.none::after    { top: 50%; height: 3px; margin-top: -1px; background: var(--mark-none); }
.legend.mk i.mark.faded::after   { opacity: .4; }

/* ==================================================== tooltip ======= */
/* Fixed to the viewport and parented to <body>, so no scroll container can
   clip it. It replaces the title attribute, which on a phone never appeared
   at all — half the board could not read a single cell. */
.tip {
  position: fixed; z-index: 90; pointer-events: none;
  background: var(--ink); color: #fff; font-size: 12px; line-height: 1.45;
  font-family: var(--mono); padding: 7px 10px; border-radius: var(--r-sm);
  max-width: 260px; box-shadow: 0 6px 20px rgba(18,33,46,.28);
}
.tip::after {
  content: ""; position: absolute; left: var(--arrow, 50%); margin-left: -5px; bottom: -5px;
  border: 5px solid transparent; border-top-color: var(--ink); border-bottom: 0;
}
.tip.below::after { bottom: auto; top: -5px; border-top: 0; border-bottom: 5px solid var(--ink); }

/* ==================================================== pills ========= */
.pill { display: inline-flex; align-items: center; gap: 5px; font-family: var(--display); font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 3px 8px; border-radius: 20px; background: var(--cloud); color: var(--muted); white-space: nowrap; }
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.plain::before { display: none; }
.pill.paid     { background: var(--teal-tint);  color: #0B6B52; }
.pill.owing    { background: var(--coral-tint); color: #A3301F; }
.pill.exempt   { background: var(--navy-tint);  color: var(--navy); }
.pill.unbilled { background: var(--cloud);      color: var(--muted); }
.pill.ASS { background: var(--navy-tint); color: var(--navy); }
.pill.COR { background: var(--blue-tint); color: #005A95; }
.pill.IND { background: var(--cloud); color: var(--muted); }
.pill.HON { background: var(--teal-tint); color: #0B6B52; }
.pill.error   { background: var(--coral-tint); color: #A3301F; }
.pill.warning { background: var(--gold-tint);  color: #7A5100; }
.pill.info    { background: var(--cloud); color: var(--muted); }
.pill.resolved{ background: var(--teal-tint); color: #0B6B52; }

/* ==================================================== controls ====== */
.toolbar { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.field { position: relative; flex: 1; min-width: 230px; }
.field input { width: 100%; padding: 9px 12px 9px 34px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--white); }
.field::before { content: "⌕"; position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 15px; }
select, .btn { padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--white); font-size: 13.5px; }
select:focus, input:focus, textarea:focus { border-color: var(--blue); outline: none; }
.btn { font-family: var(--display); font-weight: 600; color: var(--navy); }
.btn:hover { background: var(--cloud); }
.btn.primary { background: var(--blue); color: #fff; border-color: var(--blue); }
.btn.primary:hover { background: var(--navy); border-color: var(--navy); }
.btn.sm { padding: 5px 10px; font-size: 12.5px; }
.count { margin-left: auto; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* ==================================================== charts ========= */
/* Two primitives. Both are width-agnostic by construction: the bar fills
   whatever it is given, the line stretches into whatever it is given, and
   every piece of text in either is HTML laid out in normal flow. Nothing
   here has a minimum width, so nothing here breaks on a phone. */

.propcard { margin-bottom: 16px; }

.propbar .track {
  display: flex; gap: 2px; height: 26px; border-radius: 6px;
  background: var(--mark-none); overflow: hidden;
}
.propbar .track .part { display: block; height: 100%; min-width: 3px; }
.propbar .track .part:first-child { border-radius: 6px 0 0 6px; }
.propbar .track .part:last-child  { border-radius: 0 6px 6px 0; }
.propbar .track .part:only-child  { border-radius: 6px; }

.propbar .keys { display: flex; flex-wrap: wrap; gap: 12px 34px; margin-top: 15px; }
.propbar .key { min-width: 0; }
.propbar .kh { display: flex; align-items: center; gap: 7px; font-size: 12px;
  text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  font-family: var(--display); font-weight: 700; }
.propbar .kh i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex: none; }
.propbar .kv { font-family: var(--display); font-size: 23px; font-weight: 700;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; margin-top: 4px; }
.propbar .kp { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.trend { position: relative; padding-bottom: 22px; }
.trend svg { display: block; width: 100%; height: 190px; overflow: visible; }
.trend .area { fill: var(--blue-tint); }
.trend .line { fill: none; stroke: var(--mark-blue); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; }
.trend .target { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 4; }

.trend .targetlabel, .trend .lastlabel {
  position: absolute; font-size: 10.5px; font-family: var(--display); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; pointer-events: none;
  transform: translateY(-140%); white-space: nowrap;
}
.trend .targetlabel { left: 0; color: var(--muted); }
.trend .lastlabel { right: 0; color: var(--navy); background: var(--white);
  padding: 1px 5px; border-radius: 4px; transform: translateY(-150%); }

.trend .dot { position: absolute; width: 9px; height: 9px; border-radius: 50%;
  background: var(--mark-blue); border: 2px solid var(--white);
  transform: translate(-50%, -50%); pointer-events: none; }
.trend .dot.last { box-shadow: 0 0 0 3px var(--blue-tint); }
.trend .cross { position: absolute; top: 0; height: 190px; width: 1px;
  background: var(--steel); opacity: .4; pointer-events: none; }

.trend .hits { position: absolute; inset: 0 0 22px 0; display: block; }
.trend .hit { position: absolute; top: 0; bottom: 0; background: transparent;
  border: 0; padding: 0; cursor: pointer; }
.trend .hit:focus-visible { background: rgba(0,114,188,.08); outline: none; }

.trend .tip { position: absolute; top: 8px; transform: translateX(-50%);
  background: var(--navy); color: #fff; border-radius: var(--r-sm);
  padding: 8px 11px; font-size: 12.5px; line-height: 1.35; pointer-events: none;
  box-shadow: var(--shadow-lg); max-width: 230px; z-index: 2; }
.trend .tip.left  { transform: translateX(-100%); }
.trend .tip.right { transform: translateX(0); }
.trend .tip b { display: block; font-family: var(--display); font-size: 12.5px; margin-bottom: 2px; }
.trend .tip span { opacity: .82; }

.trend .axis { position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 11px; color: var(--muted); }

/* =================================================== admissions ====== */
/* A Regional Director proposes; an officer decides. One card per
   application, with everything a decision needs on it — nobody should have
   to open another screen to answer yes or no. */
.card.admission { margin-bottom: 12px; }
.admission .atop { display: flex; gap: 13px; align-items: center; }
.afacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px 20px; margin: 15px 0 4px; padding-top: 14px; border-top: 1px solid var(--line-2); }
.afacts .fk { display: block; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .09em; color: var(--muted); font-family: var(--display); font-weight: 700; }
.afacts .fv { display: block; font-size: 13.5px; margin-top: 3px; overflow-wrap: anywhere; }
.admission .anote { margin: 12px 0 0; font-size: 13.5px; color: var(--muted); }
.admission .aacts { display: flex; gap: 9px; justify-content: flex-end; margin-top: 16px; }

.declined { display: grid; grid-template-columns: minmax(120px,1fr) 110px 2fr 100px;
  gap: 12px; align-items: baseline; padding: 11px 18px; border-bottom: 1px solid var(--line-2);
  font-size: 13px; }
.declined:last-child { border-bottom: 0; }
.declined .ref { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.declined .why { color: var(--muted); }
.declined .when { font-family: var(--mono); font-size: 12px; color: var(--muted); text-align: right; }

/* =================================================== payments ======== */
/* A payment and what it settled, on one line. The workbook could record an
   amount against a member-year and nothing else, so "which years did our
   March transfer cover?" had no answer. */
.payrow { display: flex; gap: 16px; align-items: baseline; flex-wrap: wrap;
  padding: 11px 0; border-bottom: 1px solid var(--line-2); }
.payrow:last-child { border-bottom: 0; }
.payrow .pw { min-width: 190px; }
.payrow .pw b { font-family: var(--mono); font-size: 14px; font-variant-numeric: tabular-nums; }
.payrow .pw span { display: block; font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.payrow .pa { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; flex: 1; }
.alloc { font-family: var(--mono); font-size: 11.5px; background: var(--teal-tint);
  color: #0B6B52; padding: 2px 8px; border-radius: 20px; white-space: nowrap; }
.alloc b { font-weight: 700; margin-right: 4px; }
.alloc.none { background: var(--gold-tint); color: #7A5100; font-family: var(--body); }
.payrow .pref { font-size: 12px; color: var(--muted); margin-left: auto; }
.empty-line { color: var(--muted); font-size: 13.5px; margin: 0; }

/* The allocation preview, shown while the amount is being typed. This is the
   check the spreadsheet never had. */
.preview { margin-top: 16px; background: var(--cloud); border-radius: var(--r-sm); padding: 12px 14px; }
.preview:empty { display: none; }
.preview .ptitle { font-family: var(--display); font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em; color: var(--muted); margin-bottom: 8px; }
.preview .pline { display: flex; gap: 12px; align-items: baseline; font-size: 13px;
  padding: 4px 0; font-variant-numeric: tabular-nums; }
.preview .pline b { font-family: var(--mono); min-width: 52px; }
.preview .pline .cl { color: var(--muted); font-size: 12px; margin-left: auto; }
.preview .pline.over { color: #7A5100; border-top: 1px solid var(--line); margin-top: 6px; padding-top: 8px; }

/* =================================================== treasury ======== */
.sechead { font-size: 14.5px; margin: 22px 0 10px; }
.subhead { font-size: 12px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); font-family: var(--display); margin: 20px 0 8px; }

.rows .head.yhead span { white-space: nowrap; }
.rows .head.yhead, .row.yrow {
  grid-template-columns: 56px minmax(140px,1.3fr) 86px 78px 76px 86px 88px 96px 66px;
}
.row.yrow { cursor: default; }
.row.yrow .yr { font-family: var(--mono); font-weight: 700; font-size: 13px; }
.row.yrow .per { color: var(--muted); font-size: 12.5px; }
.row.yrow .n { text-align: right; font-family: var(--mono); font-size: 12.5px;
  font-variant-numeric: tabular-nums; }
.row.yrow .n.owing { color: #A3301F; font-weight: 700; }
.row.yrow .act { text-align: right; }

.runsum { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.runsum .rb { background: linear-gradient(145deg, var(--navy) 0%, var(--navy-2) 100%);
  color: #fff; border-radius: var(--r); padding: 14px 18px; flex: 1 1 190px; }
.runsum .rc { background: var(--cloud); border-radius: var(--r); padding: 14px 18px; flex: 1 1 120px; }
.runsum .v { font-family: var(--display); font-size: 22px; font-weight: 700;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.runsum .rb .v { font-size: 26px; }
.runsum .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  opacity: .75; margin-top: 4px; }
.runsum .cap { font-size: 12.5px; margin-top: 5px; opacity: .85; }

.skips { display: grid; gap: 2px; }
.skip { display: flex; gap: 12px; align-items: baseline; font-size: 13px;
  padding: 7px 10px; background: var(--cloud); border-radius: var(--r-sm); }
.skip b { font-family: var(--mono); min-width: 34px; text-align: right; }
.skip span { color: var(--muted); }

@media (max-width: 1000px) {
  .rows .head.yhead { display: none; }
  .row.yrow { display: flex; flex-wrap: wrap; gap: 6px 12px; }
  .row.yrow .n { text-align: left; }
  .row.yrow .act { margin-left: auto; }
}

table.t.recon { margin-top: 16px; }
table.t.recon th { background: var(--cloud); font-family: var(--display); font-size: 10.5px;
  font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); }
table.t.recon th.num, table.t.recon td.num { text-align: right; font-family: var(--mono);
  font-size: 12.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.t.recon td { padding: 9px 12px; border-top: 1px solid var(--line-2); font-size: 13.5px; }
table.t.recon .sub { color: var(--muted); font-family: var(--mono); font-size: 11.5px; }

.bigstate { border-radius: var(--r); padding: 16px 20px; margin-bottom: 18px; }
.bigstate.shadow { background: var(--gold-tint); border-left: 4px solid var(--mark-warn); }
.bigstate.live { background: var(--teal-tint); border-left: 4px solid var(--mark-good); }
.bigstate .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); font-family: var(--display); font-weight: 700; }
.bigstate .v { font-family: var(--display); font-size: 19px; font-weight: 700;
  letter-spacing: -.01em; margin-top: 5px; }
.bankline { display: flex; gap: 12px; align-items: baseline; padding: 9px 0;
  border-top: 1px solid var(--line-2); font-size: 13.5px; }
.bankline span { color: var(--muted); font-family: var(--mono); font-size: 12.5px; }

/* ==================================================== toast ========= */
.toast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 120%);
  background: var(--navy); color: #fff; padding: 12px 18px; border-radius: var(--r);
  box-shadow: var(--shadow-lg); font-size: 13.5px; max-width: min(520px, calc(100% - 32px));
  z-index: 60; opacity: 0; transition: transform .22s ease, opacity .22s ease; pointer-events: none; }
.toast.on { transform: translate(-50%, 0); opacity: 1; }
.toast.bad { background: #8E2E1E; }

/* ==================================================== register ====== */
.rows { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); overflow: hidden; }
.rows .head, .row { display: grid; grid-template-columns: 44px minmax(220px,2.4fr) 96px 92px minmax(120px,1fr) 176px 132px; gap: 14px; align-items: center; padding: 11px 18px; }
/* The register without its two money columns, for a reader without finance.view. */
.rows.nofin .head, .rows.nofin .row { grid-template-columns: 44px minmax(220px,2.4fr) 96px 92px minmax(120px,1fr); }
.rows .head { background: var(--cloud); border-bottom: 1px solid var(--line); font-family: var(--display); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); padding-top: 10px; padding-bottom: 10px; }
.rows .head span[data-sort] { cursor: pointer; }
.rows .head span[data-sort]:hover { color: var(--navy); }
/* Which column the list is ordered by. Without this the reader has to infer
   the order from the rows, which is guesswork the moment a filter is on. */
.rows .head span.sorted { color: var(--navy); }
.rows .head span.sorted::after { content: " \2193"; font-size: 10px; opacity: .7; }
.row { border-bottom: 1px solid var(--line-2); cursor: pointer; }
.row:last-child { border-bottom: 0; }
.row:hover { background: var(--cloud); }
.mono { width: 36px; height: 36px; border-radius: 9px; display: grid; place-items: center; font-family: var(--display); font-weight: 700; font-size: 12.5px; background: var(--navy-tint); color: var(--navy); letter-spacing: .02em; }
.mono.COR { background: var(--blue-tint); color: #005A95; }
.mono.IND { background: var(--cloud); color: var(--muted); }
.mono.HON { background: var(--teal-tint); color: #0B6B52; }
/* An association's own mark, where one has been supplied, in place of the
   initials. Contained rather than cropped: these are logos of every shape. */
.mono.logo { background: var(--white); border: 1px solid var(--line); padding: 3px; overflow: hidden; }
.mono.logo img { width: 100%; height: 100%; object-fit: contain; display: block; }

.logo-drop { display: flex; align-items: center; gap: 14px; }
.logo-drop .preview { width: 72px; height: 72px; border-radius: 12px; border: 1px dashed var(--line); display: grid; place-items: center; background: var(--cloud); overflow: hidden; flex: none; }
.logo-drop .preview img { width: 100%; height: 100%; object-fit: contain; }
.logo-drop .preview span { font-size: 11px; color: var(--muted); text-align: center; padding: 6px; }

.contact-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-2); }
.contact-row:last-of-type { border-bottom: 0; }
.contact-row .grow { flex: 1; min-width: 0; }
.contact-row .acts { display: flex; gap: 5px; flex: none; }
/* The full legal name leads. The acronym is how the workbook referred to
   members, but it is not what they are called. */
.who .name { font-weight: 600; font-size: 14.5px; line-height: 1.3; }
.who .meta { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.who .meta b { font-family: var(--mono); font-weight: 400; color: var(--steel); }
.amount { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 13.5px; }
.amount.owed { font-weight: 700; }
.amount .nil { color: var(--muted); }
.empty { padding: 56px 24px; text-align: center; color: var(--muted); }
.empty h3 { color: var(--ink); margin-bottom: 6px; font-size: 16px; }
.empty p { margin: 0 auto 16px; max-width: 46ch; }

/* ==================================================== member page === */
.member-head { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 20px; }
.member-head .mono { width: 56px; height: 56px; border-radius: 14px; font-size: 17px; }
.member-head h1 { font-size: 24px; line-height: 1.2; max-width: 34ch; }
.member-head .en { color: var(--muted); font-size: 14px; margin-top: 4px; max-width: 60ch; }
.member-head .ids { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 9px; }
.member-head .ids code { font-family: var(--mono); font-size: 12.5px; background: var(--cloud); padding: 2px 8px; border-radius: 20px; color: var(--navy); }
.member-head .right { margin-left: auto; display: flex; gap: 8px; }

.kv { display: grid; grid-template-columns: 150px 1fr; gap: 8px 16px; font-size: 14px; margin: 0; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }
.kv input, .kv select { width: 100%; padding: 6px 9px; border: 1px solid var(--line); border-radius: var(--r-sm); }

table { border-collapse: collapse; width: 100%; font-size: 13.5px; }
th, td { text-align: left; padding: 9px 14px; border-bottom: 1px solid var(--line-2); }
thead th { background: var(--cloud); font-family: var(--display); font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 700; }
td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
tbody tr:last-child td { border-bottom: 0; }
.tablewrap { overflow-x: auto; }
.note { background: var(--gold-tint); border-left: 3px solid var(--gold); padding: 11px 14px; font-size: 13.5px; border-radius: 0 var(--r-sm) var(--r-sm) 0; margin: 12px 0; }
.note.err { background: var(--coral-tint); border-left-color: var(--coral); }
.note.info { background: var(--blue-tint); border-left-color: var(--blue); }
.legacy { color: var(--muted); font-size: 11.5px; font-family: var(--mono); }

/* ==================================================== dialog ======== */
#scrim { position: fixed; inset: 0; background: rgba(0,25,50,.42); z-index: 40; }
.dialog { position: fixed; z-index: 41; top: 50%; left: 50%; transform: translate(-50%,-50%); width: min(680px, calc(100% - 32px)); max-height: 88vh; overflow-y: auto; background: var(--white); border-radius: var(--r); box-shadow: var(--shadow-lg); }
.dialog header { padding: 20px 24px 12px; border-bottom: 1px solid var(--line-2); }
.dialog header h2 { font-size: 18px; }
.dialog header p { margin: 4px 0 0; color: var(--muted); font-size: 13px; }
.dialog .body { padding: 20px 24px; }
.dialog footer { padding: 14px 24px 20px; display: flex; gap: 9px; justify-content: flex-end; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; }
.form-grid .wide { grid-column: 1 / -1; }
.form-grid label { display: block; font-size: 11.5px; font-weight: 600; margin-bottom: 5px; }
.form-grid input, .form-grid select, .form-grid textarea { width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--white); }
.form-grid .hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* A grid rather than a wrapping flex row: these labels are long enough to
   wrap, and a wrapped label in a flex row drifts away from its checkbox. */
.checks { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px 14px; }
.checks label { display: grid; grid-template-columns: auto 1fr; align-items: start; gap: 8px; font-weight: 400; font-size: 13.5px; line-height: 1.35; margin: 0; }
.checks input { margin-top: 2px; }
@media (max-width: 560px) { .form-grid { grid-template-columns: 1fr; } }

/* ==================================================== exceptions ==== */
.exwrap { display: grid; grid-template-columns: 254px 1fr; gap: 16px; align-items: start; }
.codes { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; box-shadow: var(--shadow); }
.codes button { display: flex; width: 100%; justify-content: space-between; align-items: center; gap: 8px; text-align: left; background: transparent; border: 0; border-bottom: 1px solid var(--line-2); padding: 9px 13px; font-size: 12.5px; }
.codes button:last-child { border-bottom: 0; }
.codes button:hover { background: var(--cloud); }
.codes button.on { background: var(--navy); color: #fff; }
.codes .n { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.codes button.on .n { color: rgba(255,255,255,.8); }
.resolve { display: flex; gap: 7px; margin-top: 6px; }
.resolve input { flex: 1; min-width: 120px; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 13px; }

/* ==================================================== narrow ======== */
/* A phone is not a small desktop. The rail becomes a bar with a menu behind
   it, and every register row becomes a card — the seven-column grid cannot
   simply squeeze, which is how the class pill ended up printed on top of the
   region code. */

.railtoggle { display: none; }

@media (max-width: 1000px) {
  #app { grid-template-columns: 1fr; }

  aside.rail {
    position: sticky; top: 0; z-index: 30; height: auto; overflow: visible;
    flex-direction: row; align-items: center; flex-wrap: wrap;
    gap: 10px; padding: 10px 14px;
  }
  .rail .brand { padding: 0; flex: 1; min-width: 0; }
  .rail .brand img { width: 28px; height: 28px; }

  /* The menu button, and the nav it opens. Closed by default so the page
     starts at the content rather than at a wall of navigation. */
  .railtoggle {
    display: block; background: rgba(255,255,255,.14); border: 0; color: #fff;
    padding: 8px 13px; border-radius: var(--r-sm);
    font-family: var(--display); font-weight: 700; font-size: 13px;
  }
  .rail nav {
    flex: 1 1 100%; flex-direction: column; gap: 1px;
    max-height: 70vh; overflow-y: auto;
    border-top: 1px solid rgba(255,255,255,.14); padding-top: 8px; margin-top: 2px;
  }
  .rail nav[hidden] { display: none; }
  .rail .navlabel { padding: 12px 12px 4px; }
  .rail nav button { font-size: 15px; padding: 11px 12px; }
  .rail .add { flex: 1 1 100%; margin: 0; }
  .rail .add[hidden] { display: none; }
  .rail .spacer { display: none; }
  .rail .foot { flex: 1 1 100%; padding: 8px 2px 0; border-top: 1px solid rgba(255,255,255,.14); }
  .rail .foot[hidden] { display: none; }

  /* A grid track of 1fr still stretches to its content's min-content width,
     which is how one long exception message dragged the whole page 260px
     wider than the screen. minmax(0,1fr) is what actually holds the line. */
  #app { grid-template-columns: minmax(0, 1fr); }
  main, aside.rail, .card, .rows, .page-head, .tile, .hero > * { min-width: 0; }
  main { padding: 18px 16px 48px; max-width: 100vw; overflow-x: clip; }
  .page-head h1, .page-head p, .who .name, .exrow .msg { overflow-wrap: anywhere; }
  .bars-wrap { overflow-x: auto; }
  /* A table is the one thing allowed to be wider than the screen — but it
     scrolls inside its own box, never by dragging the whole page sideways. */
  main table { display: block; overflow-x: auto; max-width: 100%; }
  .exwrap { grid-template-columns: minmax(0, 1fr); }
  .codes { min-width: 0; }
  .codes button { min-width: 0; }
  .codes button > :first-child { min-width: 0; overflow-wrap: anywhere; }
  .page-head h1 { font-size: 21px; }
  /* A tablet has room for two or three tiles abreast; one per row wastes
     the screen and buries the charts. */
  .hero { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
  .hero .headline { grid-column: 1 / -1; }
  .hero .headline .v { font-size: 32px; }

  /* Register rows as cards. Order is set explicitly rather than left to the
     grid: mark and name on the first line, the classification on the second,
     the payment history and what is owed on the third. */
  .rows { border-radius: var(--r); }
  .rows .head { display: none; }
  .row {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 7px 9px; padding: 14px 15px;
  }
  .row > :nth-child(1) { flex: none; }                    /* monogram      */
  .row > :nth-child(2) { flex: 1 1 60%; min-width: 0; }   /* name — line 1 */
  .row > :nth-child(3),                                   /* class         */
  .row > :nth-child(4),                                   /* region        */
  .row > :nth-child(5) { flex: none; font-size: 12.5px; color: var(--muted); }
  .row > :nth-child(6) { flex: 1 1 100%; margin-top: 2px; }  /* history     */
  .row > :nth-child(7) { flex: 1 1 100%; text-align: left; display: flex;
                         align-items: center; gap: 9px; }    /* amount      */
  .row .amount { text-align: left; }
  /* It never wraps — wrapping broke an eighteen-year timeline into two
     arbitrary rows and the reader lost which end was recent. The columns flex
     instead, so the same sparkline is 140px on a phone and 600px on a card.
     Slightly taller here because a finger, not a cursor, has to land on one
     of eighteen columns. */
  .wl { height: 26px; }

  .toolbar { gap: 7px; }
  .field { min-width: 100%; }
  .count { margin-left: 0; flex: 1 1 100%; }
  table.t { display: block; overflow-x: auto; }
}

@media (max-width: 560px) {
  .page-head .right { width: 100%; }
  .page-head .right .btn { flex: 1; }
  .hbar { grid-template-columns: 1fr auto; grid-template-areas: "lbl lbl" "bar val";
          gap: 3px 10px; font-size: 12.5px; }
  .hbar .lbl { grid-area: lbl; }
  .hbar .track { grid-area: bar; }
  .hbar .val { grid-area: val; }
  .hbars.wide .hbar { grid-template-columns: 1fr auto; }
  .hbars { gap: 13px; }
  .propbar .keys { gap: 12px 26px; }
  .declined { grid-template-columns: 1fr auto; gap: 4px 10px; }
  .declined .why { grid-column: 1 / -1; }
  .admission .aacts .btn { flex: 1; }
  .bars .col .xl { font-size: 9.5px; }
}

/* ================================================= rate book ======== */
/* A rate is three facts read together — what it costs, from when, and on whose
   authority — so the row keeps them on one line rather than in three columns
   of a table the reader has to scan across. */
.rates { display: grid; gap: 1px; background: var(--line-2); border: 1px solid var(--line);
         border-radius: var(--r-sm); overflow: hidden; }
.rate { display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,150px) auto;
        gap: 14px; align-items: center; padding: 13px 15px; background: var(--white); }
.rate .nm { font-weight: 600; font-size: 14px; }
.rate .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.rate .a .n { font-family: var(--mono); font-size: 16px; font-weight: 600;
              font-variant-numeric: tabular-nums; }
.rate .s { font-family: var(--mono); font-size: 11.5px; color: var(--muted); text-align: right; }
/* Agreed but not yet in force: real, and not yet true. The left rule says
   "scheduled" without spending a colour that means something else here. */
.rate.pending { background: var(--gold-tint); box-shadow: inset 3px 0 0 var(--mark-warn); }

tr.ahead td { color: var(--muted); font-style: italic; }
.warnline { color: #8A5200; font-size: 12.5px; }

/* The live consequence under the rate form. The strong line is the sentence
   the whole page exists to say — which financial year this first bites on —
   so it is the one thing set in ink rather than grey. */
.pvhead { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; margin-bottom: 8px; }
.pvhead b { font-family: var(--mono); font-size: 15px; }
.pvhead span { font-size: 12.5px; color: var(--muted); }
.pvline { font-size: 13px; color: var(--muted); margin-top: 5px; }
.pvline.strong { color: var(--ink); font-weight: 600; }
.pvline.warn { color: #8A5200; }

.btn.tiny { padding: 5px 10px; font-size: 12px; }

@media (max-width: 760px) {
  .rate { grid-template-columns: minmax(0,1fr) auto; gap: 6px 12px; }
  .rate .s { grid-column: 1 / -1; text-align: left; }
  .rate .btn.tiny { grid-column: 1 / -1; justify-self: start; }
}

/* ================================================== member lists ==== */
/* The review row. One association, everything needed to decide, and the
   decision itself — so the Secretary never has to open a second screen to
   accept a list that is obviously fine. */
.rev { display: grid; grid-template-columns: minmax(0,1fr) auto auto; gap: 12px 18px;
       align-items: center; padding: 15px 0; border-bottom: 1px solid var(--line-2); }
.rev:last-child { border-bottom: 0; }
.rev .nm { font-weight: 600; font-size: 14.5px; }
.rev .sub { font-size: 12px; color: var(--muted); margin-top: 3px; font-family: var(--mono); }
.rev .f { display: flex; gap: 20px; }
.rev .ff b { display: block; font-family: var(--mono); font-size: 17px; font-variant-numeric: tabular-nums; }
.rev .ff span { display: block; font-size: 10.5px; text-transform: uppercase;
                letter-spacing: .07em; color: var(--muted); margin-top: 2px; }
.rev .ff.up b { color: var(--mark-good); }
.rev .ff.down b { color: var(--mark-bad); }
.rev .ff.warn b { color: #8A5200; }
.rev .a { display: flex; gap: 8px; }
.rev .note2 { grid-column: 1 / -1; font-size: 12.5px; color: var(--muted); }

/* The gap between a list and a declaration, signed — under-declaring and
   over-declaring are different conversations with an association. */
.gap { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.gap.up { color: var(--mark-good); }
.gap.down { color: var(--mark-bad); }
.nilcell { color: var(--steel); }
td.num.owing { color: #A3301F; font-weight: 700; }

.rstat { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
         font-size: 13px; color: var(--muted); margin: 14px 0 4px; }
.rowacts { display: flex; gap: 9px; margin-top: 16px; flex-wrap: wrap; }
.hint2 { font-size: 12.5px; color: var(--muted); margin-top: 10px; }

/* ================================================== the lookup ===== */
/* Read at a registration desk, at arm\'s length, with somebody waiting. So the
   verdict is the first thing and it is a word, not a colour: a red card and a
   green card look the same to eight percent of men. */
.lk { display: grid; grid-template-columns: 132px minmax(0,1fr) minmax(0,1.1fr);
      gap: 18px; align-items: start; background: var(--white); border: 1px solid var(--line);
      border-radius: var(--r); padding: 18px; margin-top: 12px; box-shadow: var(--shadow); }
.lk .v b { display: block; font-family: var(--display); font-weight: 700; font-size: 12px;
           letter-spacing: .06em; text-align: center; padding: 9px 8px; border-radius: var(--r-sm); }
.lk.yes { border-left: 4px solid var(--mark-good); }
.lk.no  { border-left: 4px solid var(--mark-bad); }
.lk.yes .v b { background: var(--teal-tint); color: #0B6B52; }
.lk.no .v b  { background: var(--coral-tint); color: #A3301F; }
.lk .nm { font-weight: 700; font-size: 17px; letter-spacing: -.01em; }
.lk .w .sub { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.lk .w .em { font-family: var(--mono); font-size: 12px; margin-top: 5px; }
.lk .w .em.none { color: #8A5200; font-family: var(--body); }
.lk .y .r { font-size: 13.5px; }
.lk .chips { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 10px; }
.chip { font-size: 11px; font-weight: 600; padding: 4px 9px; border-radius: 20px; }
.chip.ok  { background: var(--teal-tint); color: #0B6B52; }
.chip.bad { background: var(--coral-tint); color: #A3301F; }

@media (max-width: 760px) {
  .rev { grid-template-columns: 1fr; }
  .rev .a { flex-wrap: wrap; }
  .rev .a .btn { flex: 1 1 auto; }
  .lk { grid-template-columns: 1fr; gap: 12px; }
}

/* Five equal tiles, and minmax(0,1fr) rather than 1fr because 1fr stretches to
   min-content and pushes the row sideways on a phone. */
.tiles.five { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: 12px; }
@media (max-width: 900px) { .tiles.five { grid-template-columns: repeat(2, minmax(0,1fr)); } }
/* Two up, not one. A number and a two-word label fit side by side at 390px,
   and stacking five of them turned the top of the page into a staircase. */
@media (max-width: 340px) { .tiles.five { grid-template-columns: minmax(0,1fr); } }

/* ============================================ association members === */
/* Its own grid rather than the register's: these rows carry a name and an
   email, not a monogram and a payment history, and reusing the member grid
   would leave two empty columns on every one of two thousand rows. */
.rows .head.phead, .row.prow {
  grid-template-columns: minmax(0,1.5fr) minmax(0,1.6fr) minmax(0,1.2fr) 78px minmax(0,1fr) 110px;
}
.row.prow { padding: 10px 18px; }
.prow .pn { font-weight: 600; }
.prow .pe { font-family: var(--mono); font-size: 12.5px; word-break: break-all; }
/* Not red. A missing email is a gap to fill, not an error somebody made. */
.prow .pe.none { color: #8A5200; font-family: var(--body); font-size: 12.5px; }
/* The acronym is the identifier; the full name is the courtesy. Left to wrap,
   "Aeronautical Information Management Association of Nigeria" took three
   lines and tripled the height of every row in a list of two thousand. */
.prow .legacy { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.selholder { display: contents; }
.morewrap { display: flex; justify-content: center; margin-top: 16px; }

@media (max-width: 860px) {
  .rows .head.phead { display: none; }
  .row.prow { display: flex; flex-wrap: wrap; gap: 4px 10px; padding: 13px 15px; }
  .row.prow > :nth-child(1) { flex: 1 1 100%; }
  .row.prow > :nth-child(2) { flex: 1 1 100%; }
  .row.prow > :nth-child(3) { flex: 1 1 auto; }
  .row.prow > :nth-child(4),
  .row.prow > :nth-child(5) { flex: none; font-size: 12.5px; color: var(--muted); }
  .row.prow > :nth-child(6) { flex: 1 1 100%; }
  /* The acronym alone on a phone. The full legal name is 58 characters and
     there is no width for it — inline it ran straight off the card edge. */
  .row.prow > :nth-child(3) { flex: 1 1 100%; min-width: 0; }
  .row.prow > :nth-child(3) .legacy { display: none; }
}
.listfilter { margin-top: 14px; display: flex; align-items: center; gap: 10px; }
.listfilter input { flex: 1 1 auto; min-width: 0; }

/* ==================================================== flags ========= */
/* The flag is an anchor, not an illustration: one size, aligned to the text
   baseline beside it, never scaled up into decoration. */
.flag { font-size: 15px; line-height: 1; display: inline-block; vertical-align: -1px; }
/* Windows ships no flag emoji, so the two-letter code takes the same slot —
   still an anchor, still scannable, and never a row of empty boxes. */
.flag.code { font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: .02em;
  background: var(--cloud); border: 1px solid var(--line); color: var(--muted);
  border-radius: 3px; padding: 2px 4px; vertical-align: 1px; }
/* A country the register spells wrongly. Deliberately not a flag. */
.flag.unknown { font-family: var(--mono); font-size: 10px; font-weight: 700;
  background: var(--gold-tint); border: 1px solid #E4CE8E; color: #8A5200;
  border-radius: 3px; padding: 1px 5px; vertical-align: 1px; cursor: help; }
.ctry { display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
.ctry .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* =============================================== representation ===== */
/* Two people-figures, side by side, never summed: one the associations
   assert, one somebody has signed for. */
.repcount { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px,100%),1fr));
  gap: 12px; margin: 12px 0 4px; }
.rc { background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 18px 20px; box-shadow: var(--shadow); }
.rc .v { font-family: var(--display); font-size: 34px; font-weight: 700; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; line-height: 1.05; }
.rc .k { font-size: 11px; text-transform: uppercase; letter-spacing: .09em; color: var(--muted); margin-top: 6px; }
.rc .cap { font-size: 12.5px; color: var(--muted); margin-top: 6px; }
.rc.live { border-left: 3px solid var(--mark-good); }
.rc.empty .v { color: var(--steel); }

.regions { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px,100%),1fr));
  gap: 14px; margin-top: 18px; }
.regcard { background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 18px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 14px; }
.regcard.orphan { border-style: dashed; box-shadow: none; background: var(--cloud); }
.rh { display: flex; gap: 12px; align-items: center; }
.rcode { flex: none; min-width: 52px; height: 40px; padding: 0 9px; border-radius: 9px;
  background: var(--navy); color: #fff; display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; font-weight: 600; }
.regcard.orphan .rcode { background: var(--steel); }
.rn { font-weight: 600; font-size: 14.5px; line-height: 1.25; }
.rsub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.rnum { display: flex; gap: 18px; flex-wrap: wrap; }
.rnum b { display: block; font-family: var(--mono); font-size: 17px; font-variant-numeric: tabular-nums; }
.rnum span { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
/* The picture: twelve flags say "we are in twelve countries" faster than the
   number twelve does. Wraps freely; never scrolls. */
.flagwrap { display: flex; flex-wrap: wrap; gap: 5px; margin-top: auto; }
.btn.small.block { width: 100%; justify-content: center; }

/* A flag you can ask a question of. The button is invisible — the flag is the
   control — but it carries the hit target, the focus ring and the title. */
.flagbtn { background: none; border: 0; padding: 2px; margin: -2px; cursor: pointer;
  border-radius: 4px; line-height: 1; }
.flagbtn:hover { background: var(--cloud); }
.flagbtn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* Declared against registered, per region. The live one is marked; a zero is
   greyed rather than hidden, because "none yet" is the finding. */
.rnum.people { padding-top: 12px; border-top: 1px solid var(--line-2); }
.rnum.people .live b { color: var(--mark-good); }
.rnum.people .zero b { color: var(--steel); }

/* A filter that arrived from another page, and the way back out of it. */
.filterchip { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--navy);
  background: var(--navy-tint); color: var(--navy); border-radius: 20px;
  padding: 6px 10px 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.filterchip b { font-size: 14px; line-height: 1; opacity: .65; }
.filterchip:hover b { opacity: 1; }
/* On the overview the flags are the picture, not a footnote to a card, so
   they get room to be read as one field of colour. */
.flagwrap.big { gap: 7px; margin-top: 16px; }
.flagwrap.big .flag { font-size: 20px; }
.flagwrap.big .flag.code { font-size: 10.5px; padding: 3px 5px; }
/* The country picker, with its flag beside it — so the person choosing sees
   the consequence at the moment they choose, not on a report next week. */
.cfield { display: flex; align-items: center; gap: 9px; }
.cfield select { flex: 1 1 auto; min-width: 0; }
.cfield .cflag { flex: none; width: 24px; text-align: center; }

/* The overview's lead block. Membership comes first now, so it carries the
   weight the money hero used to: bigger figures, more room, no top margin.
   The money block below stays prominent but stops competing for the eye. */
.card.lead { margin-top: 0; }
.card.lead .rnum { gap: 26px; }
.card.lead .rnum b { font-size: 25px; letter-spacing: -.02em; }
.card.lead .rnum.people b { font-size: 30px; }
.hero.money { margin-top: 16px; }
.hero.money .headline .v { font-size: 34px; }
@media (max-width: 760px) {
  .card.lead .rnum { gap: 16px 22px; }
  .card.lead .rnum b { font-size: 21px; }
  .card.lead .rnum.people b { font-size: 25px; }
}

/* The small globe at the top of the Membership card. Big enough to read as the
   federation rather than as an icon; the whole frame is a link to the Member
   globe. Beside the counts on a wide screen, above them on a phone. */
.ov-mem { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 28px; align-items: center; }
.ov-stats { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ov-stats .rnum.people { margin: 0; }
.ov-globe { display: flex; flex-direction: column; align-items: center; gap: 6px; text-decoration: none; color: var(--muted); border-radius: var(--r); }
.ov-globe-stage { width: 100%; aspect-ratio: 1; }
.ov-globe-stage canvas { display: block; width: 100%; height: 100%; transition: transform .25s ease; }
.ov-globe-cap { font: 600 12.5px var(--display); }
.ov-globe:hover .ov-globe-cap, .ov-globe:focus-visible .ov-globe-cap { color: var(--blue); }
.ov-globe:hover canvas { transform: scale(1.03); }
.ov-globe:focus-visible { outline: 2px solid var(--sky); outline-offset: 4px; }
@media (max-width: 760px) {
  .ov-mem { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .ov-globe { width: min(260px, 100%); margin: 0 auto; }
}
@media (prefers-reduced-motion: reduce) { .ov-globe:hover canvas { transform: none; } }

/* ===================================================== member globe === */
/* The stage is the one dark surface in the application, on purpose: a globe
   reads as a lit object against the night, and the region colours are bright
   brand values that would fail as marks on white. Everything around it stays
   in the ordinary light chrome. */
.gl-preview { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gl-preview .lbl { font-size: 12.5px; color: var(--muted); }
.gl-seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r); background: var(--white); padding: 3px; gap: 3px; }
.gl-seg button { border: 0; background: transparent; color: var(--muted); font: 600 12.5px var(--display); padding: 5px 10px; border-radius: var(--r-sm); cursor: pointer; }
.gl-seg button[aria-pressed="true"] { background: var(--blue); color: #fff; }
.gl-rdsel { font: 600 12.5px var(--display); padding: 6px 8px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--white); color: var(--navy); }

.gl-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.gl-stage { position: relative; background: #031631; border-radius: var(--r); overflow: hidden; height: clamp(440px, calc(100vh - 190px), 820px); min-width: 0; touch-action: none; }
.gl-stage canvas { display: block; width: 100%; height: 100%; cursor: grab; }
.gl-stage canvas:active { cursor: grabbing; }
.gl-crumbs { position: absolute; left: 14px; top: 12px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; color: #9DB2C9; font: 600 13px var(--display); max-width: calc(100% - 190px); }
.gl-crumbs button { font: inherit; color: #fff; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16); border-radius: var(--r-sm); padding: 3px 9px; cursor: pointer; }
.gl-crumbs .cur { color: #fff; }
.gl-crumbs .sep { color: #6F86A0; }
.gl-layers { position: absolute; right: 12px; top: 12px; display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.gl-layers button { display: inline-flex; align-items: center; gap: 7px; font: 600 12px var(--display); color: #fff; background: rgba(3,22,49,.8); border: 1px solid rgba(255,255,255,.18); border-radius: 999px; padding: 5px 11px 5px 9px; cursor: pointer; }
.gl-layers button[aria-pressed="false"] { opacity: .45; text-decoration: line-through; }
.gl-zoom { position: absolute; right: 12px; bottom: 12px; display: flex; flex-direction: column; gap: 6px; }
.gl-zoom button { width: 36px; height: 36px; border-radius: var(--r); border: 1px solid rgba(255,255,255,.16); background: rgba(3,22,49,.8); color: #fff; font: 600 18px var(--display); cursor: pointer; }
.gl-legend { position: absolute; left: 14px; bottom: 12px; color: #9DB2C9; font-size: 12.5px; max-width: calc(100% - 80px); }
.gl-tip { position: absolute; pointer-events: none; background: rgba(2,14,32,.94); color: #fff; border: 1px solid rgba(255,255,255,.15); padding: 5px 9px; border-radius: var(--r-sm); font-size: 13px; white-space: nowrap; transform: translate(12px, -50%); }
.gl-stage button:focus-visible, .gl-side button:focus-visible, .gl-search:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }

.gl-mk { display: inline-block; flex: none; width: 11px; height: 11px; --c: #fff; }
.gl-mk.a { border-radius: 50%; border: 2.5px solid var(--c); background: #fff; box-shadow: inset 0 0 0 1.5px #041A3B; }
.gl-mk.c { transform: rotate(45deg) scale(.85); border: 2.5px solid var(--c); background: #fff; box-shadow: inset 0 0 0 1.5px #041A3B; }
.gl-mk.i { border-radius: 50%; border: 1px dashed #fff; background: rgba(255,255,255,.25); width: 13px; height: 13px; }
.gl-mk.f { width: 14px; height: 10px; border: 1.5px dashed rgba(255,255,255,.85); border-radius: 2px; }
/* The FIR caveat sits on the stage, under the hint, whenever the lines show. */
.gl-firnote { margin-top: 4px; font-size: 11.5px; color: #C9D6E3; }
.gl-firnote a { color: #fff; }

.gl-side { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); padding: 16px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.gl-k { font: 600 11px var(--display); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.gl-title { font-size: 22px; color: var(--navy); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 2px; text-wrap: balance; }
.gl-name { margin: 4px 0 0; font-weight: 600; color: var(--ink); text-wrap: pretty; }
.gl-legal { margin: 2px 0 0; font-style: italic; color: var(--muted); font-size: 13.5px; }
.gl-muted { margin: 0; color: var(--muted); font-size: 13px; }
.gl-facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; }
.gl-facts dt { color: var(--muted); font-size: 13px; }
.gl-facts dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 0; overflow-wrap: anywhere; }
.gl-facts dd.na { color: var(--muted); font-weight: 400; }
.gl-facts dd a { color: var(--blue); }
.gl-sw { display: inline-block; width: 11px; height: 11px; border-radius: 3px; flex: none; }
.gl-title .gl-sw { width: 16px; height: 16px; }
.gl-rpill { display: inline-flex; align-items: center; gap: 6px; font: 600 12px var(--display); padding: 2px 9px; border-radius: 999px; background: var(--cloud); }
.gl-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.gl-chips button { font: 600 12.5px var(--display); border: 1px solid var(--line); background: var(--cloud); color: var(--navy); border-radius: var(--r-sm); padding: 4px 9px; cursor: pointer; }
.gl-chips button.corp { border-style: dashed; }
.gl-chips button:hover { border-color: var(--blue); }
.gl-officer { border: 1px solid var(--line); background: var(--page); border-radius: var(--r); padding: 12px; display: grid; gap: 9px; }
.gl-officer .btn { justify-self: start; }
.gl-check { margin: 0; font-size: 13px; border-left: 3px solid var(--gold); padding-left: 8px; }
.gl-lock { margin: 0; font-size: 13px; color: var(--muted); }
.gl-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.gl-stats div { background: var(--cloud); border-radius: var(--r-sm); padding: 8px 10px; }
.gl-stats b { display: block; font: 600 22px var(--display); color: var(--navy); font-variant-numeric: tabular-nums; }
.gl-stats span { font-size: 12px; color: var(--muted); }
.gl-regions, .gl-results { display: flex; flex-direction: column; }
.gl-row { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 7px 8px; border: 0; border-radius: var(--r-sm); background: transparent; text-align: left; cursor: pointer; width: 100%; }
.gl-row:hover { background: var(--cloud); }
.gl-row.static { cursor: default; } .gl-row.static:hover { background: transparent; }
.gl-row .nm { min-width: 0; display: flex; flex-direction: column; }
.gl-row .nm b { font: 600 13px var(--display); color: var(--navy); }
.gl-row .nm em { font: 600 10.5px var(--display); font-style: normal; letter-spacing: .05em; text-transform: uppercase; color: var(--blue); }
.gl-row .nm small { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gl-row .n { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; max-width: 9em; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gl-search { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--page); }
.gl-foot { font-size: 12.5px; color: var(--muted); max-width: 110ch; margin: 12px 0 0; }

@media (max-width: 1100px) {
  .gl-wrap { grid-template-columns: minmax(0, 1fr); }
  .gl-stage { height: min(calc(100vw - 32px), 560px); }
}
@media (max-width: 640px) {
  .gl-layers { top: 44px; left: 14px; right: auto; flex-direction: row; flex-wrap: wrap; align-items: center; }
  .gl-layers button { font-size: 11.5px; padding: 4px 9px 4px 7px; }
  .gl-crumbs { max-width: calc(100% - 28px); }
  .gl-preview { width: 100%; }
}
