/* ══════════════════════════════════════════════════════════════════════
   TNAADO site chrome — header, footer, breaking-news ticker, and The
   Dispatch secondary bar.

   SINGLE SOURCE OF TRUTH. Every page links this file; no page restyles
   .eh-* / .ef-* / .dxsub-* inline.

   Self-contained by design. Every colour below resolves against a --tnc-*
   token declared in this file, never against a page's own palette. The old
   inline copies each borrowed whatever tokens their page happened to
   define (--ink / --text-rgb / --tn-fg-rgb / --chrome-fg / …), which is
   why no two of them rendered the same. Do not reintroduce a page token
   here: if the chrome needs a new colour, add a --tnc-* for it.

   Load it LAST in <head> so it out-ranks any inline chrome CSS a page has
   not yet had removed.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  --tnc-bg: #0a0a0a;                 /* chrome surface base */
  --tnc-bg-rgb: 10, 10, 10;
  --tnc-fg: #f5f1e8;                 /* chrome primary text */
  --tnc-fg-rgb: 245, 241, 232;
  --tnc-surface: #080808;            /* footer + thin bars */
  --tnc-input-tint-rgb: 255, 255, 255;
  --tnc-red: #c8102e;                /* constant brand accent, both themes */
  --tnc-red-rgb: 200, 16, 46;
  /* #c8102e is only 3.4:1 on the dark chrome surface, so it may style borders,
     underlines and chips but never small red TEXT. --tnc-red-text is the same
     hue lifted to 5.1-5.7:1 for the few places red is the type colour (raised
     2026-08-05 from #e5334f/4.64:1 — real headroom over the 4.5 floor, and
     now the same value as base/variables.css's --red-text and retention.css's
     --tn-red-text, so header, page eyebrows and author bylines all match); in
     light mode #c8102e already clears 5.8:1, so it reverts there. */
  --tnc-red-text: #e8455a;
}
/* Opt-in light mode only — never OS prefers-color-scheme. Set by the head
   script from localStorage['tn-theme']; anything other than 'dark' is light,
   so a first-time visitor gets light. */
[data-theme="light"] {
  --tnc-bg: #faf6ee;
  --tnc-bg-rgb: 250, 246, 238;
  --tnc-fg: #1a1510;
  --tnc-fg-rgb: 26, 21, 16;
  --tnc-surface: #f1ebdd;
  --tnc-input-tint-rgb: 26, 21, 16;
  --tnc-red-text: #c8102e;
}


/* ── breaking-news ticker, the strip above the header bar ───────────────
   Markup lives inside the header region; hidden until the fetch fills it,
   and it fails closed to hidden rather than to an empty bar. */
.eh-header:has(.tn-ticker:not([hidden])) { height: auto; flex-direction: column; align-items: stretch; }
.tn-ticker {
  display: flex; align-items: stretch; height: 30px; width: 100%;
  background: var(--tnc-surface); border-bottom: 1px solid rgba(var(--tnc-fg-rgb),.12);
  overflow: hidden;
}
.tn-ticker[hidden] { display: none; }
.tn-ticker-label {
  flex-shrink: 0; display: flex; align-items: center; padding: 0 1rem;
  font-family: "JetBrains Mono", monospace; font-size: .6rem; letter-spacing: .22em;
  text-transform: uppercase; color: var(--tnc-red-text);
  border-right: 1px solid rgba(var(--tnc-fg-rgb),.12);
}
.tn-ticker-viewport { flex: 1; min-width: 0; overflow: hidden; display: flex; align-items: stretch; }
.tn-ticker-track {
  display: flex; align-items: center; width: max-content; flex-shrink: 0;
  animation: tn-ticker-marquee 38s linear infinite;
}
.tn-ticker:hover .tn-ticker-track { animation-play-state: paused; }
@keyframes tn-ticker-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.tn-ticker-half { display: flex; align-items: center; flex-shrink: 0; }
.tn-ticker-item {
  display: flex; align-items: center; white-space: nowrap; flex-shrink: 0;
  font-family: "JetBrains Mono", monospace; font-size: .62rem; letter-spacing: .06em;
  /* .62 alpha, not .65: measured 7.6:1 dark / 5.3:1 light on the bar's real
     composited surface. */
  color: rgba(var(--tnc-fg-rgb),.78); transition: color .25s ease;
}
.tn-ticker-item:hover { color: var(--tnc-fg); }
.tn-ticker-cat { color: var(--tnc-red-text); text-transform: uppercase; letter-spacing: .16em; margin-right: .55rem; }
.tn-ticker-sep { color: var(--tnc-red-text); padding: 0 1rem; }
@media (prefers-reduced-motion: reduce) { .tn-ticker-track { animation: none; } }

/* Chrome links never inherit a page's link styling. Pages differ on whether
   they reset `a { text-decoration }` at all, and a page that doesn't was
   underlining every nav item and ticker headline. The chrome states it. */
.eh-header a,
.eh-search-panel a,
.eh-mobile-overlay a,
.ef-footer a,
.dxsub a { text-decoration: none; }

/* Sticky, so it always sits above scrolling content by design — but a page
   whose hero is itself near-black (the /areas boundary map, any full-bleed
   dark photo section) used to read as "the map is overlapping the header":
   the old .92-opacity background + a 12%-alpha hairline gave almost no
   visual edge against content that dark, so header and content visually
   fused into one black field instead of reading as chrome-above-content.
   Root-cause fix, not a per-page patch: raise the header's own opacity so
   the blur has less to see through, and add a real (if soft) drop shadow —
   a shadow's own gradient still reads as depth against dark content, where
   a flat hairline border does not. */
