/* ─────────────────────────────────────────────
   immi.tv — Shared Chrome Styles
   Nav + Ticker + Trust Bar + Mobile Menu
   Single source of truth. All pages link this.
───────────────────────────────────────────── */

/* ── Design tokens (chrome-relevant subset) ── */
:root {
  --warm-white: #fafaf5;
  --cream: #f5f0e8;
  --cream-dark: #ede5d4;
  --forest: #166534;
  --forest-mid: #15803d;
  --forest-light: #dcfce7;
  --forest-faint: #f0fdf4;
  --amber: #d97706;
  --brown: #1c1917;
  --stone: #57534e;
  --stone-light: #78716c;
  --border: #e7e2d9;
  --border-dark: #d4cfc6;
  --white: #ffffff;
  --ticker-bg: #1c1917;
  --ticker-text: #f5f0e8;
  --ticker-dot: #ef4444;
  --ticker-sep: #d97706;
  --nav-h: 60px;
  --ticker-h: 32px;
  --trust-bar-h: 40px;
  --offset: calc(
    var(--nav-h) + var(--ticker-h) + var(--trust-bar-h)
  ); /* 132px */
}

/* Keyboard focus styles */
*:focus-visible {
  outline: 2px solid #166534;
  outline-offset: 2px;
}

*:focus:not(:focus-visible) {
  outline: none;
}

/* ── TV logo animations ── */
@keyframes tv-flicker {
  0%,
  88%,
  100% {
    opacity: 0.8;
    fill: var(--forest);
  }
  90% {
    opacity: 0.25;
    fill: var(--amber);
  }
  92% {
    opacity: 0.9;
    fill: var(--forest);
  }
  95% {
    opacity: 0.15;
  }
  97% {
    opacity: 0.85;
    fill: var(--forest);
  }
}
@keyframes antenna-sway {
  0%,
  100% {
    transform: rotate(0deg);
    transform-origin: bottom center;
  }
  30% {
    transform: rotate(-4deg);
    transform-origin: bottom center;
  }
  70% {
    transform: rotate(3deg);
    transform-origin: bottom center;
  }
}
@keyframes tv-glow-pulse {
  0%,
  100% {
    filter: drop-shadow(0 0 0px rgba(22, 101, 52, 0));
  }
  50% {
    filter: drop-shadow(0 0 5px rgba(22, 101, 52, 0.5));
  }
}

.tv-logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  text-decoration: none;
  animation: tv-glow-pulse 4s ease-in-out infinite;
}
.tv-icon {
  width: 36px;
  height: 32px;
  flex-shrink: 0;
}
.tv-screen {
  fill: var(--forest);
  animation: tv-flicker 5s ease-in-out infinite;
}
.tv-antenna-l {
  animation: antenna-sway 6s ease-in-out infinite;
}
.tv-antenna-r {
  animation: antenna-sway 6s ease-in-out infinite reverse;
}
.logo-text {
  font-family: "Fraunces", serif;
  font-size: 22px;
  font-weight: 700;
  color: var(--brown);
  letter-spacing: -0.02em;
  line-height: 1;
}
.logo-text span {
  color: var(--forest);
}

/* ─────────────────────────────────────────────
   FIXED NAV
───────────────────────────────────────────── */
nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
  height: var(--nav-h);
  background: rgba(255, 255, 255, 0.97);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav-links {
  display: flex;
  gap: 24px;
  list-style: none;
}
.nav-links a {
  color: var(--stone);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  transition: color 0.15s;
}
.nav-links a:hover {
  color: var(--brown);
}
.nav-links a.nav-active {
  color: var(--forest);
  font-weight: 600;
}

/* ── Geo toggle ── */
.nav-geo {
  display: inline-flex;
  align-items: center;
  background: var(--warm-white);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 3px;
  gap: 2px;
}
.nav-geo-btn {
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 5px;
  cursor: pointer;
  border: none;
  background: transparent;
  color: var(--stone);
  font-family: inherit;
  transition: all 0.15s;
  white-space: nowrap;
}
.nav-geo-btn.active {
  background: var(--forest);
  color: var(--white);
}
.flag-svg {
  width: 22px;
  height: 15px;
  border-radius: 2px;
  border: 0.5px solid rgba(0, 0, 0, 0.15);
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}

.nav-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.nav-btn-ghost {
  color: var(--stone);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  padding: 8px 18px;
  border: 1px solid var(--border);
  border-radius: 6px;
  transition: all 0.15s;
}
.nav-btn-ghost:hover {
  border-color: var(--forest);
  color: var(--forest);
}
.nav-btn-primary {
  background: var(--forest);
  color: var(--white);
  padding: 9px 20px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s;
}
.nav-btn-primary:hover {
  background: var(--forest-mid);
}

/* ── Free Tools dropdown ── */
.nav-item-dd {
  position: relative;
  list-style: none;
}
.nav-dd {
  position: absolute;
  top: 100%;
  left: 0;
  padding-top: 6px;
  display: none;
  z-index: 300;
}
/* Right-aligned dropdown for items near the right edge of the nav */
.nav-dd-right {
  left: auto;
  right: 0;
}
.nav-item-dd:hover .nav-dd {
  display: block;
}
.nav-dd-inner {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(28, 25, 23, 0.12);
  min-width: 244px;
  padding: 8px;
  overflow: hidden;
}
.nav-dd-inner-wide {
  min-width: 480px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 8px;
  padding: 12px;
}
/* Two-column layout: each col is a grid child that stacks items vertically */
.nav-dd-col {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.nav-dd-section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--stone-light);
  padding: 2px 8px 8px;
}
/* Full-width separator and cross-country row span both columns */
.nav-dd-sep-full,
.nav-dd-row-full {
  grid-column: 1 / -1;
}
.nav-dd-sep-full {
  height: 1px;
  background: var(--border);
  margin: 8px 0 4px;
}
.nav-dd-row-full {
  display: flex;
  gap: 4px;
}
/* Legacy single-separator rule (kept for backward compat) */
.nav-dd-sep {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--border);
  margin: 6px 0;
}
.nav-dd-inner-wide .nav-dd-item {
  grid-column: auto;
}
.nav-dd-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 14px;
  text-decoration: none;
  border-radius: 6px;
  transition: background 0.15s;
}
.nav-dd-item:hover {
  background: var(--forest-faint);
}
.nav-dd-item:hover .nav-dd-item-name {
  color: var(--forest);
}
.nav-dd-item-icon {
  font-size: 16px;
  line-height: 1.3;
  flex-shrink: 0;
}
.nav-dd-item-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-dd-item-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--brown);
}
.nav-dd-item-sub {
  font-size: 11px;
  color: var(--stone-light);
  font-weight: 400;
  line-height: 1.4;
}
/* Small badge to distinguish calculators/tools from guide links in dropdowns */
.nav-dd-tool-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--forest-faint);
  color: var(--forest);
  border: 1px solid var(--forest-mid);
  border-radius: 3px;
  padding: 1px 5px;
  margin-left: 6px;
  vertical-align: middle;
  line-height: 1.6;
}

/* ─────────────────────────────────────────────
   LIVE TICKER
───────────────────────────────────────────── */
@keyframes ticker-scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
@keyframes live-blink {
  0%,
  49% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}
