/* ════════════════════════════════════════════════════════════════
   LAUNCH ANNOUNCEMENT BAR — Ontario expansion, 2026-08-04
   ════════════════════════════════════════════════════════════════

   ┌─────────────────────────────────────────────────────────────┐
   │  KILL SWITCH — one edit, site-wide.                          │
   │                                                              │
   │  To retire the banner when the launch stops being news, set  │
   │  --announce-on to 0 below. Nothing else needs touching: the  │
   │  bar hides, the nav returns to the top of the viewport, and  │
   │  the body padding collapses, because all three read the same │
   │  variable. The markup can stay in the pages harmlessly.      │
   └─────────────────────────────────────────────────────────────┘ */
:root {
  --announce-on: 1;               /* 1 = show, 0 = retire */
  --announce-h: 40px;             /* desktop, one line — EXACT rendered height */
}

/* The height every other rule keys off. When the switch is 0 this collapses to
   zero, so the nav offset and the body padding disappear with the bar rather
   than leaving a 40px hole behind. */
:root { --announce-space: calc(var(--announce-h) * var(--announce-on)); }

/* Dismissed state is set on <html> by the inline head script BEFORE first
   paint, so a returning visitor never sees the bar flash and then vanish —
   that flash would be a real layout shift, which is the thing we are avoiding. */
html.announce-off { --announce-space: 0px; }

.announce {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 210;                   /* above the nav (200), below modals */
  display: block;
  /* EXACT height, border-box, and the hairline drawn as an inset shadow rather
     than a border. All three exist for the same reason: the nav is offset by
     --announce-h, so the bar's RENDERED height must equal that variable to the
     pixel. With min-height plus a 1px border it rendered 42px against a 40px
     offset and sat 2px over the nav — caught on the deployed site, not locally,
     because it is a sub-pixel layout fact rather than a code fact. */
  box-sizing: border-box;
  height: var(--announce-h);
  overflow: hidden;
  background: #0A1640;            /* --primary-dark */
  color: #fff;
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, .10);
}
:root[style] .announce, .announce { }

/* Hidden by the kill switch or by dismissal. `content-visibility` keeps it out
   of the a11y tree too, so a screen reader does not announce a dismissed bar. */
html.announce-off .announce { display: none; }
@supports not (min-height: calc(1px * 1)) { .announce { min-height: 40px; } }

.announce-inner {
  max-width: 1160px;
  margin: 0 auto;
  padding: 10px 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;                /* one line on desktop, wraps to two on mobile */
  text-align: center;
  font-family: 'Inter Tight', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.35;
}

.announce-text { color: rgba(255, 255, 255, .92); }

/* The blue is on the link ONLY. Everything else stays white on navy so the bar
   reads like a route announcement rather than a sale banner. */
.announce-link {
  color: #6E8BFF;                 /* --primary lifted for AA contrast on navy */
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 1px solid rgba(110, 139, 255, .45);
  /* Visual size unchanged; the HIT AREA is padded to a comfortable thumb
     target. Measured at 142x21 before this — fine for a mouse, mean on a phone
     at a bus stop, which is the whole scenario this bar exists for. The bar's
     height is fixed and overflow-hidden, so padding cannot change the layout. */
  padding: 13px 6px 12px;
  margin: -13px -6px -12px;
}
.announce-link:hover { color: #9DB2FF; border-bottom-color: rgba(157, 178, 255, .7); }
.announce-link:focus-visible { outline: 2px solid #9DB2FF; outline-offset: 3px; border-radius: 2px; }

.announce-close {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  /* The GLYPH stays small so it never competes with the link, but the tappable
     box is a full 44px. A 32px dismiss on a phone is the kind of thing people
     jab at three times. */
  width: 44px; height: 44px;
  display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, .55);
  font-size: 18px; line-height: 1;
  cursor: pointer;
  border-radius: 6px;
}
.announce-close:hover { color: #fff; background: rgba(255, 255, 255, .08); }
.announce-close:focus-visible { outline: 2px solid #9DB2FF; outline-offset: 2px; }

/* ── The offsets. These are why there is no layout shift: the space is
   reserved by CSS at first paint, not created later by JavaScript. ── */
body { padding-top: var(--announce-space); }
nav { top: var(--announce-space) !important; }

@media (max-width: 640px) {
  /* Measured at 375px with the copy below wrapping to two lines. If the copy
     changes, re-measure — this number and the rendered height must agree. */
  :root { --announce-h: 62px; }
  .announce-inner { padding: 9px 40px 9px 16px; font-size: 13px; gap: 6px; }
  .announce-close { right: 4px; }
}

@media (prefers-reduced-motion: no-preference) {
  .announce-link { transition: color .15s ease, border-color .15s ease; }
}
