.rail {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--rail-w-collapsed);
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  /* 24px, 1.5x the previous 16px — pulls the Menu button down from the top
     and the search/contact pair up from the bottom, so both sit closer to
     the centred logo. Mobile sets its own padding, so this is desktop-only. */
  padding: var(--sp-6) 0;
  background: var(--paper);
  /* No hairline: the rail reads as a white surface lying on the tinted
     page ground, separated by tone and a soft cast shadow rather than a
     drawn line. Sampled off the reference — it darkens the ground by ~4.5%
     at the edge and fades out over ~8px. */
  box-shadow: 3px 0 12px -2px rgba(18, 24, 31, 0.09);
  /* Above the scrim (150) so Menu stays clickable, and above the drawer
     (200) so the panel slides out from BEHIND the rail rather than sweeping
     across it. At rest they simply abut, so this only shows during motion. */
  z-index: 210;
  overflow-y: auto;
}

.rail-trigger {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  min-width: 44px;
  min-height: 44px;
  padding: var(--sp-2);
  background: none;
  border: none;
  color: var(--bms-blue-700);
  cursor: pointer;
  list-style: none;
  text-decoration: none;
}
.rail-trigger::-webkit-details-marker { display: none; }
.rail-icon { width: 22px; height: 22px; flex-shrink: 0; }

/* Hamburger → X morph */
.rail-burger {
  position: relative;
  display: block;
  width: 24px;
  height: 14px;
  flex: none;
}
.rail-burger i {
  position: absolute;
  left: 0;
  display: block;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition:
    transform var(--t-burger) var(--ease-burger),
    opacity calc(var(--t-burger) / 2) linear;
}
.rail-burger i:nth-child(1) { top: 0; }
.rail-burger i:nth-child(2) { top: 50%; margin-top: -1px; }
.rail-burger i:nth-child(3) { bottom: 0; }
.rail-menu[open] .rail-burger i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.rail-menu[open] .rail-burger i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
.rail-menu[open] .rail-burger i:nth-child(2) { opacity: 0; }

/* Menu / Close label crossfade */
.rail-trigger-label {
  position: relative;
  display: block;
  min-width: 3.4em;
  text-align: center;
  font-size: var(--step--1);
  font-weight: 600;
}
.rail-trigger-label span {
  display: block;
  transition: opacity calc(var(--t-burger) / 1.5) ease;
}
.rail-trigger-label-close { position: absolute; inset: 0; opacity: 0; }
/* Two words, one under the other. The spans already stack; this only closes
   the leading that a label meant for one line leaves between them. */
.rail-trigger-label--stacked { line-height: 1.15; }
.rail-menu[open] .rail-trigger-label-open { opacity: 0; }
.rail-menu[open] .rail-trigger-label-close { opacity: 1; }

.rail-menu, .rail-search, .rail-quicklinks { position: static; }
.rail-logo {
  display: flex;
  margin-top: auto;
  margin-bottom: auto;
  /* --sp-1 rather than --sp-2 at the sides, so the 89px mark still fits the
     101px rail. */
  padding: var(--sp-2) var(--sp-1);
}
/* Larger than the rail's 5% growth alone would give. The mark is a mid-grey
   tower on white, so it needs the extra size to read clearly. The artwork is
   portrait inside a square canvas, so only ~53% of this width is ink. */
/* 83px -> 89px, Sean 2026-09-18. */
.rail-logo img { width: 89px; height: 89px; }

/* Search + contact only, 20% up on the shared 22px. Scoped to those two
   triggers on purpose — .rail-icon is also used by the nav chevrons, the
   Back arrow and the panel close buttons, which should not grow. */
@media (min-width: 1024px) and (hover: hover), (min-width: 1024px) and (pointer: fine), (min-width: 1024px) and (pointer: none), (min-width: 1401px) {
  .rail-end-group > .rail-trigger .rail-icon,
  .rail-end-group > .rail-search > .rail-trigger .rail-icon {
    width: 26.4px;
    height: 26.4px;
  }
}

/* Desktop: search + contact just sit in normal document flow with the
   rest of the rail — the wrapper only becomes a real layout box on mobile. */