.live-ticker {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  z-index: 199;
  height: var(--ticker-h);
  background: var(--ticker-bg);
  display: flex;
  align-items: center;
  overflow: hidden;
  border-bottom: 2px solid var(--amber);
}
.ticker-label {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 18px;
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  background: var(--ticker-bg);
  z-index: 2;
  position: relative;
}
.ticker-live-dot {
  width: 8px;
  height: 8px;
  background: var(--ticker-dot);
  border-radius: 50%;
  animation: live-blink 1s step-start infinite;
  box-shadow: 0 0 6px rgba(239, 68, 68, 0.6);
}
.ticker-live-text {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--ticker-dot);
  text-transform: uppercase;
}
.ticker-track {
  display: flex;
  align-items: center;
  white-space: nowrap;
  animation: ticker-scroll 45s linear infinite;
}
.ticker-track:hover {
  animation-play-state: paused;
}
.ticker-item {
  display: inline-flex;
  align-items: center;
  padding: 0 24px;
}
.ticker-item-country {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--amber);
  margin-right: 8px;
}
.ticker-item-flag {
  font-size: 15px;
  line-height: 1;
  margin-right: 6px;
  flex-shrink: 0;
}
.ticker-item-date {
  font-size: 12px;
  color: var(--ticker-sep);
  margin-right: 6px;
  white-space: nowrap;
}
.ticker-breaking {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--stone-900, #1c1917);
  background: #ef4444;
  padding: 1px 5px;
  border-radius: 2px;
  margin-right: 6px;
  white-space: nowrap;
  flex-shrink: 0;
}
.ticker-item-link {
  font-size: 12px;
  color: var(--ticker-text);
  font-weight: 400;
  text-decoration: none;
}
.ticker-item-link:hover {
  color: var(--amber);
  text-decoration: underline;
}
.ticker-item-text {
  font-size: 12px;
  color: var(--ticker-text);
  font-weight: 400;
}
.ticker-sep {
  color: var(--ticker-sep);
  font-size: 14px;
  padding: 0 8px;
  opacity: 0.5;
}

/* ─────────────────────────────────────────────
   TRUST BAR
───────────────────────────────────────────── */
.trust-bar-sticky {
  position: fixed;
  top: calc(var(--nav-h) + var(--ticker-h));
  left: 0;
  right: 0;
  z-index: 198;
  height: var(--trust-bar-h);
  background: var(--forest);
  padding: 0 48px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
.trust-bar-sticky .trust-bar-inner {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  flex-wrap: nowrap;
}
.trust-bar-sticky .trust-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 11px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
}
.trust-bar-sticky .trust-item:first-child {
  padding-left: 0;
}
.trust-bar-sticky .trust-item:last-child {
  border-right: none;
  padding-right: 0;
}
.trust-bar-sticky .trust-item strong {
  color: var(--white);
}
/* ── TRUST BAR MARQUEE ────────────────────────────────────────────────
   Applied by chrome.js ONLY when the credentials overflow. If they fit, none of these
   classes are added and the bar is completely static. Same mechanism as `.ticker-track`:
   one transform on one element, so there is nothing to latch and nothing to collapse. */
@keyframes trust-marquee-scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
.trust-bar-sticky.trust-marquee {
  overflow: hidden;
}
.trust-bar-sticky.trust-marquee .trust-bar-inner {
  justify-content: flex-start;
  min-width: max-content;
  max-width: none;
  animation-name: trust-marquee-scroll;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  /* animation-duration is set inline by chrome.js, DERIVED from content width so the reading
     speed is constant whatever the credentials say (R-110: never a hardcoded duration). */
  will-change: transform;
}
/* ⛔ Reduced motion: this IS translation, which is the class of motion the setting exists to
   suppress — unlike the cross-fade it replaced. So the animation stops, and the bar becomes
   scrollable so every credential is still reachable. Nothing is hidden, nothing moves. */
@media (prefers-reduced-motion: reduce) {
  .trust-bar-sticky.trust-marquee .trust-bar-inner {
    animation: none;
    transform: none;
  }
  .trust-bar-sticky.trust-marquee {
    overflow-x: auto;
    scrollbar-width: none;
  }
  .trust-bar-sticky.trust-marquee::-webkit-scrollbar {
    display: none;
  }
}
.trust-bar-sticky.trust-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.trust-bar-sticky.trust-scroll::-webkit-scrollbar {
  display: none;
}
.trust-bar-sticky.trust-scroll .trust-bar-inner {
  justify-content: flex-start;
  min-width: max-content;
}
.trust-bar-sticky .trust-icon {
  font-size: 13px;
}

