/* Black Bird Group -- shared design system.
 *
 * Two sites, one master brand. Everything that must look identical across
 * blackbirdgroup.fi and business.blackbirdgroup.fi lives here: the palette,
 * the type scale, the entity switcher, the masthead and the footer. The
 * per-site personality lives in ngo.css and business.css.
 *
 * The theme is chosen by data-site on <html>, not by prefers-color-scheme.
 * The think tank is a light editorial surface and the company is a dark
 * cinematic one; those are brand decisions, not viewer preferences, and a
 * visitor flipping between the two should see the contrast deliberately.
 *
 * Colour rules come from 21_Brandi-ohjeet and are not negotiable:
 *   - forest green is the brand
 *   - brass is the accent on dark grounds, slate blue the accent on light
 *   - they are never mixed on the same ground
 *   - brass and sage fail contrast on white, so on light they are for
 *     rules, icons and fills, never for words
 *   - burgundy and slate are data colours: red is the adversary, blue is
 *     own or allied. They belong on the map, not on decoration.
 */

/* ---------------------------------------------------------------- tokens */

:root {
  /* Core palette -- exact values from the brand guide. */
  --forest: #2f3a2e;
  --brass: #b8a46f;
  --slate: #44546a;
  --burgundy: #63051b;
  --sage: #94a892;
  --cream: #e9ddc2;
  --stone: #6f7268;
  --ash: #e2e0da;

  /* Fluid type scale.
   *
   * Every clamp here reaches its maximum at roughly 1900px, not at 1440.
   * The earlier curve saturated by about 1500px, which meant a 1440x900
   * laptop was already being served the full desktop scale -- display type
   * at its largest and section padding at its deepest, on a screen barely
   * two thirds the height. Everything fitted on a large monitor and
   * nothing fitted on a laptop.
   *
   * The anchors are f(768) for tablet and f(1900) for a large desktop; a
   * 1280 or 1440 laptop now lands sensibly between them.
   */
  /* TWO scales, not one -- see the media queries below.
   *
   * The distinction matters more than the numbers. Text people READ has
   * to stay legible at any screen size: body copy is 16-17px on a phone,
   * a laptop and a 4K monitor alike, because reading distance barely
   * changes and legibility is absolute. Display type is compositional and
   * does scale. Vertical rhythm is what actually has to compress when a
   * screen is short.
   *
   * An earlier version multiplied all three by one factor. That shrank
   * body text and navigation to ~13px on a laptop and pulled the gutters
   * in, pushing content toward the screen edges -- solving a vertical
   * problem by damaging horizontal legibility.
   */
  --ui-type: 1;   /* display type only */
  --ui-space: 1;  /* vertical rhythm only */

  /* Read, not composed: width-based only, and never below 16px. */
  --step--1: clamp(0.8rem, 0.77rem + 0.1vw, 0.88rem);
  --step-0: clamp(1rem, 0.97rem + 0.12vw, 1.1rem);
  --step-1: clamp(1.12rem, 1.06rem + 0.22vw, 1.32rem);

  /* Composed: scales with width, and eases off on a short screen because
     a display heading is what eats the fold. */
  --step-2: calc(clamp(1.3rem, 1.08rem + 0.55vw, 1.72rem) * var(--ui-type));
  --step-3: calc(clamp(1.6rem, 1.05rem + 1.35vw, 2.6rem) * var(--ui-type));
  --step-4: calc(clamp(2.05rem, 1.25rem + 2.3vw, 4.05rem) * var(--ui-type));
  --step-5: calc(clamp(2.7rem, 1.4rem + 4.05vw, 6.75rem) * var(--ui-type));

  --measure: 68ch;
  /* TWO horizontal insets, because they answer different questions.
   *
   * --gutter is how far the CHROME sits from the window edge. The mark is
   * meant to sit near the corner, and that stays modest.
   *
   * --pad is how far the CONTENT column sits from the edge, and it has to
   * be bigger. The content column is capped at --wrap-max, so above about
   * 1366px the cap decides the inset and it grows with the screen -- 340px
   * at 1920. Below the cap the gutter decides it, and at 49px the text sat
   * hard against the edge. One value could not serve both: raising it far
   * enough for a laptop pushed the mark away from the corner on a desktop.
   */
  --gutter: clamp(1.25rem, 1rem + 2.6vw, 5rem);
  --pad: clamp(1.25rem, 0.5rem + 5vw, 9rem);
  --wrap-max: 1240px;
  /* The real lever for "it fits on a laptop". */
  --section: calc(clamp(2.5rem, 1.06rem + 3.5vw, 5.25rem) * var(--ui-space));
  --radius: 2px;

  /* Height of the utility row, reused as the mark's bottom padding so the
     logo sits centred in the masthead as a whole rather than centred in
     the lower row with the utility row stacked on top of it. */
  --util-h: 1.55rem;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- laptop scaling ---------------------------------------------------
 *
 * A laptop is wide but SHORT. Sizing everything off viewport width alone
 * meant a 1440x760 laptop got the same type and spacing as a 1440x1200
 * desktop, so section after section overflowed the fold: the hero's slide
 * dots fell below the screen, the funding chart and its table could not be
 * seen together, the team grid dropped to two cards a row.
 *
 * --ui-space compresses vertical rhythm hard, because that is what makes
 * a section overflow the fold. --ui-type eases display headings back only
 * slightly. Body text, navigation and gutters are deliberately absent from
 * both: shrinking those does not buy vertical room, it just makes the page
 * harder to read and pushes it toward the edges.
 *
 * Width is still the primary axis; this is a height-aware correction on
 * top of it, and it applies only to wide-and-short viewports -- phones and
 * tablets are unaffected.
 */
@media (min-width: 900px) and (max-height: 900px) {
  :root {
    --ui-type: 0.95;
    --ui-space: 0.84;
  }
}

@media (min-width: 900px) and (max-height: 820px) {
  :root {
    --ui-type: 0.9;
    --ui-space: 0.74;
  }
}

@media (min-width: 900px) and (max-height: 730px) {
  :root {
    --ui-type: 0.86;
    --ui-space: 0.66;
  }
}

/* Think tank: light, editorial, slate accent. */
html[data-site='ngo'] {
  --bg: #f7f7f4;
  --surface: #ffffff;
  --sunken: #f0f1ec;
  --ink: #12160f;
  --muted: #5c6357;
  --line: #dce0d4;
  --rule: var(--sage);
  --accent: var(--slate);
  --accent-ink: #ffffff;
  --shadow: 0 1px 2px rgba(18, 22, 15, 0.04), 0 8px 24px rgba(18, 22, 15, 0.05);
}

/* Company: dark, cinematic, brass accent. */
html[data-site='business'] {
  --bg: #0b0e0b;
  --surface: #12160f;
  --sunken: #090c09;
  --ink: #eceee7;
  --muted: #99a294;
  --line: rgba(236, 238, 231, 0.12);
  --rule: var(--brass);
  --accent: var(--brass);
  --accent-ink: #0b0e0b;
  --shadow: none;
}

/* ----------------------------------------------------------------- reset */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Raleway', 'Trebuchet MS', Arial, sans-serif;
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h3,
h4 {
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0;
}

p {
  margin: 0;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

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

/* ------------------------------------------------------------- utilities */

.wrap {
  width: min(100% - var(--pad) * 2, var(--wrap-max));
  margin-inline: auto;
}

.wrap--narrow {
  width: min(100% - var(--pad) * 2, 860px);
  margin-inline: auto;
}

.section {
  padding-block: var(--section);
}

.eyebrow {
  margin: 0;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

.lede {
  font-size: var(--step-1);
  color: var(--muted);
  max-width: var(--measure);
}

.prose p + p {
  margin-top: 1.1em;
}

.prose {
  max-width: var(--measure);
}

/* Ordinary bullet lists inside prose.
 *
 * The privacy notice is the first place on the site that needs one. Every
 * earlier list is a layout with its own rules -- the media rows, the team,
 * the footers -- so `.prose` had no styling for a plain <ul>, and the items
 * rendered flush left with no markers, reading as run-together paragraphs. */
.prose ul,
.prose ol {
  margin-top: 1.1em;
  padding-inline-start: 1.5em;
  list-style: disc;
}

.prose ol {
  list-style: decimal;
}

.prose li + li {
  margin-top: 0.5em;
}

.prose ul + p,
.prose ol + p,
.prose ul + h3,
.prose ol + h3 {
  margin-top: 1.1em;
}

/* Sub-headings inside a document section need to separate from the paragraph
   above them; nothing else on the site puts an h3 inside .prose. */
.prose h3 {
  margin-top: 1.8em;
  margin-bottom: 0.5em;
  font-size: 1.05rem;
}

.prose h3:first-child {
  margin-top: 0;
}

/* The deck's signature device: a short rule under every section heading. */
.sec-head {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}

.sec-head h2 {
  font-size: var(--step-3);
}

.sec-head::after {
  content: '';
  width: 5.5rem;
  height: 2px;
  background: var(--rule);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: var(--accent-ink);
}

.skip-link:focus {
  left: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease),
    border-color 0.25s var(--ease);
}

.btn:hover {
  background: transparent;
  color: var(--accent);
}

.btn--ghost {
  background: transparent;
  color: var(--accent);
}

/* Smaller and rounded: for a single secondary action that should read as a
   link to a document rather than as a primary call to action. */
.btn--pill {
  padding: 0.6rem 1.25rem;
  border-radius: 999px;
  background: transparent;
  color: var(--accent);
  font-size: 0.76rem;
  text-transform: none;
  letter-spacing: 0.04em;
}

.btn--pill:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn--ghost:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

/* Text link with a moving underline -- used for "view all" style links. */
.arrow-link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--accent);
}