.eh-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: 64px;
  /* No background/backdrop-filter on the sticky element itself — see ::before
     below. The previous fix (transform: translateZ(0) + will-change:
     transform, kept below as a cheap extra compositing hint) promotes the
     element to its own GPU layer but does NOT stop iOS Safari from
     re-deciding that layer's contents mid-scroll — it measurably still
     drops the header on a real iPhone. The verified fix (confirmed working
     on service.tnaado.ca, commit e9c22d1) is to never let the sticky/fixed
     element itself paint a background or backdrop-filter at all; put both
     on an absolutely positioned ::before behind its content instead.
     `!important` on the next two lines is deliberate, not a style hack: 34
     pages still carry a stale, pre-chrome.css inline `<style id="tn-chrome-
     css">` copy of this exact selector (dead weight this fix doesn't clean
     up — see commit message) that independently declares `background` and
     `backdrop-filter` on `.eh-header`. Cascade resolves those two properties
     per-declaration, not per-rule-block, so once this rule stopped
     contesting them the stale copy silently won them back — which measurably
     reintroduced the bug's exact precondition (backdrop-filter directly on
     the sticky element) on every page still carrying that leftover style.
     `!important` here is the one-file guarantee that this fix cannot be
     undone by dead CSS anyone (including a future edit) leaves lying around
     elsewhere on the page. */
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  will-change: transform;
  border-bottom: 1px solid rgba(var(--tnc-fg-rgb),.3);
  box-shadow: 0 10px 24px -14px rgba(0,0,0,.65);
  display: flex;
  align-items: center;
}
.eh-header::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(var(--tnc-bg-rgb),.97);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  pointer-events: none;
}
.eh-inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 clamp(1rem,4vw,2.5rem);
  width: 100%;
  display: flex;
  align-items: center;
  gap: 2rem;
}
.eh-logo { flex-shrink: 0; display: flex; align-items: center; }
.eh-logo img { height: 28px; width: auto; display: block; }
.eh-nav {
  display: flex;
  align-items: center;
  gap: 2rem;
  flex: 1;
  justify-content: center;
}
.eh-nav a {
  font-family: "IBM Plex Sans", sans-serif;
  font-size: .82rem;
  font-weight: 400;
  letter-spacing: .04em;
  color: rgba(var(--tnc-fg-rgb),.78);
  transition: color .2s;
  white-space: nowrap;
}
.eh-nav a:hover { color: var(--tnc-fg); }
.eh-actions {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  flex-shrink: 0;
}
.eh-theme-btn {
  background: none;
  border: none;
  color: rgba(var(--tnc-fg-rgb),.72);
  padding: .3rem;
  display: flex;
  align-items: center;
  transition: color .2s;
}
.eh-theme-btn:hover, .eh-theme-btn:focus-visible { color: var(--tnc-fg); outline: none; }
.eh-theme-ico-moon { display: none; }
html[data-theme="light"] .eh-theme-ico-sun { display: none; }
html[data-theme="light"] .eh-theme-ico-moon { display: block; }
.eh-search-btn {
  background: none;
  border: none;
  color: rgba(var(--tnc-fg-rgb),.72);
  padding: .3rem;
  display: flex;
  align-items: center;
  transition: color .2s;
}
.eh-search-btn:hover { color: var(--tnc-fg); }
.eh-hamburger {
  display: none;
  background: none;
  border: none;
  color: rgba(var(--tnc-fg-rgb),.75);
  padding: .3rem;
  flex-direction: column;
  gap: 5px;
}
.eh-hamburger span {
  display: block;
  width: 22px;
  height: 1.5px;
  background: currentColor;
  transition: transform .3s, opacity .3s;
}
.eh-hamburger.is-open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.eh-hamburger.is-open span:nth-child(2) { opacity: 0; }
.eh-hamburger.is-open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ── THE COMPANY dropdown (desktop) ── */
.eh-dropdown { position: relative; display: flex; align-items: center; }
.eh-dropdown-toggle {
  background: none;
  border: none;
  font-family: "IBM Plex Sans", sans-serif;
  font-size: .82rem;
  font-weight: 400;
  letter-spacing: .04em;
  color: rgba(var(--tnc-fg-rgb),.78);
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: 1.2rem 0;
  transition: color .2s;
  white-space: nowrap;
}
.eh-dropdown-toggle:hover,
.eh-dropdown-toggle:focus-visible { color: var(--tnc-fg); outline: none; }
.eh-dd-caret {
  font-size: .6rem;
  color: var(--tnc-red-text);
  transition: transform .25s cubic-bezier(0.16, 1, 0.3, 1);
}
.eh-dropdown:hover .eh-dd-caret,
.eh-dropdown:focus-within .eh-dd-caret,
.eh-dropdown.is-open .eh-dd-caret { transform: rotate(180deg); }
.eh-dropdown-panel {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  min-width: 200px;
  background: rgba(var(--tnc-bg-rgb),.92);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(var(--tnc-fg-rgb),.12);
  border-top: 1px solid rgba(var(--tnc-red-rgb),.55);
  padding: .5rem 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, transform .25s cubic-bezier(0.16, 1, 0.3, 1), visibility .2s;
}
.eh-dropdown:hover .eh-dropdown-panel,
.eh-dropdown:focus-within .eh-dropdown-panel,
.eh-dropdown.is-open .eh-dropdown-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}
.eh-dropdown-panel a {
  display: block;
  padding: .55rem 1.2rem;
  font-family: "JetBrains Mono", monospace;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(var(--tnc-fg-rgb),.65);
  transition: color .15s, background .15s;
}
.eh-dropdown-panel a:hover,
.eh-dropdown-panel a:focus-visible {
  color: var(--tnc-red-text);
  background: rgba(var(--tnc-red-rgb),.07);
  outline: none;
}