/* ─────────────────────────────────────────────
   MOBILE NAV — hamburger + drawer
───────────────────────────────────────────── */
.nav-hamburger {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
  color: var(--brown);
  font-size: 22px;
  line-height: 1;
}
.nav-mobile-menu {
  display: none;
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  background: rgba(255, 255, 255, 0.98);
  backdrop-filter: blur(12px);
  z-index: 300;
  padding: 16px 20px 24px;
  border-bottom: 2px solid var(--border);
  box-shadow: 0 8px 32px rgba(28, 25, 23, 0.12);
  overflow-y: auto;
  max-height: calc(100vh - var(--nav-h));
}
.nav-mobile-menu.open {
  display: block;
}
.nav-mobile-links {
  list-style: none;
  border-bottom: 1px solid var(--border);
  padding-bottom: 12px;
  margin-bottom: 12px;
}
.nav-mobile-links li a {
  display: block;
  padding: 12px 4px;
  font-size: 16px;
  font-weight: 500;
  color: var(--brown);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
}
.nav-mobile-links li:last-child a {
  border-bottom: none;
}
.nav-mobile-geo {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.nav-mobile-geo .nav-geo-btn {
  flex: 1;
  padding: 10px 8px;
  font-size: 13px;
  text-align: center;
}
.nav-mobile-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.nav-mobile-actions .nav-btn-ghost,
.nav-mobile-actions .nav-btn-primary {
  display: block;
  text-align: center;
  padding: 13px;
  font-size: 15px;
}

/* ─────────────────────────────────────────────
   FOOTER
───────────────────────────────────────────── */
footer {
  background: var(--forest);
  padding: 56px 48px 40px;
}
.footer-inner {
  max-width: 1100px;
  margin: 0 auto;
}
.footer-top {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1fr 1fr;
  gap: 32px;
  margin-bottom: 48px;
  padding-bottom: 48px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.footer-logo-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.footer-logo-text {
  font-family: "Fraunces", serif;
  font-size: 20px;
  font-weight: 700;
  color: white;
}
.footer-logo-text span {
  color: white;
}
.footer-brand p {
  font-size: 13px;
  color: white;
  line-height: 1.6;
  margin-bottom: 16px;
}
.footer-cred {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.footer-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 4px;
  color: white;
}
.footer-compliance {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.footer-compliance-line {
  font-size: 11px;
  color: white;
  line-height: 1.5;
}
.footer-compliance-line strong {
  color: white;
  font-weight: 600;
}
.footer-compliance-line a {
  color: white;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.4);
}
.footer-compliance-line a:hover {
  color: white;
}
.footer-rcic-badge {
  margin-top: 12px;
  display: inline-block;
  background: var(--white);
  border-radius: 6px;
  padding: 10px 16px;
}
.footer-rcic-badge img {
  display: block;
  height: 56px;
  width: auto;
}
.footer-col h5 {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: white;
  margin-bottom: 16px;
}
.footer-col ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.footer-col a {
  font-size: 13px;
  color: white;
  text-decoration: none;
  transition: color 0.1s;
}
.footer-col a:hover {
  color: rgba(255, 255, 255, 0.75);
}
.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.footer-copy {
  font-size: 12px;
  color: white;
}
.footer-bottom-links {
  display: flex;
  gap: 20px;
}
.footer-bottom-links a {
  font-size: 12px;
  color: white;
  text-decoration: none;
}

/* ─────────────────────────────────────────────
   EMBED MODE — hide all chrome
───────────────────────────────────────────── */
.embed-mode #site-chrome,
.embed-mode #site-footer,
.embed-mode nav,
.embed-mode .live-ticker,
.embed-mode .trust-bar-sticky,
.embed-mode .nav-mobile-menu {
  display: none !important;
}
.embed-mode body {
  padding-top: 0 !important;
}

/* ─────────────────────────────────────────────
   RESPONSIVE — MEDIUM DESKTOP (1024–1279px)
   Compact nav: tighten gaps, drop ghost button
───────────────────────────────────────────── */
@media (min-width: 1024px) and (max-width: 1279px) {
  nav {
    padding: 0 16px;
    overflow: visible;
  }
  .nav-links {
    gap: 12px;
  }
  .nav-links a {
    font-size: 13px;
  }
  .nav-btn-ghost {
    display: none;
  }
  .nav-geo-btn {
    padding: 4px 7px;
    font-size: 10px;
  }
  .nav-btn-primary {
    padding: 8px 14px;
    font-size: 13px;
  }
  /* Prevent wide dropdowns from overflowing viewport at compact-desktop width */
  .nav-dd-inner-wide {
    min-width: 260px;
    grid-template-columns: 1fr;
  }
  .nav-dd-inner-wide .nav-dd-sep-full,
  .nav-dd-inner-wide .nav-dd-row-full {
    grid-column: 1;
  }
}

/* ─────────────────────────────────────────────
   RESPONSIVE — TABLET (769–1023px)
   Hamburger replaces full nav
───────────────────────────────────────────── */
@media (min-width: 769px) and (max-width: 1023px) {
  nav {
    padding: 0 20px;
  }
  .nav-links,
  .nav-geo,
  .nav-actions {
    display: none;
  }
  .nav-hamburger {
    display: flex;
    align-items: center;
  }
  .footer-top {
    grid-template-columns: 1.3fr 1fr 1fr 1fr;
  }
}

/* ─────────────────────────────────────────────
   COOKIE CONSENT BANNER
───────────────────────────────────────────── */
@keyframes cookie-slide-up {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

#cookie-banner {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%) translateY(calc(100% + 24px));
  z-index: 9999;
  background: var(--warm-white);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  max-width: 680px;
  width: calc(100% - 32px);
  box-shadow:
    0 4px 24px rgba(28, 25, 23, 0.1),
    0 1px 4px rgba(28, 25, 23, 0.06);
  opacity: 0;
  transition:
    transform 0.4s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.4s ease;
}
#cookie-banner.cookie-banner-visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}

.cookie-banner-icon {
  flex-shrink: 0;
  font-size: 18px;
  line-height: 1;
}

.cookie-banner-text {
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 13px;
  color: var(--stone);
  line-height: 1.5;
  flex: 1;
  margin: 0;
}
.cookie-banner-text a {
  color: var(--forest);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: color 0.15s;
}
.cookie-banner-text a:hover {
  color: var(--forest-mid);
}

#cookie-accept {
  flex-shrink: 0;
  background: var(--forest);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 8px 20px;
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background 0.15s,
    box-shadow 0.15s;
  white-space: nowrap;
  line-height: 1;
}
#cookie-accept:hover {
  background: var(--forest-mid);
  box-shadow: 0 2px 8px rgba(22, 101, 52, 0.25);
}

/* ⛔ THE DECLINE BUTTON IS A REAL, LEGIBLE CHOICE — not a link, not grey-on-grey, not smaller.
   A banner whose refusal is visually demoted is the same dark pattern as a banner with no
   refusal at all, which is what this replaced. It shares the accept button's size, padding,
   font-size and weight; only the fill differs, because ONE of two options being the default
   emphasis is legitimate and hiding the other is not.
   ⚠ 13px, matching #cookie-accept — see R-053 on 16px, which applies to form INPUTS (iOS zooms
   on focus of an input under 16px); a <button> does not trigger that. */
#cookie-decline {
  flex-shrink: 0;
  background: transparent;
  color: var(--stone);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 20px;
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
  white-space: nowrap;
  line-height: 1;
}
#cookie-decline:hover {
  background: var(--warm-white);
  border-color: var(--stone);
}
/* Both buttons must show a visible keyboard focus ring (WCAG 2.4.7). The accept button
   inherited one from the UA default; an explicit rule keeps it once `background` is themed. */
#cookie-accept:focus-visible,
#cookie-decline:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: 2px;
}

@media (max-width: 600px) {
  #cookie-banner {
    bottom: 12px;
    flex-direction: row;
    flex-wrap: wrap;
    padding: 12px 16px;
    gap: 10px;
  }
  .cookie-banner-icon {
    display: none;
  }
  .cookie-banner-text {
    flex-basis: calc(100% - 40px);
    font-size: 12px;
  }
  /* ⚠ Two buttons must fit the ≤600px row without the text column collapsing. `margin-left:auto`
     is on the FIRST of the pair only — putting it on both pushes them apart and the second wraps
     alone on a 320px screen. */
  #cookie-accept {
    margin-left: auto;
    padding: 7px 16px;
    font-size: 12px;
  }
  #cookie-decline {
    padding: 7px 16px;
    font-size: 12px;
  }
}