.rail-end-group { display: contents; }

/* ── Scrim ─────────────────────────────────────────────────────── */
.rail-scrim {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: rgba(18, 24, 31, 0.5);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--t-scrim-out) var(--ease-scrim),
    visibility 0s linear var(--t-scrim-out);
}
.rail-scrim.is-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--t-scrim-in) var(--ease-scrim), visibility 0s;
}

/* ── Drawer ────────────────────────────────────────────────────── */
.rail-drawer {
  position: fixed;
  top: 0;
  left: var(--rail-w-collapsed);
  width: var(--drawer-w);
  height: 100dvh;
  background: var(--paper);
  /* Same treatment as the rail — a raised white surface, not a bordered box */
  box-shadow: 4px 0 18px -4px rgba(18, 24, 31, 0.12);
  z-index: 200;
  overflow: hidden;          /* views scroll individually, not the drawer */
  transform: translateX(-100%);
  visibility: hidden;
  transition:
    transform var(--t-close) var(--ease-drawer),
    visibility 0s linear var(--t-close);
}
/* Two selectors on purpose. The [open] pair covers the no-JS case, where
   the panel is still nested inside <details>. With JS the panel is lifted
   out to a sibling of the rail (so its slide isn't suppressed by <details>
   content-hiding, and so iOS can't clip it inside the scrolling top bar),
   and .is-open is what drives it. */
.rail-menu[open] > .rail-drawer,
.rail-search[open] > .rail-drawer,
.rail-quicklinks[open] > .rail-drawer,
.rail-drawer.is-open {
  transform: none;
  visibility: visible;
  transition: transform var(--t-open) var(--ease-drawer), visibility 0s;
}
.rail-drawer--search,
.rail-drawer--quick { display: flex; flex-direction: column; }

/* ── Views ─────────────────────────────────────────────────────── */
/* Root and sub-views are siblings, stacked in the same box. A sub-view is
   never a descendant of the root list — otherwise dimming or inerting the
   root would apply to the sub-view's own links as well. */
.rail-view {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  transform: translateX(100%);
  transition: transform var(--t-submenu) var(--ease-submenu);
}
.rail-view--root { transform: none; }
.rail-view--sub.is-active { transform: none; }

/* Root slides back and dims while a sub-view is forward. The dim is a
   pseudo-element, not opacity on the element, so it can never bleed onto
   anything else. */
.rail-drawer.has-sub .rail-view--root { transform: translateX(-22%); }
.rail-view--root::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-submenu) var(--ease-submenu);
}
.rail-drawer.has-sub .rail-view--root::after { opacity: 0.28; }

.rail-view-scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-12) var(--sp-6) var(--sp-8);
}

.rail-eyebrow {
  margin-bottom: var(--sp-6);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
}

/* ── Nav lists ─────────────────────────────────────────────────── */
.rail-nav-list,
.rail-nav-sublist {
  list-style: none;
  margin: 0;
  padding: 0;
}
.rail-nav-list > li { border-bottom: 1px solid var(--paper-alt); }
.rail-nav-list > li:first-child { border-top: 1px solid var(--paper-alt); }

.rail-nav-link, .rail-nav-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: 100%;
  min-height: 44px;
  padding: var(--sp-3) 0;
  background: none;
  border: none;
  color: var(--ink);
  font-weight: 600;
  font-size: var(--step-1);
  line-height: 1.25;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: color 0.3s ease, padding-left 0.38s var(--ease-item);
}
/* Hover effects in the menu only where there is a pointer that hovers. A
   touch screen fakes :hover on whatever was last tapped and leaves it there,
   and in this menu the tap that opens a section lands, a moment later, on
   the sub-menu row that has slid in under the finger — so on an iPad the
   first row of Key Information, the second of Learning and so on sat
   indented and blue as if they were the page being viewed (Sean,
   2026-09-22). The current page keeps its own marker below, which is not a
   hover state. */