/* ── THE COMPANY group (mobile overlay) ── */
.eh-mob-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
}
.eh-mob-group-toggle {
  background: none;
  border: none;
  font-family: "Fraunces", serif;
  font-size: clamp(1.4rem,5vw,2rem);
  font-weight: 400;
  color: var(--tnc-fg);
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  transition: color .2s;
}
.eh-mob-group-toggle:hover,
.eh-mob-group-toggle[aria-expanded="true"] { color: var(--tnc-red-text); }
.eh-mob-group-toggle .eh-dd-caret { font-size: .9rem; }
.eh-mob-group-toggle[aria-expanded="true"] .eh-dd-caret { transform: rotate(180deg); }
.eh-mob-group-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding-bottom: .4rem;
}
.eh-mobile-overlay .eh-mob-group-links a {
  font-family: "JetBrains Mono", monospace;
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(var(--tnc-fg-rgb),.7);
}
.eh-mobile-overlay .eh-mob-group-links a:hover { color: var(--tnc-red-text); }

/* Mobile overlay nav. Always in the flex layout (never display:none) so it can
   transition — the old display:none/flex toggle made open/close an instant
   snap with zero animation, the one thing that made it feel worse than the
   slide-down search panel a few rules up. visibility+opacity+transform is
   the same recipe .eh-search-panel already uses, same 380ms cubic-bezier. */
.eh-mobile-overlay {
  display: flex;
  position: fixed;
  /* Longhands, not the `inset` shorthand. `inset: var(--x) 0 0 0` is one
     declaration, so an unresolved --tnc-header-h invalidates ALL FOUR sides and
     the fixed element shrink-wraps at its static position instead of covering
     the screen. That is what was pushing the mobile sheet off-centre and past
     the right edge. Split, a bad variable can only cost us `top`. */
  top: var(--tnc-header-h, 64px);
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(var(--tnc-bg-rgb),.97);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  z-index: 99;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-14px);
  transition: opacity 300ms ease, transform 380ms cubic-bezier(0.16,1,0.3,1), visibility 380ms;
}
.eh-mobile-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
}
/* keep the header (logo, close button, breaking-news ticker) pinned on top while the mobile menu is open (fixes menu-open header scroll-away + banner overlap) */
body:has(.eh-mobile-overlay.is-open) .eh-header { position: fixed; top: 0; left: 0; right: 0; z-index: 2000; }
.eh-mobile-overlay a {
  font-family: "Fraunces", serif;
  font-size: clamp(1.4rem,5vw,2rem);
  font-weight: 400;
  color: var(--tnc-fg);
}
.eh-mobile-overlay a:hover { color: var(--tnc-red-text); }
/* Per-item cascade: links arrive a beat after the sheet itself instead of
   all popping in at once with it. transition lives here (not on `.eh-mobile-
   overlay a` above) so this one rule owns opacity/transform/color for every
   direct child without two rules fighting over the transition shorthand. */
.eh-mobile-overlay > * {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 260ms ease, transform 320ms cubic-bezier(0.16,1,0.3,1), color .2s;
}
.eh-mobile-overlay.is-open > * { opacity: 1; transform: translateY(0); }
.eh-mobile-overlay.is-open > *:nth-child(1) { transition-delay: 70ms; }
.eh-mobile-overlay.is-open > *:nth-child(2) { transition-delay: 110ms; }
.eh-mobile-overlay.is-open > *:nth-child(3) { transition-delay: 150ms; }
.eh-mobile-overlay.is-open > *:nth-child(4) { transition-delay: 190ms; }
.eh-mobile-overlay.is-open > *:nth-child(5) { transition-delay: 230ms; }
.eh-mobile-overlay.is-open > *:nth-child(6) { transition-delay: 270ms; }
@media (prefers-reduced-motion: reduce) {
  .eh-mobile-overlay, .eh-mobile-overlay > * { transition-duration: 1ms !important; transition-delay: 0ms !important; }
}

@media (max-width: 768px) {
  .eh-nav { display: none; }
  .eh-hamburger { display: flex; }
}

/* tn-nav-gap */
@media (max-width: 960px) {
  .eh-nav { gap: 1rem; }
}