.arrow-link span {
  transition: transform 0.25s var(--ease);
}

.arrow-link:hover span {
  transform: translateX(0.3rem);
}

/* -------------------------------------------------------------- masthead */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

/* On the business homepage the masthead floats over the video until the
   page scrolls, which is where the cinematic hero gets its full height. */
html[data-site='business'] .masthead[data-overlay='true'] {
  position: fixed;
  inset-inline: 0;
  background: transparent;
  border-bottom-color: transparent;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}

html[data-site='business'] .masthead[data-overlay='true'].is-stuck {
  background: rgba(11, 14, 11, 0.92);
  border-bottom-color: transparent;
  backdrop-filter: blur(10px);
}

/* No rules anywhere in the company masthead. The only framing on that site
   is the black border around the hero itself; a hairline under the header
   competes with it. */
html[data-site='business'] .masthead {
  border-bottom: 0;
}

/* --- upper row: context controls ---
   Which entity am I looking at, and which language am I reading. Both
   answer "where am I", not "where can I go", which is why they sit apart
   from the navigation rather than inside it.
   Both sit together in the top-left corner, with no rule beneath: the row
   reads as a quiet utility strip above the mark, not as a second navbar. */
/* Vertical rhythm of the masthead, in three deliberate parts:
 *
 * 1. Real space above the pair. It was 5px, which read as the row being
 *    jammed against the top of the window.
 * 2. The two rows pulled together. The nav is centred in a row whose
 *    height is set by the 48px mark, so the gap between the rows is
 *    structurally (rowHeight - navHeight)/2 and cannot be tightened by
 *    alignment alone. A negative margin on the lower row closes it
 *    directly; the padding added above is larger, so the net effect is
 *    that the pair sits lower rather than the mark moving up.
 * 3. The lower row is the important one, so it is the larger of the two.
 */