@media (hover: hover) {
  .rail-nav-link:hover, .rail-nav-trigger:hover {
    color: var(--bms-blue-700);
    padding-left: var(--sp-2);
  }
}
.rail-chevron { width: 16px; height: 16px; opacity: 0.5; transition: opacity 0.3s ease, transform 0.3s ease; }
@media (hover: hover) {
  .rail-nav-trigger:hover .rail-chevron { opacity: 1; transform: translateX(4px); }
}
.rail-nav-link[aria-current="page"],
.rail-nav-trigger[aria-current="true"] {
  color: var(--bms-blue-700);
  box-shadow: inset 3px 0 0 var(--bms-blue-700);
  padding-left: var(--sp-3);
}

.rail-nav-sublist > li { border-bottom: 1px solid var(--paper-alt); }
.rail-nav-sublist > li:first-child { border-top: 1px solid var(--paper-alt); }
.rail-nav-sublist a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: var(--sp-3) 0;
  color: var(--ink);
  font-size: var(--step-0);
  text-decoration: none;
  transition: color 0.3s ease, padding-left 0.38s var(--ease-item);
}
@media (hover: hover) {
  .rail-nav-sublist a:hover { color: var(--bms-blue-700); padding-left: var(--sp-2); }
}
.rail-nav-sublist a[aria-current="page"] {
  color: var(--bms-blue-700);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--bms-blue-700);
  padding-left: var(--sp-3);
}

.rail-back {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 44px;
  margin-top: var(--sp-6);
  padding: var(--sp-2) 0;
  background: none;
  border: none;
  color: var(--ink-muted);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.3s ease, gap 0.3s ease;
}
@media (hover: hover) {
  .rail-back:hover { color: var(--bms-blue-700); gap: var(--sp-3); }
}
.rail-back .rail-icon { width: 16px; height: 16px; }

/* ── Staggered reveal ──────────────────────────────────────────── */
.rail-stagger {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--t-item-out) ease,
    transform var(--t-item-out) ease;
}
/* Same dual-selector pattern as the drawer itself: [open] covers the no-JS
   case where the panel is still nested in <details>, .is-open covers the
   JS case where it has been lifted out to a sibling of the rail. Without
   the second selector the root items stay at opacity 0 — invisible but
   still clickable, since opacity does not affect hit-testing. */
.rail-menu[open] .rail-stagger,
.rail-quicklinks[open] .rail-stagger,
.rail-drawer.is-open .rail-stagger {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--t-item-in) var(--ease-item),
    transform var(--t-item-in) var(--ease-item);
  transition-delay: calc(var(--stagger-offset) + (var(--i, 0) * var(--stagger)));
}

/* ── Search panel ──────────────────────────────────────────────── */
.rail-panel-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
}
.rail-panel-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: none;
  color: var(--ink);
  cursor: pointer;
}
.rail-search-form { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.rail-search-input {
  flex: 1 1 12rem;
  min-height: 44px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--ink-muted);
  border-radius: var(--radius);
  font-size: var(--step-0);
}

/* ── No-JS fallback ────────────────────────────────────────────── */
/* Without JS the sliding views can't be driven, so every sub-view renders
   stacked in normal flow instead — all links stay reachable. */
html:not(.js) .rail-drawer { overflow-y: auto; }
html:not(.js) .rail-view { position: static; transform: none; }
html:not(.js) .rail-view--root::after { display: none; }
html:not(.js) .rail-view-scroll { overflow: visible; padding-top: var(--sp-6); }
html:not(.js) .rail-view--root .rail-view-scroll { padding-bottom: 0; }
html:not(.js) .rail-nav-trigger,
html:not(.js) .rail-back { display: none; }
html:not(.js) .rail-stagger { opacity: 1; transform: none; }

/* ── Phone layout: rail becomes a top bar ──────────────────────── */
/* Below 1024px, and on a touch tablet either way up (assets/js/layout.js). */
/* Menu and Quick Links left, logo centred, search + contact grouped right.
   Drawer goes full width. */