/* ─────────────────────────────────────────────
   RESPONSIVE — MOBILE (≤768px)
───────────────────────────────────────────── */
@media (max-width: 768px) {
  nav {
    padding: 0 20px;
  }
  .nav-links,
  .nav-geo,
  .nav-actions {
    display: none;
  }
  .nav-hamburger {
    display: flex;
    align-items: center;
  }

  .trust-bar-sticky {
    padding: 0 16px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* ⛔ HIDE THE SCROLLBAR CHROME, KEEP THE SCROLL (owner review 2026-08-20).
       The five credential items are 949px wide in a 390px viewport, so this bar has always
       scrolled horizontally — on LIVE too (measured 2026-08-20: live 948/390, staged 949/390,
       identical). Nobody reports seeing a bar on a phone because iOS and Android draw OVERLAY
       scrollbars that fade; Chrome DevTools device emulation on a desktop OS draws a classic
       persistent one, which is what surfaced this (R-051: emulation is not the user's runtime).
       ⛔ Do NOT "fix" this by removing overflow-x — the items genuinely do not fit and would be
       clipped with no way to reach them. Only the bar chrome is hidden; swipe still works.
       ⚠ This is site-wide chrome, not occupation-page CSS: it changes every page on immi.tv. */
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* legacy Edge */
  }
  .trust-bar-sticky::-webkit-scrollbar {
    display: none; /* Chrome / Safari */
  }
  .trust-bar-sticky .trust-bar-inner {
    justify-content: flex-start;
    gap: 0;
    min-width: max-content;
  }
  .trust-bar-sticky .trust-item {
    padding: 0 12px;
    font-size: 11px;
  }

  footer {
    padding: 40px 20px 28px;
  }
  .footer-top {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .footer-bottom {
    flex-direction: column;
    gap: 12px;
    text-align: center;
  }
  .footer-bottom-links {
    flex-wrap: wrap;
    justify-content: center;
  }
}

/* ─────────────────────────────────────────────
   CALCULATOR MODAL (injected by chrome.js)
───────────────────────────────────────────── */
.calc-modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(28, 25, 23, 0.82);
  z-index: 500;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.calc-modal-overlay.open {
  display: flex;
}
.calc-modal {
  background: var(--white, #ffffff);
  border-radius: 16px;
  width: 100%;
  max-width: 1100px;
  height: 90vh;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  box-shadow: 0 24px 80px rgba(28, 25, 23, 0.35);
  transition: height 0.25s ease;
}
.calc-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 10;
  background: var(--brown, #78350f);
  color: var(--white, #ffffff);
  border: none;
  border-radius: 50%;
  width: 34px;
  height: 34px;
  cursor: pointer;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
  font-family: inherit;
}
.calc-modal-close:hover {
  background: var(--stone, #57534e);
}
.calc-modal-frame {
  width: 100%;
  flex: 1;
  border: none;
  display: block;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

@media (max-width: 640px) {
  .calc-modal-overlay {
    padding: 0;
    align-items: flex-end;
  }
  .calc-modal {
    width: 100%;
    height: 92vh;
    border-radius: 16px 16px 0 0;
    max-width: 100%;
    overflow: hidden;
  }
  .calc-modal-close {
    top: 10px;
    right: 10px;
    width: 38px;
    height: 38px;
    font-size: 18px;
  }
}

/* ── Mobile sticky CTA bar (site-wide) ── */
.mobile-cta {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  padding: 12px 20px;
  z-index: 500;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.12);
}
.mobile-cta a {
  display: block;
  background: #fff;
  color: var(--forest);
  text-align: center;
  padding: 12px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
}
/* ⛔ 580px AND SCROLL-REVEALED — matching `.mobile-cta`, which is what 617 pages
   already use against this class's 262. Owner 2026-08-27: "the mobile CTA appears
   on the hub pages sooner than the occupation pages".
   Measured: this appeared at 1140px IMMEDIATELY, while `.mobile-cta` appears at
   580px and only once the hero scrolls out of view. Two classes, two breakpoints
   and two reveal mechanisms — a 560px difference from one "shared" component.
   ⚠ A sticky bar at 1140px covers content on a small laptop, which is why the
   narrower breakpoint is the right one to converge on.
   ⚠ KNOWN GAP, NOT INTRODUCED HERE: between 580px and 1140px neither the sidebar
   (hidden below 1140) nor the sticky bar (shown below 580) is present. That dead
   zone already existed on all 617 occupation-style pages; converging makes it
   consistent rather than creating it. Worth a design decision separately. */
@media (max-width: 1000px) {
  .mobile-cta {
    display: block;
    transform: translateY(110%);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.25s ease, opacity 0.25s ease;
  }
  .mobile-cta.show {
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }
}

/* Occupation-page tiered variant: calc-primary row + Book/Call/WhatsApp secondary row.
   Set by chrome.js on /australia/occupations/* pages only. */
.mobile-cta-tiered {
  padding: 10px 14px 8px;
}
.mobile-cta-tiered .mobile-cta-primary {
  display: block;
  background: var(--forest-2, #08724a);
  color: #fff;
  text-align: center;
  padding: 11px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
}
.mobile-cta-tiered .mobile-cta-secondary {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.mobile-cta-tiered .mobile-cta-secondary a {
  flex: 1 1 0;
  display: block;
  background: transparent;
  border: 1.5px solid var(--forest-2, #08724a);
  color: var(--forest-2, #08724a);
  text-align: center;
  padding: 7px 4px;
  border-radius: 5px;
  font-weight: 600;
  font-size: 12.5px;
  text-decoration: none;
}
.mobile-cta-tiered .mobile-cta-secondary a:active {
  background: var(--mint, #e8f5ed);
}

/* ── v7 occupation corpus: the SAME tiered bar on a WHITE background ──────────
   ⛔ WHY THIS BLOCK EXISTS (CP-C11, 2026-08-20). Everything above assumes the
   bar is `--forest` dark green, so it paints the primary button WHITE and the
   secondary links WHITE-on-transparent. The v7 occupation page ships
   `.mobile-cta { background:#fff }` from its own inline <style>. Pointing
   chrome.js at that node without this block renders white-on-white — the CTA
   is present, clickable, passes every gate, and is INVISIBLE (R-125).
   Measured before writing this: bar bg rgb(255,255,255) vs the tiered rules'
   assumed rgb(22,101,52).
   Specificity: `.mobile-cta-tiered X` (0,3,0) beats
   `.mobile-cta-tiered X` (0,2,0), so these win without !important —
   ⛔ never !important here, the bar's show/hide is a transform animation
   (R-126a). Colours are the v7 page's own tokens, hard-coded as a fallback
   because chrome.css redefines `--forest` to a different green than the v7
   page does and must not be relied on across that boundary. */
.mobile-cta-tiered {
  padding: 10px 13px calc(8px + env(safe-area-inset-bottom));
}
.mobile-cta-tiered .mobile-cta-primary {
  background: var(--forest-2, #08724a);
  color: #fff;
  font-size: 15px;
  padding: 13px;
}
.mobile-cta-tiered .mobile-cta-secondary a {
  border: 1.5px solid var(--forest-2, #08724a);
  color: var(--forest-2, #08724a);
  background: transparent;
  min-height: 34px;
  line-height: 1.35;
}
.mobile-cta-tiered .mobile-cta-secondary a:active {
  background: var(--mint, #e8f5ed);
}
/* ⛔ THE SAME HEADING THE OCCUPATION PAGES USE (owner 2026-08-26). Measured on
   `.occ-disc summary`: flex, justify-content FLEX-START, gap 8px, an inline ⓘ svg before the text,
   and a `+`/`−` marker pushed right by `margin-left:auto`. This widget had
   justify-content:space-between with a `▼` chevron GLYPH in the markup, and the title read
   "Important disclaimer". Title, icon and marker are now identical; only the body wording differs
   by page, which is the agreed rule. */
.disclaimer-toggle {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.5rem;
  cursor: pointer;
  user-select: none;
}
.disclaimer-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone-light);
}
.disclaimer-chevron {
  font-size: 12px;
  color: var(--stone-light);
  transition: transform 0.2s;
}
/* 🗄 The rotate rules are retired — there is no chevron to rotate any more. */

.disclaimer-body {
  display: block;
  margin-top: 12px;
  font-size: 11px;
  color: var(--stone-light);
  line-height: 1.7;
}
.disclaimer-body strong {
  font-weight: 600;
  color: var(--stone);
}
.disclaimer-body a {
  color: var(--stone);
  text-decoration: underline;
}

/* 🗄 `.calc-disclaimer.legal` RULES REMOVED 2026-08-27 (step b5).
   They were a hand-written twin of the frozen template's `.occ-disc`, kept in step BY HAND
   — one guarantee, two mechanisms (R-116), and it had drifted twice in one week.
   The single definition now lives in the GENERATED assets/css/disclaimer.css, emitted from
   the frozen template by automation-scripts/build-disclaimer-css.py, which maps the two
   different markups (native <details>/<summary> vs div/.disclaimer-toggle) from one source.
   ⛔ Do not re-add disclaimer rules here. Regenerate instead. */

/* ── SPACING BELOW THE LEGAL DISCLAIMER — one value site-wide ─────────────────
   Owner 2026-08-27: the gap above and below the disclaimer must be the same on
   occupation pages and hubs. Above is 44px on both (the panel's own margin-top).
   Below was 90px on occupation pages and 0 on hubs.

   ⛔ The 90px comes from `main{padding:48px 0 90px}` in the FROZEN template's
   inline <style>, which sits BEFORE the <link> tags — so this rule overrides it
   without touching the frozen file and without a regeneration.
   ⚠ `:has(.occ-disc)` scopes it to pages carrying the occupation disclaimer, so
   it cannot reach hubs (which use .calc-disclaimer.legal and get their 40px from
   the panel's own margin-bottom) or any other family with a <main>.
   ⚠ CHANGE BOTH TOGETHER: the hub value lives in the GENERATED
   assets/css/disclaimer.css, emitted by automation-scripts/build-disclaimer-css.py. */
/* ⚠ ZERO, not 40. The 40px now comes from the panel's own margin-bottom in the
   GENERATED disclaimer.css, so it is one rule for every page instead of two
   mechanisms that drifted to 90px and 0px. Leaving 40 here would double it. */
main:has(.occ-disc) { padding-bottom: 0; }

/* ── ONE COLOUR SCHEME FOR THE STICKY BAR ────────────────────────────────────
   ⛔ These were INVERTED between the two classes, and nobody had configured
   them to differ. Measured 2026-08-28 at 390px:
     .mobile-cta        white bar · forest #08724a primary · forest text
     .mobile-cta  FOREST #166534 bar · WHITE primary · white text
   Two classes, two independent schemes — and two different greens, because one
   read `--forest` from chrome.css (#166534) and the other `--forest-2` from the
   occupation template (#08724a). The token collision this project namespaced
   around was showing up as a visible colour difference on the primary
   conversion control.
   ⇒ Converged on the occupation scheme, which is the reference and which 617
   pages already used against this class's 262.
   ⚠ The old `.mobile-cta-tiered` overrides below are now
   REDUNDANT — they restate what the base rules say. Left in place only because
   removing them is a separate, verifiable edit; they cannot cause drift while
   they agree, and a gate would catch it if they stopped. */


/* ── prefers-reduced-motion: the five remaining chrome animations (R-1, 2026-09-02) ────────────
   ⛔ WHY THIS EXISTS. `trust-marquee-scroll` has been guarded since it shipped; the other five
   never were. MEASURED on the live page 2026-09-02 by pixel-diffing two frames under
   `reduced_motion: reduce`: the logo glow still moved. So a reader who asked their operating
   system for less motion was still served a continuously scrolling news ticker, a blinking dot, a
   pulsing glow, a flickering screen and two swaying antennae.

   ⛔ REDUCE MEANS REDUCE MOVEMENT, NOT REMOVE THE BEHAVIOUR. Each rule pins its animation to that
   animation's OWN RESTING FRAME, read out of the @keyframes above rather than invented:
     tv-flicker      0%/88%/100% -> opacity .8, fill var(--forest)
     antenna-sway    0%/100%     -> rotate(0deg)
     tv-glow-pulse   0%/100%     -> drop-shadow(0 0 0 rgba(22,101,52,0))
     ticker-scroll   0%          -> translateX(0)
     live-blink      0%–49%      -> opacity 1
   ⚠ `live-blink` is the one that matters: it is a step-start toggle, and its other half is
   `opacity: 0`. Stopping it on the wrong frame would DELETE a live-state indicator rather than
   calm it — which is why the resting frame is read from the keyframes, not guessed.

   ⛔ NO `!important`, DELIBERATELY (R-126a). An important declaration beats an animation, and a
   SHORTHAND sets its siblings important too, so the element reports `animationPlayState: running`
   and moves zero pixels — verified-looking and wrong. This block sits at the END of the file and
   repeats the same selectors, so plain source order decides at equal specificity.

   ⚠ NOTHING IS HIDDEN. The ticker stops AND its container becomes scrollable, so every headline
   stays reachable — the same resolution `.trust-bar-sticky` uses above. Stopping a marquee without
   that would make the clipped items unreachable, trading a motion problem for a content one. */
@media (prefers-reduced-motion: reduce) {
  .tv-logo {
    animation: none;
    filter: drop-shadow(0 0 0 rgba(22, 101, 52, 0));
  }
  .tv-screen {
    animation: none;
    opacity: 0.8;
    fill: var(--forest);
  }
  .tv-antenna-l,
  .tv-antenna-r {
    animation: none;
    transform: rotate(0deg);
    transform-origin: bottom center;
  }
  .ticker-live-dot {
    animation: none;
    opacity: 1;
  }
  .ticker-track {
    animation: none;
    transform: translateX(0);
  }
  .live-ticker {
    overflow-x: auto;
  }
}

/* ── OCCUPATION PROCESSING-ORDER PANEL + LABOUR CARDS ─────────────────────────────────
   Moved here from an inline <style> injection 2026-10-01 (release #311). It CANNOT be an
   inline block: the generator's GATE 1 asserts the output's <style> count and content are
   byte-identical to the frozen template, so a page carrying an extra block aborts the build.
   A shared sheet is also fetched once rather than repeating ~21 KB on 581 pages.
   ⛔ Every selector is namespaced (.po-*, .sig-*, .la-*, .mini-grid.po-cards) so it cannot
   reach another page's chrome (R-125).
   ⛔ Editing this file changes its CONTENT HASH — a query string is not a Cloudflare cache key
   (R-004). Re-run automation-scripts/fingerprint-assets.py, update the template's href and
   data/frozen-template.json :: asset_refs (derived, never hand-typed). */
/* ⛔ Namespaced, and deliberately THIN. The page already owns `.mini-grid`, `.mini-card`,
   `.section-head`, `.kicker`, `.pb-*` and `.signal`; borrowing a stylesheet means inheriting a
   contract, so we reuse those and only add what does not exist (R-125). */
.sig-note{margin:0 0 14px;line-height:1.6}
.sig-foot{font-size:.78rem;color:#6b7684;margin:12px 0 0;line-height:1.55}
.sig-foot a{color:#2f6fb0}
.pb-prio{display:flex;gap:10px;flex-wrap:wrap;margin:2px 0 0}
.pb-prio div{border:1px solid #e2e8ee;border-radius:8px;padding:7px 12px;background:#fbfcfd;min-width:132px}
.pb-prio b{display:block;font-size:1.02rem;letter-spacing:-.01em}
.pb-prio small{color:#6b7684;font-size:.76rem}
.pb-prio .on{border-color:#2e7d5b;background:#eef7f2}
.pb-prio .on b{color:#22624a}
/* the page's carousel styling, reached by a PRESENTATION class instead of a fact attribute */
/* ⛔ 6px top padding, not 2px. `.mini-card:hover` lifts the card 3px; at 2px the track's own
   overflow clipped the card's TOP BORDER on hover — visible by hovering, never in the markup. */
/* ⛔ THE SAME PADDING CONTRACT AS `.po-cards` NEXT TO IT, AND ALL THREE NUMBERS ARE MEASURED.
   3px of side padding left a snapped card's neighbour 3px from the clip edge, so its right border
   sat on the rounding boundary and disappeared at fractional device-pixel ratios; 10px of bottom
   padding clipped the hover shadow (`0 10px 24px` under a 3px lift) exactly as 2px once clipped the
   top border. ⛔ `scroll-padding-inline` MUST EQUAL the side padding: the first card's snap position
   is `offset - scroll-padding`, so with padding 3 and scroll-padding 0 the track came to rest at
   scrollLeft 3 — and the page's own arrow script disables the left button at `scrollLeft <= 1`, so
   at the left extreme it stayed live and clicking it did nothing. Matching them rests the track at
   0 and the button disables on its own. */
.mini-grid.sig-track{display:flex;overflow-x:auto;gap:12px;scroll-snap-type:x mandatory;
  padding:6px 12px 20px;margin-inline:-12px;scroll-padding-inline:12px;
  scrollbar-width:none;-ms-overflow-style:none}
.mini-grid.sig-track::-webkit-scrollbar{display:none}
/* a series label, the same job `.pb-series-h` does in the points block */
.sig-series{font-size:.82rem;font-weight:700;letter-spacing:.01em;margin:16px 0 2px;
  color:var(--occ-forest,#0d5c3d)}
.sig-series:first-of-type{margin-top:6px}
/* ⛔ TWO per view, not three, and NO type override. MEASURED across the page: every `.mini-card`
   renders b 16px / small 11px, except inside the siblings carousel where the sheet shrinks it to
   12px / 9.5px. I had copied that compact rule, which made these the only odd tiles on the page.
   Standard type is kept and the card widened instead, so nothing is cramped. */
.mini-grid.sig-track>*{flex:0 0 calc((100% - 12px)/2);scroll-snap-align:start;
  display:flex;flex-direction:column}
/* ⛔ A SNAP POINT MUST EXIST AT THE END OF THE TRACK. Every card start-aligns, so the last card's
   snap position sits a card BEYOND max scroll and the end of the range is not a snap point at all.
   Under `scroll-snap-type: mandatory` a container must come to rest ON one: Chromium clamps to max
   and looks correct, WebKit/Safari falls back to the previous snap point and stops one card short —
   a card's width of blank at the right, which is what the owner saw and Chromium cannot show.
   ⛔ MEASURED, not reasoned: 17 of 24 snapping tracks had no end snap point, short by 148-370px
   against a 171px card; the page's own siblings carousel was 0px short at every width and is the
   known positive proving the check can pass. `end` on the last child puts a snap point exactly at
   max — which holds only while `scroll-padding-inline` equals the side padding, above. */
.mini-grid.sig-track>*:last-child,
.mini-grid.po-cards>*:last-child{scroll-snap-align:end}

/* ── processing order ─────────────────────────────────────────────────────────────────────────
   ⛔ MEASURED, NOT ASSUMED: `.pill`, `.path`, `.visa`, `.pillstack` live in the page's OWN inline
   <style>, not the shared sheet (0 hits in design/assets/css). These are namespaced additions to
   that block; the row shape, the badge, the pill and the tab chrome are all inherited unchanged.
   ⚠ `.path{grid-template-columns:54px 1fr auto}` and `.path b{display:block}` do the work — the
   middle column stacks "Priority N of M" over its condition exactly as the Pathways rows stack a
   visa name over "Requires state nomination". Nothing here re-implements that. */
/* ⛔ 7px, MEASURED AGAINST THE DONOR, not chosen. A Pathways row insets its middle column 24px
   from the border: 17px of `.path` padding plus ~6.5px of centring slack, because there the PILL
   STACK (61px) is the tallest child and the text (48px) is centred against it. Here the text is the
   tallest child, so it got no slack and sat 17px off the border — the line reading as too close.
   7px top and 11px bottom of its own padding put the TEXT at 25px / 28px from the two borders —
   the donor's own measured insets, taken from a Pathways row in the same page at the same width. ⚠ There is deliberately no `.po-row`
   rule: the row inherits `.path` whole, so grid, gap, alignment, padding and border can never drift
   from the Pathways rows they sit below. */
.po-steps{padding:7px 0 11px}
/* ⛔ THE VISA IDENTITY IS ONE PILL. It keeps the donor badge's own colours — `--occ-gold-pale` on
   `#8a5700`, 12px radius — so it still reads as the same family, but it auto-widths to hold the
   number AND the name. The donor's 50x50 `.visa` square cannot, which is why `.po-row` drops to two
   columns below: a wide identity has nowhere to sit in a 54px track.
   ⚠ This is the one place the panel deliberately departs from the Visa Pathways row shape. */
/* ⚠ also used inside #pathways, where it REPLACES the 50x50 `.visa` badge — see PATHWAYS_VISA.
   ⛔ THE COLUMN HAS TO OPEN UP WITH IT. `.path` is `54px 1fr auto`, sized for the square badge, so
   the wider pill was crushed into 54px and its text overlapped the visa name beside it. Seen only
   by rendering the section and looking at it (R-125) — the markup was valid and every gate green.
   ⚠ Scoped to `#pathways`: `.path` is shared, and widening it globally would move a section nobody
   asked about (R-113). */
#pathways .path{grid-template-columns:auto 1fr auto}
.path > .po-visapill{margin:0;align-self:center;white-space:nowrap}
.po-visapill{display:inline-flex;align-items:baseline;gap:9px;background:var(--occ-gold-pale,#fbf1d9);
  color:#8a5700;border-radius:12px;padding:7px 13px;margin:0 0 11px;max-width:100%;
  font:600 14px/1.35 var(--occ-sans,system-ui)}
.po-visapill{font-weight:700}
/* ⛔ THE PILL IS ONE TOKEN AND MUST NOT BREAK. `white-space:nowrap` was already set on
   `.path > .po-visapill`, which reaches NOTHING in the shipping layout: option D puts the pill
   inside `.po-cardhead`, not `.path` (a built page carries 0 `.path po-row` elements). The rule
   read as if the case were covered while `flex:0 1 auto; min-width:0` actively licensed the
   shrink. ⛔ MEASURED on the built pages: `Subclass 494` broke across TWO lines on 5 of 8 pages
   at 1280, and `Subclass 482`, `186` and `494` all broke at 390. The NAME beside it may wrap —
   that is prose — but the identity may not.
   ⚠ THIS RULE EXISTS TWICE in this file (two near-identical style blocks, 19 of 24 lines the
   same) and both reach the page, so the LATER one wins. Both are edited together; a fix to one
   alone would have been invisible (R-130). */
.po-cardhead .po-visapill{margin:0;flex:0 0 auto;min-width:0;white-space:nowrap}
.po-steps b{font-size:.95rem;letter-spacing:-.01em}
/* ⛔ TWO COLUMNS, NOT THE DONOR'S THREE. `.path` is `54px 1fr auto` for a fixed-width badge; the
   identity pill is now variable-width and lives inside the text column instead. */
.po-row{grid-template-columns:1fr auto}
.po-steps b:not(:first-child){margin-top:9px}
/* ⚠ `line-height` is NOT the cause of the 4px and was restored: removing it left the bottom gap at
   24px and grew every multi-rung row 8px for nothing. The gap comes from the donor's centring slack,
   so it is closed in the padding below. */
.po-steps small{display:block;line-height:1.4}
.po-lead{margin:0 0 18px;line-height:1.6;color:#3f4a55}
.po-lead b{font-weight:700;color:inherit}
/* ⛔ Same size and font as every other pill — `.pill` is inherited and only the colour differs, the
   rule `.listpill` already follows, so the Direction pill can never drift from the list pill it sits
   beside (design note 2026-09-23 §3). */
.pill.mdpill{background:#eef2f7;color:#3a4a5c}
/* ⛔ REMOVED 2026-09-28. `#signals .tabs{margin:6px 0 2px}` overrode the donor's `.tabs{margin:18px
   0}` + `.tabs{margin-bottom:22px}` and left the first row's border-top TWO pixels under the tab
   pills, against 22px in Visa Pathways. Measured, not eyeballed. The tabs inherit the donor rule.
   ⚠ Cards variant only. */
/* ⛔ A TRACK, NOT A GRID. `.mini-grid` is `repeat(3,1fr)`, so a fourth or fifth rung wrapped onto a
   second row and at half width three columns became 2-up with a dangling slot. The rungs are an
   ORDERED LADDER — wrapping row 2 under row 1 breaks the reading order that is the whole point.
   Same flex/snap/hidden-scrollbar shape the siblings carousel uses, so `.crsl-btn` drives it
   unchanged once `.po-cards` is added to TRACKS.
   ⚠ `:not(.po-cards)` on the lower-grid rule for the same reason `.sig-track` needed it — that rule
   is `display:grid!important`, which no specificity can beat from here (R-126). */
/* ⛔ PADDING SIZED FROM THE HOVER GEOMETRY, MEASURED. `.mini-card:hover` is `translateY(-3px)` plus
   `box-shadow:0 10px 24px`, so the painted box runs ~5px ABOVE the card, ~19px BELOW and ~12px to
   EACH side. `overflow-x:auto` clips at the padding box, so anything less is cut off.
   ⚠ I had `2px 0 4px` — measured room 0px on ALL FOUR sides — which clipped the top border on hover
   exactly as reported, and silently clipped the shadow on the other three. The codebase had already
   hit and documented this once for `.sig-track`; I reintroduced it in a second copy (R-113).
   ⚠ Horizontal padding is cancelled by a negative margin so the cards stay aligned with the text
   above, and `scroll-padding-inline` keeps snap points on the card edge, not the padding. */
.mini-grid.po-cards{display:flex;overflow-x:auto;gap:12px;margin:12px -12px 0;
  scroll-snap-type:x mandatory;padding:6px 12px 20px;scroll-padding-inline:12px;
  scrollbar-width:none;-ms-overflow-style:none}
/* ⛔ MEASURED AGAINST THE DONOR: `#pathways .path b` is 15px / weight 700 / rgb(23,33,27). The name
   had NO rule at all — I deleted it when the pill was cut back to "Subclass NNN" and restored only
   the markup when the name came back, so it inherited 15px/400. That was the single element in the
   panel not matching its counterpart; the rest already did (card label = `#related .mini-card small`
   11px/400/muted · card priority = `#related .mini-card b` 16px/700/forest · lead = the Points-test
   section blurb 15px/400/muted). */
.po-name{font:700 15px/1.35 var(--occ-sans,system-ui);color:var(--occ-ink,#17211b)}
/* ── CARDS: one set of rules for both new tracks ─────────────────────────────────────────────
   ⛔ `> span` — DIRECT CHILD ONLY. The rule here was `.mini-card span`, which also caught the bound
   markers inside `<b>Priority <span>2</span> of <span>4</span></b>` and made each one a BLOCK, so a
   priority rendered as four stacked rows. Measured after: the marker spans are 12.5px/700/block,
   which is the fingerprint of that bug.
   ⛔ A MINIMUM WIDTH. `flex:0 0 calc((100% - 24px)/3)` is three-up of whatever the container gives,
   and in the two-column lower grid that produced 112px-wide, 371px-tall cards beside 171px ones in
   the very next section. The card now has a floor and simply shows fewer per view when the
   container is narrow — which is what the scroll arrows are for.
   ⛔ ONE HOVER BEHAVIOUR. `.la-other` was `border-style:dashed`, so it kept a dotted edge on hover
   while every other card went solid-green: two cards side by side, behaving differently, for no
   reason a reader could name. It is distinguished by its tint alone and hovers like the rest. */
/* ⛔ A WHOLE NUMBER OF CARDS MUST FIT THE TRACK. Measured: the donor's Career-pathways track is
   443px and fits exactly 3 × 140 + 2 gaps = 444 — the next card starts off-screen, which reads as a
   carousel. My `clamp(190px, …)` floor put two 190px cards in a 384px track, so the second was cut
   32px mid-card, which reads as broken. A floor that ignores the container is not a floor.
   ⚠ The two tracks are in DIFFERENT containers by design — the processing-order one in the
   full-width section, the labour-agreement one in the two-column lower grid — so each takes the
   basis that fits ITS container exactly. Same component, same card, different arithmetic. */
.mini-grid.po-cards > *{flex:0 0 calc((100% - 24px)/3);scroll-snap-align:start;min-height:0}
.mini-grid.la-cards > *{flex:0 0 calc((100% - 12px)/2)}
.mini-grid.po-cards .mini-card > span,.mini-grid.la-cards .mini-card > span{display:block;
  margin-top:6px;font:400 12.5px/1.45 var(--occ-sans,system-ui);color:var(--occ-muted,#617067)}
.mini-grid.po-cards .mini-card b.abstain,.mini-grid.la-cards .mini-card b.abstain{
  color:var(--occ-muted,#617067)}
/* ⛔ NO TINT. `.la-other` carried `background:#fbfbf9` while every other card on the page is
   #fff — measured across 5 sections, it was the ONLY card with its own background. The owner
   has set the consistency rule three times (2026-09-30 ×2, 2026-10-01); a tint is the same
   class of difference as the width override already reverted today. The card is distinguished
   by its eyebrow and its text, not by its fill. */
/* ⛔ HEIGHT PARITY WITH THE NEIGHBOURS IN THE SAME SECTION. `#additional` holds Labour agreements
   and Career pathways side by side, and the Career-pathways cards carry the donor's
   `min-height:200px`. Measured before: LA 190x147 against 171x200 next to it — the same card
   component reading as two.
   ⚠ Widths cannot match exactly: the two tracks sit in different-width grid cells, so the LA cards
   come out ~190px and the neighbours ~171px. Height is what makes them read as one family. */
.mini-grid.la-cards .mini-card{min-height:200px}
/* the merged card's second sentence — same muted register as the abstention line above it */
.mini-card .la-alt{margin-top:8px;color:#6b7684}
/* ⛔ NO `:only-child` WIDTH OVERRIDE. I added one so the merged lone card filled the row; it
   made that card WIDER than every other card on the page, which breaks the consistency rule
   the owner has now set three times (2026-09-30 twice, 2026-10-01). A card keeps the track's
   width whether it has siblings or not; empty space beside a single card is a grid with one
   item, not a defect. */
@media (max-width:720px){.mini-grid.po-cards > *{flex:0 0 clamp(190px,calc((100% - 12px)/2),320px)}}
@media (max-width:460px){.mini-grid.po-cards > *{flex:0 0 78%}}
#pathways .path{grid-template-columns:auto 1fr auto}
.path > .po-visapill{margin:0;align-self:center;white-space:nowrap}
.po-visapill{display:inline-flex;align-items:baseline;gap:9px;background:var(--occ-gold-pale,#fbf1d9);
  color:#8a5700;border-radius:12px;padding:7px 13px;margin:0 0 11px;max-width:100%;
  font:600 14px/1.35 var(--occ-sans,system-ui)}
.po-visapill{font-weight:700}
/* ⛔ THE PILL IS ONE TOKEN AND MUST NOT BREAK. `white-space:nowrap` was already set on
   `.path > .po-visapill`, which reaches NOTHING in the shipping layout: option D puts the pill
   inside `.po-cardhead`, not `.path` (a built page carries 0 `.path po-row` elements). The rule
   read as if the case were covered while `flex:0 1 auto; min-width:0` actively licensed the
   shrink. ⛔ MEASURED on the built pages: `Subclass 494` broke across TWO lines on 5 of 8 pages
   at 1280, and `Subclass 482`, `186` and `494` all broke at 390. The NAME beside it may wrap —
   that is prose — but the identity may not.
   ⚠ THIS RULE EXISTS TWICE in this file (two near-identical style blocks, 19 of 24 lines the
   same) and both reach the page, so the LATER one wins. Both are edited together; a fix to one
   alone would have been invisible (R-130). */
.po-cardhead .po-visapill{margin:0;flex:0 0 auto;min-width:0;white-space:nowrap}
.po-steps b{font-size:.95rem;letter-spacing:-.01em}
/* ⛔ TWO COLUMNS, NOT THE DONOR'S THREE. `.path` is `54px 1fr auto` for a fixed-width badge; the
   identity pill is now variable-width and lives inside the text column instead. */
.po-row{grid-template-columns:1fr auto}
.po-steps b:not(:first-child){margin-top:9px}
/* ⚠ `line-height` is NOT the cause of the 4px and was restored: removing it left the bottom gap at
   24px and grew every multi-rung row 8px for nothing. The gap comes from the donor's centring slack,
   so it is closed in the padding below. */
.po-steps small{display:block;line-height:1.4}
.po-lead{margin:0 0 18px;line-height:1.6;color:#3f4a55}
.po-lead b{font-weight:700;color:inherit}
/* ⛔ Same size and font as every other pill — `.pill` is inherited and only the colour differs, the
   rule `.listpill` already follows, so the Direction pill can never drift from the list pill it sits
   beside (design note 2026-09-23 §3). */
.pill.mdpill{background:#eef2f7;color:#3a4a5c}
/* ⛔ REMOVED 2026-09-28. `#signals .tabs{margin:6px 0 2px}` overrode the donor's `.tabs{margin:18px
   0}` + `.tabs{margin-bottom:22px}` and left the first row's border-top TWO pixels under the tab
   pills, against 22px in Visa Pathways. Measured, not eyeballed. The tabs inherit the donor rule.
   ⚠ Cards variant only. */
/* ⛔ A TRACK, NOT A GRID. `.mini-grid` is `repeat(3,1fr)`, so a fourth or fifth rung wrapped onto a
   second row and at half width three columns became 2-up with a dangling slot. The rungs are an
   ORDERED LADDER — wrapping row 2 under row 1 breaks the reading order that is the whole point.
   Same flex/snap/hidden-scrollbar shape the siblings carousel uses, so `.crsl-btn` drives it
   unchanged once `.po-cards` is added to TRACKS.
   ⚠ `:not(.po-cards)` on the lower-grid rule for the same reason `.sig-track` needed it — that rule
   is `display:grid!important`, which no specificity can beat from here (R-126). */
/* ⛔ PADDING SIZED FROM THE HOVER GEOMETRY, MEASURED. `.mini-card:hover` is `translateY(-3px)` plus
   `box-shadow:0 10px 24px`, so the painted box runs ~5px ABOVE the card, ~19px BELOW and ~12px to
   EACH side. `overflow-x:auto` clips at the padding box, so anything less is cut off.
   ⚠ I had `2px 0 4px` — measured room 0px on ALL FOUR sides — which clipped the top border on hover
   exactly as reported, and silently clipped the shadow on the other three. The codebase had already
   hit and documented this once for `.sig-track`; I reintroduced it in a second copy (R-113).
   ⚠ Horizontal padding is cancelled by a negative margin so the cards stay aligned with the text
   above, and `scroll-padding-inline` keeps snap points on the card edge, not the padding. */
.mini-grid.po-cards{display:flex;overflow-x:auto;gap:12px;margin:12px -12px 0;
  scroll-snap-type:x mandatory;padding:6px 12px 20px;scroll-padding-inline:12px;
  scrollbar-width:none;-ms-overflow-style:none}
/* ⛔ MEASURED AGAINST THE DONOR: `#pathways .path b` is 15px / weight 700 / rgb(23,33,27). The name
   had NO rule at all — I deleted it when the pill was cut back to "Subclass NNN" and restored only
   the markup when the name came back, so it inherited 15px/400. That was the single element in the
   panel not matching its counterpart; the rest already did (card label = `#related .mini-card small`
   11px/400/muted · card priority = `#related .mini-card b` 16px/700/forest · lead = the Points-test
   section blurb 15px/400/muted). */
.po-name{font:700 15px/1.35 var(--occ-sans,system-ui);color:var(--occ-ink,#17211b)}
/* ⚠ The first version of these rules lived here and survived a later rewrite that inserted the
   replacement ABOVE without deleting this copy. Being later in source order, this one won on equal
   specificity: its `.mini-card span` (no `>`) kept blocking the bound markers inside `<b>`, so a
   priority still rendered as stacked rows, and its `border-style:dashed` kept the one odd hover.
   Both symptoms were reported as separate bugs; they were one dead copy (R-130). */
.po-cardhead .po-name{flex:1 1 auto;min-width:0}
.mini-grid.po-cards::-webkit-scrollbar{display:none}
/* ⚠ the card-width rules live ABOVE with the rest of the card formatting — a second copy here came
   LATER in source order and silently won on equal specificity, so the min-width had no effect at all
   until it was deleted (R-130: the rule you are reading is often the dead one). */
.po-cardgroup{padding:18px 0;border-top:1px solid var(--occ-line)}
.po-cardhead{display:flex;align-items:center;gap:14px}
@media (max-width:560px){
  .po-steps b{font-size:.9rem}
  /* ⚠ The donor collapses `.path` to two columns here and re-homes a bare `.pill` with
     `.path .pill{grid-column:2}`. Our Direction pill sits inside a `.pillstack`, which that rule
     does not reach, so it landed under the BADGE at the far left instead of under the text. Same
     destination, stated for the wrapper. Seen by rendering at 390px, not in the markup. */
  .po-row .pillstack{grid-column:2;justify-self:start;margin-top:4px}
}