.utilbar {
  padding-top: 1.5rem;
}

.mainbar {
  margin-top: -0.6rem;
}

/* Right-aligned: these are secondary controls, and the top-left corner is
   where the eye lands first -- that belongs to the mark. */
/* Full width with gutter padding rather than a capped, centred column.
   Capped at 1400px the mark drifted far from the corner on a wide screen
   while sitting correctly on a laptop; padded by the gutter it keeps the
   same distance from the edge at every size, and that distance scales. */
.utilbar-in {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.35rem;
  padding-inline: var(--gutter);
}

/* Only the overlaid masthead needs to clear the hero's inset black frame.
   Applying this to every company page made the sticky header on the
   interior pages half again as tall as it needed to be. The mark's
   balancing offset grows to match, so it stays centred. */
html[data-site='business'] .masthead[data-overlay='true'] .utilbar {
  padding-top: clamp(1.25rem, 2.4vw, 2rem);
}

html[data-site='business'] .masthead[data-overlay='true'] .brand {
  margin-bottom: 3.2rem;
}

.langs {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  flex: none;
}

.lang {
  padding: 0.2rem 0.45rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-decoration: none;
  color: var(--muted);
  transition: color 0.2s var(--ease);
}

.lang[aria-current='true'] {
  color: var(--ink);
}