@media (max-width: 1023px), (hover: none) and (pointer: coarse) and (max-width: 1400px) {
  .rail {
    inset: 0 0 auto 0;
    width: 100%;
    height: var(--topbar-h);
    flex-direction: row;
    align-items: center;
    /* The extra bar height goes into clearance around the logo and icons
       rather than into their size. Vertical padding stays at --sp-1: the
       55px logo plus --sp-2 either side would come to 71px and overflow the
       70px bar, which is what made the bar itself scrollable before. */
    padding: var(--sp-1) var(--sp-4);
    overflow: visible;
    /* Shadow cast downward here rather than sideways */
    box-shadow: 0 3px 12px -2px rgba(18, 24, 31, 0.09);
    /* z-index inherited from the base rule (210) — the drawer starts below
       the bar here, so they never overlap anyway. */
  }
  /* The two pairs of icons sit the same --sp-2 apart: burger and info on the
     left, search and contact on the right. */
  .rail { gap: var(--sp-2); }
  .rail-menu-trigger,
  .rail-quicklinks > .rail-trigger { justify-content: center; }
  /* Icons only up here, as on the right: no "Menu", no "Quick Links". */
  .rail-menu-trigger .rail-trigger-label,
  .rail-quicklinks .rail-trigger-label { display: none; }
  /* Centred on the bar itself rather than between the two groups, which are
     no longer the same width. */
  .rail-logo {
    position: absolute;
    left: 50%;
    translate: -50% 0;
  }
  /* No padding here: 52px image + 8px padding = 68px, which overflows the
     64px bar and was clipped by the drawer's top edge. */
  .rail-logo { margin: 0; padding: 0; flex: 0 0 auto; }
  /* +5% alongside the taller bar, keeping the proportion you signed off */
  .rail-logo img { width: 55px; height: 55px; }
  .rail-end-group {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-2);
    margin-left: auto;
  }
  /* The triggers are column flex boxes and default to flex-start, so the icon
     sat at the top of its 44px target — 21px of bar above it against 27 below.
     Centring it splits the new clearance evenly. */
  .rail-end-group .rail-trigger { justify-content: center; }
  /* The search and contact labels are a wide-screen affordance. In the top bar
     the icons sit side by side in a 70px strip and there is no room for words
     under them. */
  .rail-end-group .rail-trigger-label { display: none; }
  /* Starts below the top bar rather than covering it, so the Close button,
     logo, search and contact stay visible and usable while the menu is
     open — and nothing scrolls underneath a translucent bar. */
  .rail-drawer {
    top: var(--topbar-h);
    left: 0;
    width: 100%;
    height: calc(100dvh - var(--topbar-h));
    box-shadow: none; /* full-width here, so it has no edge to cast from */
  }
  .rail-view-scroll { padding-top: var(--sp-8); }
  /* No scrim. It is there to dim the page beside a drawer and catch the tap
     that closes it; a full-width drawer leaves no page beside it. Worse, it
     reaches full strength in about a fifth of a second while the drawer eases
     out from the edge over 0.62s, so on a wide tablet the whole screen went
     half black before the white panel swept across it, and the last dark
     sliver hung at the right-hand edge — the flicker Sean saw on an iPad
     held sideways (2026-09-22). */
  .rail-scrim { display: none; }
}

/* A tablet on its side: the drawer is revealed where it stands rather than
   slid in from off the screen. Moved in from the left, every strip of it had
   to be painted as it came into view, and an iPad Safari running the hero
   video underneath fell a frame behind: for that frame the strip was
   see-through, and the dark footage flashed in gaps in the moving panel —
   caught in Sean's screen recording, 2026-09-22, and only on the iPad held
   sideways, where the drawer is at its widest. Standing still, the whole
   panel is on the screen from the first frame and is painted once, and the
   clip-path wipe gives the same left-to-right arrival. Phones and upright
   tablets keep the slide; nothing showed through there. */
@media (hover: none) and (pointer: coarse) and (min-width: 1024px) and (max-width: 1400px) {
  .rail-drawer {
    transform: none;
    clip-path: inset(0 100% 0 0);
    transition:
      clip-path var(--t-close) var(--ease-drawer),
      visibility 0s linear var(--t-close);
  }
  .rail-menu[open] > .rail-drawer,
  .rail-search[open] > .rail-drawer,
  .rail-quicklinks[open] > .rail-drawer,
  .rail-drawer.is-open {
    clip-path: inset(0);
    transition: clip-path var(--t-open) var(--ease-drawer), visibility 0s;
  }
}