.ef-footer {
  background: var(--tnc-surface);
  border-top: 1px solid rgba(var(--tnc-fg-rgb),.12);
  padding: 3rem 0 0;
}
.ef-footer-inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 clamp(1rem,4vw,2.5rem);
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 3rem;
  padding-bottom: 2.5rem;
}
.ef-col-logo img { height: 26px; width: auto; margin-bottom: 1rem; }
.ef-tagline {
  font-family: "JetBrains Mono", monospace;
  font-size: .65rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(var(--tnc-fg-rgb),.72);
}
.ef-social { display: flex; align-items: center; gap: 16px; margin-top: 1.4rem; }
.ef-social a { display: inline-flex; color: rgba(var(--tnc-fg-rgb),.7); transition: color .2s ease, transform .2s ease; }
.ef-social a:hover, .ef-social a:focus-visible { color: var(--tnc-fg); transform: translateY(-1px); outline: none; }
.ef-social svg { display: block; width: 18px; height: 18px; fill: currentColor; }
.ef-col-heading {
  font-family: "JetBrains Mono", monospace;
  font-size: .65rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(var(--tnc-fg-rgb),.72);
  margin-bottom: 1.2rem;
}
.ef-col nav { display: flex; flex-direction: column; gap: .7rem; }
.ef-col nav a {
  font-size: .88rem;
  color: rgba(var(--tnc-fg-rgb),.78);
  transition: color .2s;
}
.ef-col nav a:hover { color: var(--tnc-fg); }
.ef-bottom {
  border-top: 1px solid rgba(var(--tnc-fg-rgb),.06);
  padding: 1.2rem clamp(1rem,4vw,2.5rem);
  max-width: 1140px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.ef-copy {
  font-family: "JetBrains Mono", monospace;
  font-size: .62rem;
  letter-spacing: .1em;
  color: rgba(var(--tnc-fg-rgb),.72);
}
/* was an inline style="color:#c8102e" on the anchor — 3.4:1 on the footer
   surface. Class + --tnc-red-text instead, so it is styled here like the rest
   of the chrome and clears AA in both themes. */
.ef-bottom-support { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; font-size: .85em; }
.ef-support { color: var(--tnc-red-text); font-weight: 600; letter-spacing: .04em; }
.ef-bottom-links { display: flex; gap: 1.4rem; }
.ef-bottom-links a {
  font-family: "JetBrains Mono", monospace;
  font-size: .62rem;
  letter-spacing: .1em;
  color: rgba(var(--tnc-fg-rgb),.78);
  transition: color .2s;
}
.ef-bottom-links a:hover { color: var(--tnc-fg); }

@media (max-width: 768px) {
  .ef-footer-inner { grid-template-columns: 1fr; gap: 2rem; }
}
@media (min-width: 769px) and (max-width: 1040px) {
  /* four tracks get cramped on a tablet, so the three link columns go 2-up */
  .ef-footer-inner { grid-template-columns: 1fr 1fr; gap: 2.2rem; }
}

.skip-link { position: absolute; top: -100%; left: 1rem; background: var(--tnc-red); color: #fff; padding: .5rem 1rem; font-size: .85rem; z-index: 9999; }
.skip-link:focus { top: 1rem; }

/* tn slide-down search */
.eh-search-panel {
  position: fixed; top: var(--tnc-header-h, 64px); left: 0; right: 0; z-index: 98;
  background: rgba(var(--tnc-bg-rgb),.97);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid rgba(var(--tnc-red-rgb),.45);
  transform: translateY(-110%); opacity: 0; visibility: hidden;
  transition: transform 380ms cubic-bezier(0.16,1,0.3,1), opacity 300ms ease, visibility 380ms;
  max-height: calc(100vh - var(--tnc-header-h, 64px)); max-height: calc(100svh - var(--tnc-header-h, 64px)); overflow-y: auto;
}
.eh-search-panel.is-open { transform: translateY(0); opacity: 1; visibility: visible; }
.eh-search-panel-inner {
  max-width: 680px; margin: 0 auto; padding: 1.4rem clamp(1rem,4vw,2.5rem);
  display: flex; align-items: center; gap: .9rem;
}
.eh-search-panel-inner svg { color: var(--tnc-red); flex-shrink: 0; }
.eh-search-input {
  flex: 1; min-height: 44px; background: rgba(var(--tnc-input-tint-rgb),.06);
  border: 1px solid rgba(var(--tnc-input-tint-rgb),.15); color: var(--tnc-fg);
  font-family: "IBM Plex Sans", sans-serif; font-size: 1rem;
  padding: 0 1.1rem; border-radius: 4px; outline: none; transition: border-color .2s;
}
.eh-search-input::placeholder { color: rgba(var(--tnc-fg-rgb),.3); }
.eh-search-input:focus { border-color: var(--tnc-red); }
.eh-search-close {
  background: none; border: none; color: rgba(var(--tnc-fg-rgb),.55);
  font-size: 1.5rem; line-height: 1; min-width: 44px; min-height: 44px;
  display: flex; align-items: center; justify-content: center; transition: color .2s;
}
.eh-search-close:hover { color: var(--tnc-fg); }
.eh-search-results { max-width: 680px; margin: 0 auto; padding: 0 clamp(1rem,4vw,2.5rem) 1rem; text-align: left; }
.eh-search-results .search-hit {
  display: block; padding: .8rem 1rem; border-top: 1px solid rgba(var(--tnc-input-tint-rgb),.06);
  text-decoration: none; color: inherit; transition: background .15s;
}
.eh-search-results .search-hit:hover { background: rgba(var(--tnc-red-rgb),.07); }
.eh-search-results .search-hit-cat {
  font-family: "JetBrains Mono", monospace; font-size: .58rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--tnc-red-text); margin: 0 0 .25rem;
}
.eh-search-results .search-hit-title { font-size: .9rem; color: var(--tnc-fg); margin: 0; }
.eh-search-results .search-hit-empty { padding: 1rem; font-size: .85rem; color: rgba(var(--tnc-fg-rgb),.45); text-align: center; }


.eh-theme-btn, .eh-search-btn, .eh-hamburger, .eh-dropdown-toggle { min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
.eh-nav a { padding-top: .75rem; padding-bottom: .75rem; min-height: 44px; display: inline-flex; align-items: center; }
.eh-mobile-overlay a, .eh-mob-group-toggle { min-height: 44px; display: inline-flex; align-items: center; }

/* ── The Dispatch secondary bar ─────────────────────────────────────────
   The product sub-header that sits under the site header on every Dispatch
   surface: the wordmark plus the section links. Every item is a link to
   another page — there are no controls in here, so nothing in this bar can
   be mistaken for the category FILTER buttons further down /dispatch.
   The current section is marked with .is-current + aria-current="page".

   Sticky, pinned directly under the main header via --tnc-header-h (set by
   partials/header.html's ResizeObserver, recomputed live on ticker show/hide
   and any header-height change) — the exact hazard that used to block making
   this sticky is now handled centrally by that variable, the same one
   .eh-mobile-overlay and .eh-search-panel already depend on. */
.dxsub { position: sticky; top: var(--tnc-header-h, 64px); z-index: 89; }
.dxsub-bar {
  display: flex; align-items: center; gap: 20px;
  padding: 11px clamp(1rem, 4vw, 2.5rem);
  background: var(--tnc-surface);
  border-bottom: 1px solid rgba(var(--tnc-fg-rgb),.12);
  font-family: "IBM Plex Sans", -apple-system, system-ui, sans-serif;
}
.dxsub-mark {
  flex-shrink: 0;
  font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 20px;
  color: var(--tnc-fg); text-decoration: none;
}
.dxsub-mark i { font-style: normal; color: var(--tnc-red-text); }
.dxsub-nav {
  display: flex; align-items: center; gap: 18px;
  font-size: 13px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.dxsub-nav::-webkit-scrollbar { display: none; }
.dxsub-link {
  padding: 3px 0; white-space: nowrap; text-decoration: none;
  /* .70 alpha: 8.9:1 dark / 6.1:1 light composited on --tnc-surface. */
  color: rgba(var(--tnc-fg-rgb),.78);
  border-bottom: 2px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.dxsub-link:hover, .dxsub-link:focus-visible { color: var(--tnc-fg); outline: none; }
.dxsub-link.is-current { color: var(--tnc-fg); border-bottom-color: var(--tnc-red); }
@media (max-width: 560px) {
  .dxsub-bar { gap: 14px; }
  .dxsub-nav { gap: 14px; }
  .dxsub-link { min-height: 44px; display: inline-flex; align-items: center; }
  /* All four sections do not fit beside the wordmark on a phone, and the one
     that fell off the edge was whichever section you were currently in. The
     wordmark is the thing to drop: the site logo is directly above it. */
  .dxsub-mark { display: none; }
}

/* ── REBOOT 2026-09-08: brand column on the left, bigger centre nav ──────────
   Ethan: "links and the firm need to be moved to under tnaado logo on the left
   and size of the 3 remaining middle links increased."

   Every selector here is deliberately prefixed with `.eh-header`. This began
   as a defence against per-page inline copies of the chrome that declared
   `.eh-nav a { font-size: .82rem }` at specificity (0,1,1); a bare `.eh-nav a`
   here would tie and lose to the later inline copy. Those copies are all gone
   now (2026-09-09, the last three were live-map, on-air and live-go), but the
   prefix stays: it costs nothing and it is what stops the next pasted block
   from silently winning. */

.eh-header .eh-brand {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}
/* Beside the wordmark, not under it, and stacked: Links above The Firm.
   Under the logo they read as a caption hanging off it. */
.eh-header .eh-brand-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: .3rem;
  padding-left: 1rem;
  border-left: 1px solid rgba(var(--tnc-fg-rgb),.18);
}
.eh-header .eh-brand-nav a,
.eh-header .eh-brand-nav .eh-dropdown-toggle {
  font-family: "JetBrains Mono", monospace;
  font-size: .62rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(var(--tnc-fg-rgb),.62);
  padding: 0;
  min-height: 0;
  white-space: nowrap;
}
.eh-header .eh-brand-nav a:hover,
.eh-header .eh-brand-nav .eh-dropdown-toggle:hover {
  color: var(--tnc-fg);
}
.eh-header .eh-brand-nav .eh-dropdown { align-items: center; }
.eh-header .eh-brand-nav .eh-dropdown-toggle { padding: 0; line-height: 1.1; }
.eh-header .eh-brand-nav a { line-height: 1.1; }
.eh-header .eh-brand-nav .eh-dd-caret { font-size: .5rem; }

/* The three that remain in the centre carry the site now, so they read larger.

   `line-height` is pinned rather than inherited. Without it the link box is
   font-size x whatever line-height the PAGE happens to set, so the header came
   out 44px tall on pages that load only chrome.css and 49px on the ones that
   also load main.css (line-height 1.55). That 5px landed on the header itself,
   which visibly jumped height when moving between sections. The chrome must
   not be a consequence of which stylesheets a page happens to carry. */
.eh-header .eh-nav a {
  font-family: "Fraunces", Georgia, serif;
  font-size: 1.02rem;
  line-height: 1.2;
  letter-spacing: .005em;
  color: rgba(var(--tnc-fg-rgb),.86);
}
.eh-header .eh-nav { gap: 2.4rem; }

/* The section you are on reads red. This lived inline on /live and /apps only,
   so the current-section cue worked on 2 pages out of 43. --red-text is the
   lightened red (#e8455a); plain #c8102e on ink measures 3.4:1 and fails AA. */
.eh-header .eh-nav a[aria-current="page"] { color: var(--red-text, #e8455a); }

/* The brand column is two rows now, so a fixed 64px would clip it. Height goes
   auto with a floor; --tnc-header-h is measured by the ResizeObserver in the
   header partial, so the search panel and mobile overlay follow automatically. */
.eh-header { height: auto; min-height: 68px; }

@media (max-width: 768px) {
  /* The mobile overlay already carries Links and the Firm group, so the brand
     column collapses back to just the logo rather than duplicating them. */
  .eh-header .eh-brand-nav { display: none; }
  .eh-header { min-height: 64px; }
}
@media (max-width: 960px) {
  .eh-header .eh-nav { gap: 1.4rem; }
  .eh-header .eh-nav a { font-size: .92rem; }
}

/* ── Migrated 2026-09-08 from the stale inline <style id="tn-chrome-css"> block ──
   That block sat in the head of 35 pages, duplicating most of this file and
   silently winning every cascade tie because it came later. It caused three
   separate bugs in one night. These are the rules it carried that this file did
   NOT, so they had to move here before the block could be deleted. The .tn-hdr
   rules it also carried were dropped: no .tn-hdr markup exists anywhere. */

.eh-theme-icon { pointer-events: none; }
.eh-theme-icon--moon { display: none; }
[data-theme="light"] .eh-theme-icon--sun { display: none; }
[data-theme="light"] .eh-theme-icon--moon { display: block; }
html, body { overflow-x: hidden; overflow-x: clip; max-width: 100%; }
img, video, iframe, svg, canvas { max-width: 100%; }
h1 { font-size: clamp(2.4rem, 6vw, 5rem) !important; line-height: 1.08; overflow-wrap: break-word; }
h2 { font-size: clamp(1.8rem, 4vw, 3rem) !important; line-height: 1.15; overflow-wrap: break-word; }
.inner { max-width: 1140px; margin-left: auto; margin-right: auto; padding-left: clamp(1rem,4vw,2.5rem); padding-right: clamp(1rem,4vw,2.5rem); }

/* ── REBOOT 2026-09-08: the Firm dropdown, and the mobile sheet ─────────────
   Ethan: "drop down menu needs work for the firm ... and make sure its built
   beautfulli for mobile."

   The panel was centred on its trigger (left:50% + translateX(-50%)). That was
   fine when the trigger sat in a centred nav, but the brand column moved it to
   the far left, so the panel hung out to the right and overlapped the hero. It
   now anchors to the trigger's left edge. */

.eh-header .eh-brand-nav .eh-dropdown-panel {
  left: 0;
  right: auto;
  transform: translateY(6px) scale(.98);
  transform-origin: top left;
  min-width: 210px;
  padding: .4rem;
  border: 1px solid rgba(var(--tnc-fg-rgb),.10);
  border-top: 2px solid var(--tnc-red);
  border-radius: 2px;
  background: rgba(var(--tnc-bg-rgb),.97);
  box-shadow: 0 18px 40px -20px rgba(0,0,0,.85), 0 2px 8px -4px rgba(0,0,0,.4);
}
.eh-header .eh-brand-nav .eh-dropdown:hover .eh-dropdown-panel,
.eh-header .eh-brand-nav .eh-dropdown:focus-within .eh-dropdown-panel,
.eh-header .eh-brand-nav .eh-dropdown.is-open .eh-dropdown-panel {
  transform: translateY(0) scale(1);
}
/* Items get room to breathe and a red index rule on hover, rather than a flat
   background flash that read as an OS select menu. */
.eh-header .eh-dropdown-panel a {
  position: relative;
  padding: .62rem .9rem .62rem 1.15rem;
  font-size: .64rem;
  letter-spacing: .18em;
  color: rgba(var(--tnc-fg-rgb),.72);
  border-radius: 1px;
}
.eh-header .eh-dropdown-panel a::before {
  content: "";
  position: absolute;
  left: .45rem; top: 50%;
  width: 2px; height: 0;
  background: var(--tnc-red);
  transform: translateY(-50%);
  transition: height .18s cubic-bezier(0.16,1,0.3,1);
}
.eh-header .eh-dropdown-panel a:hover,
.eh-header .eh-dropdown-panel a:focus-visible {
  color: var(--tnc-fg);
  background: rgba(var(--tnc-fg-rgb),.045);
}
.eh-header .eh-dropdown-panel a:hover::before,
.eh-header .eh-dropdown-panel a:focus-visible::before { height: 58%; }

/* ── Mobile sheet ─────────────────────────────────────────────────────────
   The submenu could never collapse: .eh-mob-group-links sets display:flex,
   which defeats the `hidden` attribute the toggle relies on. So the Firm group
   was permanently expanded and the toggle appeared to do nothing. */
.eh-mobile-overlay .eh-mob-group-links[hidden] { display: none; }

@media (max-width: 768px) {
  .eh-mobile-overlay {
    justify-content: flex-start;
    gap: 0;
    padding: 2.25rem 1.5rem calc(2rem + env(safe-area-inset-bottom));
    overflow-y: auto;
    text-align: center;
  }
  /* One rhythm for the whole sheet instead of a 2.5rem gap that pushed the
     last items off a short screen. */
  .eh-mobile-overlay .eh-mob-link,
  .eh-mobile-overlay .eh-mob-group { width: 100%; }
  .eh-mobile-overlay .eh-mob-link {
    display: block;
    padding: .95rem 0;
    font-size: clamp(1.5rem, 7vw, 2.1rem);
    border-bottom: 1px solid rgba(var(--tnc-fg-rgb),.09);
  }
  .eh-mobile-overlay .eh-mob-group {
    width: 100%;
    gap: 0;
    border-bottom: 1px solid rgba(var(--tnc-fg-rgb),.09);
  }
  .eh-mobile-overlay .eh-mob-group-toggle {
    width: 100%;
    justify-content: center;
    padding: .95rem 0;
    font-size: clamp(1.5rem, 7vw, 2.1rem);
  }
  .eh-mobile-overlay .eh-mob-group-links {
    gap: 0;
    padding: 0 0 .9rem;
  }
  .eh-mobile-overlay .eh-mob-group-links a {
    display: block;
    padding: .6rem 0;
    font-size: .72rem;
    letter-spacing: .2em;
    color: rgba(var(--tnc-fg-rgb),.6);
  }
}

/* The chrome had no box-sizing reset of its own, so `padding` on the mobile
   sheet was being added OUTSIDE its width: the sheet measured 390 + 48 and its
   rows ran ~24px past the right edge, which is what made the menu look
   off-centre. Scoped to the chrome so it cannot disturb page layout. */
.eh-header, .eh-header *,
.eh-mobile-overlay, .eh-mobile-overlay *,
.eh-search-panel, .eh-search-panel *,
.ef-footer, .ef-footer * { box-sizing: border-box; }

/* Footer contact block. Ethan: "fix footer to have address and email / contact
   details like other companies do." Sits in the brand column under the tagline,
   set in the mono label face so it reads as a colophon rather than navigation. */
.ef-footer .ef-contact {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  margin-top: 1rem;
}
.ef-footer .ef-contact__line,
.ef-footer .ef-contact__link {
  font-family: "JetBrains Mono", monospace;
  font-size: .64rem;
  letter-spacing: .1em;
  line-height: 1.5;
  color: rgba(var(--tnc-fg-rgb),.55);
}
.ef-footer .ef-contact__link { transition: color .2s; }
.ef-footer .ef-contact__link:hover { color: var(--tnc-red-text, #e8455a); }


/* ── RESTORED 2026-09-09 ─────────────────────────────────────────────
   These were lost when I deleted the stale inline <style id="tn-chrome-css">
   block from 35 pages. I computed the orphan-selector diff from index.html
   alone and assumed that block was identical everywhere. It was not: each
   page carried its own additions. That silently unstyled the Show sub-header
   on three pages and broke light mode across several more.
   Chrome-scoped rules land here so they cannot be lost again. */

/* The blur kill needs !important; the COLOUR must not have it.
   This rule came back in 865848a when 134 selectors were restored from
   per-page inline blocks. In those blocks it was scoped to pages that were
   dark-only, so a hardcoded ink background was harmless. Promoted into shared
   chrome it forced the header and footer to near-black on EVERY page, and
   because it carries !important it beat the [data-theme="light"] rule two
   lines below it. The result: in light theme the body went bone and the
   chrome stayed black, and the caret, correctly switched to the light red
   #c8102e, landed on that black ground at 3.37:1.
   --tnc-bg-rgb is already theme-scoped (10,10,10 dark / 250,246,238 light),
   so the colour follows the theme and only the blur stays forced. */
.eh-header, .ef-footer {
  background: rgb(var(--tnc-bg-rgb)) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.eh-nav .eh-dropdown-panel a { display: block; min-height: auto; }
[data-theme="light"] .eh-header { background: rgba(250,246,238,.92); border-bottom-color: rgba(20,16,12,.12); }
[data-theme="light"] .eh-nav a { color: rgba(20,16,12,.65); }
[data-theme="light"] .eh-nav a:hover { color: #1a1510; }
[data-theme="light"] .eh-dropdown-toggle { color: rgba(20,16,12,.65); }
[data-theme="light"] .eh-dropdown-toggle:hover, [data-theme="light"] .eh-dropdown-toggle:focus-visible { color: #1a1510; }
[data-theme="light"] .eh-dropdown-panel { background: rgba(250,246,238,.96); border-color: rgba(20,16,12,.14); }
[data-theme="light"] .eh-dropdown-panel a { color: rgba(20,16,12,.65); }
[data-theme="light"] .eh-dropdown-panel a:hover, [data-theme="light"] .eh-dropdown-panel a:focus-visible { color: #c8102e; background: rgba(200,16,46,.08); }
[data-theme="light"] .eh-theme-btn { color: rgba(20,16,12,.55); }
[data-theme="light"] .eh-theme-btn:hover, [data-theme="light"] .eh-theme-btn:focus-visible { color: #1a1510; }
[data-theme="light"] .eh-search-btn { color: rgba(20,16,12,.55); }
[data-theme="light"] .eh-search-btn:hover { color: #1a1510; }
[data-theme="light"] .eh-hamburger { color: rgba(20,16,12,.75); }
[data-theme="light"] .eh-mobile-overlay { background: rgba(250,246,238,.97); }
[data-theme="light"] .eh-mobile-overlay a { color: #1a1510; }
[data-theme="light"] .eh-mob-group-toggle { color: #1a1510; }
[data-theme="light"] .eh-mobile-overlay .eh-mob-group-links a { color: rgba(20,16,12,.7); }
[data-theme="light"] .tn-ticker { background: #faf6ec; border-bottom-color: rgba(20,16,12,.12); }
[data-theme="light"] .tn-ticker-label { border-right-color: rgba(20,16,12,.12); }
[data-theme="light"] .tn-ticker-item { color: rgba(20,16,12,.65); }
[data-theme="light"] .tn-ticker-item:hover { color: #1a1510; }
[data-theme="light"] .eh-search-panel { background: rgba(250,246,238,.97); }
[data-theme="light"] .eh-search-input { background: rgba(20,16,12,.05); border-color: rgba(20,16,12,.18); color: #1a1510; }
[data-theme="light"] .eh-search-input::placeholder { color: rgba(20,16,12,.35); }
[data-theme="light"] .eh-search-close { color: rgba(20,16,12,.55); }
[data-theme="light"] .eh-search-close:hover { color: #1a1510; }
[data-theme="light"] .eh-search-results .search-hit { border-top-color: rgba(20,16,12,.08); }
[data-theme="light"] .eh-search-results .search-hit:hover { background: rgba(200,16,46,.06); }
[data-theme="light"] .eh-search-results .search-hit-title { color: #1a1510; }
[data-theme="light"] .eh-search-results .search-hit-empty { color: rgba(20,16,12,.45); }
[data-theme="light"] .ef-footer { background: #f1ebdd; border-top-color: rgba(20,16,12,.12); }
[data-theme="light"] .ef-tagline { color: rgba(20,16,12,.4); }
[data-theme="light"] .ef-social a { color: rgba(20,16,12,.7); }
[data-theme="light"] .ef-social a:hover, [data-theme="light"] .ef-social a:focus-visible { color: #1a1510; }
[data-theme="light"] .ef-col-heading { color: rgba(20,16,12,.45); }
[data-theme="light"] .ef-col nav a { color: rgba(20,16,12,.6); }
[data-theme="light"] .ef-col nav a:hover { color: #1a1510; }
[data-theme="light"] .ef-bottom { border-top-color: rgba(20,16,12,.08); }
[data-theme="light"] .ef-copy { color: rgba(20,16,12,.4); }
[data-theme="light"] .ef-bottom-links a { color: rgba(20,16,12,.4); }
[data-theme="light"] .ef-bottom-links a:hover { color: #1a1510; }
.show-subnav { position: sticky; top: var(--tnc-header-h, 64px); z-index: 80; }
.show-subnav-inner { display: flex; align-items: center; gap: 20px; padding: 11px clamp(1rem,4vw,2.5rem); background: var(--surface-2); border-bottom: 1px solid var(--border); font-family: "IBM Plex Sans", -apple-system, sans-serif; }
.show-subnav-brand { font-family: "Fraunces", serif; font-weight: 600; font-size: 20px; color: var(--on-black); }
.show-subnav-brand i { color: var(--red-text); font-style: normal; }
.show-subnav nav { display: flex; gap: 18px; font-size: 13px; flex-wrap: wrap; }
.show-subnav nav a { color: var(--muted-2); padding: 3px 0; border-bottom: 2px solid transparent; transition: color .2s; }
.show-subnav nav a:hover { color: var(--on-black); }
.show-subnav nav a.on { color: var(--on-black); border-bottom-color: #c8102e; }
[data-theme="light"] .ef-col nav a { color: rgba(var(--fg-rgb),.62); }
.eh-search-btn, .eh-hamburger, .eh-dropdown-toggle { min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
.eh-theme-btn:hover { color: var(--text); }
.eh-mob-group-links[hidden] { display: none; }
.show-subnav nav a { color: var(--muted-2); padding: 3px 0; border-bottom: 2px solid transparent; text-decoration: none; transition: color .2s; }
.show-subnav-brand span { color: var(--red-text); }
.show-subnav nav a { color: var(--muted-2); padding: 3px 0; text-decoration: none; transition: color .2s; }
.show-subnav nav a.is-active { color: var(--on-black); border-bottom: 2px solid #c8102e; }

/* == REBOOT 2026-09-10: SUBMIT A STORY, the one button in the chrome ========
   HEADERS.md change 2. Submit a story left the Firm dropdown and became the
   action, because it is what this site wants from a reader rather than a fact
   about the firm. The rules are service.tnaado.ca's, copied as they stand so
   the estate has one call to action and not two.

   Solid red on the dark chrome: #c8102e against #fff is 5.9:1, so the LABEL
   clears AA even though the same red as small text on the chrome surface would
   not, which is what --tnc-red-text exists for elsewhere. */
.eh-cta {
  display: inline-flex; align-items: center;
  padding: .52rem 1.05rem;
  background: var(--tnc-red);
  color: #fff;
  font-family: "IBM Plex Sans", sans-serif;
  font-size: .8rem; font-weight: 600; letter-spacing: .03em;
  white-space: nowrap;
  border: 1px solid var(--tnc-red);
  transition: background .2s ease, color .2s ease;
}
.eh-cta:hover, .eh-cta:focus-visible { background: transparent; color: var(--tnc-fg); outline: none; }
@media (max-width: 768px) { .eh-cta { display: none; } }

/* The mobile sheet's own call to action, since the bar's is hidden there. */
.eh-mobile-overlay .eh-mob-cta {
  margin-top: .6rem;
  padding: .7rem 1.4rem;
  background: var(--tnc-red);
  color: #fff;
  font-family: "IBM Plex Sans", sans-serif;
  font-size: 1rem; font-weight: 600; letter-spacing: .02em;
  border-bottom: 0;
}
.eh-mobile-overlay .eh-mob-cta:hover { color: #fff; }