/* Finnish and Swedish are shown but inert in this demo. Dimmed and
   non-interactive rather than hidden, so the control can be seen. */
.lang[aria-disabled='true'] {
  opacity: 0.55;
  cursor: default;
}

.lang[aria-disabled='true']:hover {
  color: var(--muted);
}

/* --- lower row: mark and navigation --- */
.mainbar-in {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding-inline: var(--gutter);
  min-height: 3.6rem;
}

/* The mark alone carries the offset that balances it against the utility
   row above. Putting it on the whole row instead lifted the navigation
   with it, which is what left a band of dead space under the links: they
   were centred in a box that stopped short of the masthead's foot.
   align-items centres the margin box, so a bottom margin here raises the
   mark by half of it -- exactly the correction needed. */
.brand {
  margin-bottom: var(--util-h);
}



/* --- entity switcher ---
   Deliberately not styled like the navigation. The nav answers "where can I
   go in this site"; the switcher answers "which Black Bird Group am I
   looking at". Keeping them visually distinct is the whole point, and the
   ry/Oy separation the switcher expresses is a legal requirement, not a
   layout preference. */
/* Quiet by design. It used to be a filled segmented control, which made it
   the loudest thing on the page -- for a control most visitors never touch.
   It now matches the language switch beside it: small caps, muted, with the
   active side simply darker. The information is still unambiguous, it just
   no longer shouts. */
.switcher {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  flex: none;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.45rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  white-space: nowrap;
  transition: color 0.2s var(--ease);
}

.switch:hover {
  color: var(--ink);
}

.switch[aria-current='true'] {
  color: var(--ink);
}

html[data-site='business'] .switch[aria-current='true'] {
  color: var(--brass);
}

.switch--other .switch-mark {
  font-size: 0.85em;
  opacity: 0.7;
}

/* --- the mark ---
   The official lockup as supplied: insignia, name, tagline. It is never
   rebuilt, re-lettered or re-spaced here -- the only thing that changes
   between the light and dark sites is which of the two supplied colour
   versions is used. Sized by height so the artwork's own proportions
   are preserved. */
.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex: none;
}

/* Footer marks sit in normal flow and take no balancing offset. */
.brand--footer {
  margin-bottom: 0;
}

.brand img {
  width: auto;
  height: 3rem;
}

.brand--footer img {
  height: 2.4rem;
}

.masthead nav {
  margin-left: auto;
}

/* Direct children only. `.masthead nav ul` would also match .submenu, and
   at (0,1,2) it out-specifies `.submenu { display: none }` at (0,1,0) --
   which left every dropdown permanently open as a flex row. */
.masthead nav > ul {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2rem);
}

/* The primary row. Larger and darker than the utility row above it,
   because these are the site's actual destinations -- the switcher and the
   language control are context, not navigation. The vertical padding also
   gives each link a proper hit target rather than a line of text. */
.masthead nav a {
  font-size: calc(var(--step-0) * 1.14);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  color: var(--ink);
  padding-block: 0.45rem;
  transition: color 0.2s var(--ease);
}

.masthead nav a:hover,
.masthead nav a[aria-current='page'] {
  color: var(--accent);
}

html[data-site='business'] .masthead[data-overlay='true']:not(.is-stuck) nav a,
html[data-site='business'] .masthead[data-overlay='true']:not(.is-stuck) .switch {
  color: rgba(236, 238, 231, 0.82);
}

.nav-cta {
  padding: 0.65rem 1.25rem;
  font-size: var(--step--1);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--accent) !important;
  letter-spacing: 0.1em !important;
  text-transform: uppercase;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}

.nav-cta:hover {
  background: var(--accent);
  color: var(--accent-ink) !important;
}

/* --- dropdown (About us) --- */
.has-menu {
  position: relative;
}

/* Default cursor, not a pointer: this button does not take you anywhere,
   it only reveals the panel. A pointer promises navigation it cannot
   deliver. */
.has-menu > button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0;
  border: 0;
  background: none;
  font-size: calc(var(--step-0) * 1.14);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
  cursor: default;
}

.has-menu > button:hover,
.has-menu[data-open='true'] > button,
.has-menu[data-active='true'] > button {
  color: var(--accent);
}

.has-menu > button::after {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
}

/* Left-aligned to the parent item.
   `top: 100%` with no gap is deliberate. An earlier version offset the
   panel by 0.9rem, and crossing that dead space counted as leaving the
   menu, so the panel closed before the pointer could reach an item. The
   visual separation now comes from the panel's own padding, and site.js
   adds a short close delay on top. */
.submenu {
  position: absolute;
  top: 100%;
  left: -1rem;
  right: auto;
  min-width: 15rem;
  margin-top: 0;
  padding: 0.5rem 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: none;
}

.has-menu[data-open='true'] .submenu {
  display: block;
}

/* Left alignment is the intended look. This flips only when the panel
   would otherwise run off the right edge -- site.js measures it on open
   and sets the attribute. CSS alone cannot see the viewport offset of an
   absolutely positioned child. */
.submenu[data-align='right'] {
  left: auto;
  right: -1rem;
}

.submenu li a {
  display: block;
  padding: 0.6rem 1.25rem;
  font-weight: 400;
  letter-spacing: 0;
}

.submenu li a:hover {
  background: var(--sunken);
}

/* --- mobile nav ---
   The switcher stays visible at every width. A procurement officer opening
   this on a phone after an event has to be able to tell which entity they
   are looking at without opening a menu. */
.nav-toggle {
  display: none;
  margin-left: auto;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: none;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

@media (max-width: 1080px) {
  .nav-toggle {
    display: inline-block;
  }

  .masthead nav {
    display: none;
    position: absolute;
    inset-inline: 0;
    top: 100%;
    padding: 1.25rem var(--pad) 2rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
  }

  .masthead.is-open nav {
    display: block;
  }

  .masthead nav > ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0.25rem;
  }

  .masthead nav > ul > li > a,
  .has-menu > button {
    display: block;
    width: 100%;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--line);
    text-align: left;
  }

  .submenu {
    position: static;
    display: block;
    min-width: 0;
    padding: 0.25rem 0 0.75rem 1rem;
    border: 0;
    box-shadow: none;
    background: none;
  }

  .has-menu > button::after {
    display: none;
  }

  .nav-cta {
    display: inline-block;
    margin-top: 1rem;
    text-align: center;
  }

  .brand img {
    height: 2.3rem;
  }
}

/* Phone widths. The upper row carries the switcher and the language
   control; the lower row carries the lockup and the menu button. At 390px
   there is only about 350px per row. Everything below is measured against
   that, not guessed: build/shots.js fails on any horizontal overflow at
   390px. */
@media (max-width: 560px) {
  .mainbar-in {
    gap: 0.6rem;
  }

  .switch {
    padding: 0.4rem 0.55rem;
    font-size: 0.58rem;
    letter-spacing: 0.06em;
  }

  .lang {
    padding: 0.25rem 0.3rem;
    font-size: 0.62rem;
    letter-spacing: 0.08em;
  }

  /* The lockup is a fixed-ratio image, so it scales rather than reflows.
     Height is the only lever, and the tagline is still legible here. */
  .brand img {
    height: 1.95rem;
  }

  .nav-toggle {
    padding: 0.5rem 0.7rem;
    font-size: 0.62rem;
    letter-spacing: 0.1em;
  }
}

@media (max-width: 400px) {
  .brand img {
    height: 1.7rem;
  }
}

/* ---------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--sunken);
  padding-block: clamp(3rem, 6vw, 5rem) 2rem;
}

html[data-site='business'] .site-footer {
  background: var(--sunken);
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(min(100%, 15rem), 1.4fr) repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

/* auto-fit drops columns as space runs out, but it always keeps at least
   one -- so below about 456px the 15rem brand column plus one 9rem link
   column plus the gap no longer fit, and the footer pushes the whole page
   sideways. The min(100%, ...) guard cannot catch that case, because
   neither track individually exceeds the container. Collapse explicitly. */
@media (max-width: 560px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

.footer-brand .brand {
  margin-bottom: 1.1rem;
}

.footer-brand p {
  max-width: 34ch;
  font-size: 0.92rem;
  color: var(--muted);
}

.footer-col h2 {
  margin-bottom: 1rem;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.footer-col li + li {
  margin-top: 0.5rem;
}

.footer-col a {
  font-size: 0.94rem;
  text-decoration: none;
  color: var(--ink);
}

.footer-col a:hover {
  text-decoration: underline;
}

.footer-legal {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2rem;
  font-size: 0.82rem;
  color: var(--muted);
}

.footer-legal a {
  color: inherit;
}

/* The entity note. Grant-funded NGO activity and commercial activity have
   to be publicly distinguishable -- the ry's tax position depends on it --
   so both footers state plainly which legal person is speaking. */
.entity-note {
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--rule);
  background: var(--surface);
  font-size: 0.86rem;
  color: var(--muted);
  max-width: 62ch;
}

/* ------------------------------------------------------------ demo notes */

/* Amber, deliberately unmissable, and never the brand colours: everything
   it marks is placeholder or illustrative and must not be mistaken for
   approved copy. */
.demo-note {
  display: flex;
  gap: 0.7rem;
  padding: 0.75rem 1rem;
  border: 1px dashed #b8860b;
  border-radius: var(--radius);
  background: rgba(184, 134, 11, 0.07);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--muted);
}

.demo-note b {
  color: #b8860b;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  flex: none;
}

/* ------------------------------------------------- long-form documents */

/* Shared by the think tank's About pages and the company's Approach
   page. These lived in ngo.css, which the business site never loads --
   so every heading on Approach rendered with no spacing at all. */

.stack {
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 5vw, 4rem);
}

.doc-section h2 {
  font-size: var(--step-2);
  margin-bottom: 1.25rem;
}

.doc-section h3 {
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
  font-size: var(--step-1);
}

.table-scroll {
  overflow-x: auto;
}

.fact-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1.25rem;
  font-size: 0.95rem;
}

.fact-table th,
.fact-table td {
  padding: 0.75rem 1rem 0.75rem 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.fact-table th {
  width: 34%;
  font-weight: 600;
  color: var(--muted);
}

/* -------------------------------------------------------- back to top */

.to-top {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.05rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease),
    color 0.2s var(--ease);
}

.to-top.is-in {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.to-top:hover {
  color: var(--ink);
  border-color: var(--rule);
}

/* ------------------------------------------------------- reveal on scroll */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* No JavaScript: never leave the page invisible. */
.no-js .reveal {
  opacity: 1;
  transform: none;
}

/* An unresolved decision in a legal document, marked so it cannot ship
   unnoticed. Deliberately loud: this is not a design element, it is a note
   that something is missing, and it should look wrong on a finished page. */
.pending {
  border-inline-start: 3px solid var(--brass, #a8894a);
  padding: 0.6rem 0 0.6rem 0.9rem;
  background: color-mix(in srgb, var(--brass, #a8894a) 8%, transparent);
  font-style: italic;
}

span.pending,
li.pending {
  display: inline;
  border: 0;
  padding: 0;
  background: none;
}

li.pending {
  display: list-item;
}
