/* --- Skip link (WCAG SC 2.4.1) --- */
        .skip-link {
          position: absolute;
          top: -44px;
          left: 0;
          background: #000000;
          color: #ffffff;
          padding: 10px 16px;
          z-index: 99999;
          font-size: 1rem;
          font-weight: bold;
          text-decoration: underline;
          border-radius: 0 0 4px 0;
          transition: top 0.2s ease;
        }
        .skip-link:focus {
          top: 0;
          outline: 3px solid #ffffff;
          outline-offset: 2px;
        }

        /* --- Screen-reader-only utility (WCAG SC 1.1.1) --- */
        .sr-only {
          position: absolute !important;
          width: 1px !important;
          height: 1px !important;
          padding: 0 !important;
          margin: -1px !important;
          overflow: hidden !important;
          clip: rect(0, 0, 0, 0) !important;
          white-space: nowrap !important;
          border: 0 !important;
        }

        /* --- Contrast overrides for yellow skin (WCAG SC 1.4.3) ---
           Dark header passes 12:1 on white text. Gold accent border
           provides brand identity without contrast issues. */
        .skin-yellow .main-header .logo,
        .skin-yellow .main-header .logo:hover {
          background-color: #1a2a3a !important;
          color: #ffffff !important;
        }
        .skin-yellow .main-header .navbar {
          background-color: #1a2a3a !important;
          color: #ffffff !important;
        }
        .skin-yellow .main-sidebar {
          background-color: #2c2c2c !important;
        }
        .skin-yellow .sidebar-menu > li > a {
          color: #f0f0f0 !important;
        }
        .skin-yellow .sidebar-menu > li.active > a,
        .skin-yellow .sidebar-menu > li > a:hover {
          background-color: #7a5200 !important;
          color: #ffffff !important;
          border-left-color: #ffcc66 !important;
        }

        /* WCAG SC 2.4.7 — visible focus ring on every keyboard-focusable
           element. #main-content and #aria-announcer are excluded from
           the ring because they only receive focus programmatically
           (skip-link target + AR live region); a ring on either would
           confuse sighted users since neither is reachable by Tab. */
        a:focus,
        button:focus,
        input:focus,
        select:focus,
        textarea:focus,
        [tabindex]:focus:not(#main-content):not(#aria-announcer) {
          outline: 3px solid #005fcc !important;
          outline-offset: 2px !important;
        }

        /* Suppress focus ring on the programmatic skip-target + AR
           announcer. Both are script-focused only. */
        #main-content:focus,
        #aria-announcer:focus {
          outline: none !important;
        }

        /* Header Guided Tour button. */
        .header-tour-btn {
          display: inline-flex;
          align-items: center;
          background: rgba(255, 215, 0, 0.12);
          color: #ffd700;
          border: 1px solid rgba(255, 215, 0, 0.35);
          border-radius: 6px;
          padding: 6px 14px;
          font-size: 12px;
          font-weight: 600;
          cursor: pointer;
          transition: background 0.15s, border-color 0.15s;
        }
        .header-tour-btn:hover {
          background: rgba(255, 215, 0, 0.20);
          border-color: rgba(255, 215, 0, 0.55);
        }
        .header-tour-btn:focus-visible {
          outline: 2px solid #ffd700;
          outline-offset: 2px;
        }
        @media (max-width: 768px) {
          .header-tour-btn { display: none; }
        }

        /* --- Perceived-loading polish (2026-04-19) ---
           #3 fade-in + #6 layout-shift guards. Keeps the initial paint
           from looking "empty then pop" as content mounts. */

        /* Content-reveal helper — opt-in. Add class="content-reveal" to
           a container to have its contents fade + subtly rise on first
           render. Not applied globally to every shiny-bound-output
           because those re-render on filter changes and we don't want
           the fade replaying on every interaction. */
        .content-reveal {
          animation: content-reveal-in 0.22s ease-out both;
        }
        @keyframes content-reveal-in {
          from { opacity: 0; transform: translateY(4px); }
          to   { opacity: 1; transform: translateY(0); }
        }
        @media (prefers-reduced-motion: reduce) {
          .content-reveal { animation: none; }
        }

        /* Tab-switch fade was removed — it made every navigation feel */
        /* 250 ms slower even on fast hardware. The content-reveal opt-in */
        /* class (above) is still available for specific containers that */
        /* benefit from it. */

        /* CLS guard: reserve chart/table heights even before the
           skeleton CSS loads. Matches the inline <style> bootstrap in
           app.R. Listed here too so the full stylesheet re-confirms
           them once it arrives. */
        .chart-skeleton-plot  { min-height: 450px; }
        .chart-skeleton-map   { min-height: 600px; }
        .chart-skeleton-table { min-height: 240px; }

        /* Hero images + logos have intrinsic dimensions so nothing jumps. */
        .hero-logo        { width: 120px;  height: 32px;  max-width: none; }
        .hero-topbar .hero-logo,
        .hero-content img { height: auto; }

        /* --- Feedback widget (bottom of each PM page) --- */
        .feedback-widget {
          max-width: 640px;
          margin: 48px auto 32px;
          padding: 22px 28px;
          border: 1px solid #e5e7eb;
          border-radius: 12px;
          background: #fafbfc;
          text-align: center;
        }
        .feedback-prompt {
          display: flex; align-items: center; justify-content: center;
          gap: 18px;
          flex-wrap: wrap;
        }
        .feedback-prompt-label {
          font-size: 15px;
          font-weight: 500;
          color: #1a2a3a;
        }
        .feedback-buttons {
          display: flex; gap: 10px;
        }
        .btn.feedback-btn {
          width: 40px; height: 40px;
          padding: 0;
          border-radius: 50%;
          background: #fff;
          border: 1.5px solid #cbd5e1;
          color: #64748b;
          display: inline-flex; align-items: center; justify-content: center;
          cursor: pointer;
          transition: all 0.15s;
        }
        @media (hover: hover) and (pointer: fine) {
          .btn.feedback-btn:hover { transform: translateY(-1px); }
        }
        .btn.feedback-btn-up:hover {
          background: rgba(46, 204, 113, 0.12);
          border-color: #2ecc71; color: #1c7843;
        }
        .btn.feedback-btn-down:hover {
          background: rgba(231, 76, 60, 0.12);
          border-color: #e74c3c; color: #a02e1f;
        }
        .feedback-detail {
          text-align: left;
        }
        .feedback-comment {
          width: 100%;
          min-height: 72px;
          padding: 10px 14px;
          border: 1px solid #cbd5e1;
          border-radius: 6px;
          /* 16px below — iOS Safari auto-zooms the entire page on
             focus of any input/textarea/select with computed
             font-size < 16px. The page layout shifts and the user
             has to pinch-zoom-out to dismiss. 16px is the documented
             threshold and applies to every focusable form control. */
          font-size: 16px;
          font-family: inherit;
          resize: vertical;
          box-sizing: border-box;
        }
        .feedback-comment:focus {
          outline: 2px solid #005fcc;
          outline-offset: 1px;
        }
        .feedback-detail-actions {
          margin-top: 10px;
          display: flex; gap: 8px; justify-content: flex-end;
        }
        .feedback-thanks {
          display: flex; align-items: center; justify-content: center;
          gap: 10px;
          color: #1c7843;
          font-weight: 500;
          font-size: 15px;
        }
        /* Error variant: shown when both local TSV write and webhook
           POST failed. Different icon + amber palette so the user
           can tell at a glance their submission DIDN'T land. */
        .feedback-error {
          color: #a02e1f;
        }
        .feedback-error .feedback-retry {
          margin-left: 12px;
        }

        /* --- Command palette (⌘K / Ctrl+K) --- */
        .cmdk-overlay {
          position: fixed; inset: 0;
          z-index: 100000;
          display: flex; align-items: flex-start; justify-content: center;
          padding-top: 15vh;
        }
        .cmdk-backdrop {
          position: absolute; inset: 0;
          background: rgba(9, 42, 64, 0.55);
          backdrop-filter: blur(3px);
        }
        .cmdk-box {
          position: relative;
          width: min(640px, 94vw);
          max-height: 60vh;
          background: #ffffff;
          border-radius: 12px;
          box-shadow: 0 20px 60px rgba(0,0,0,0.25),
                      0 2px 8px rgba(0,0,0,0.15);
          overflow: hidden;
          display: flex; flex-direction: column;
        }
        .cmdk-input {
          width: 100%;
          padding: 18px 22px;
          border: 0;
          border-bottom: 1px solid #e5e7eb;
          font-size: 16px;
          font-weight: 500;
          color: #1a2a3a;
          outline: none;
          background: #fff;
        }
        .cmdk-input::placeholder { color: #9ca3af; }
        .cmdk-input:focus { outline: none; }
        .cmdk-list {
          list-style: none;
          margin: 0; padding: 6px 0;
          overflow-y: auto;
          max-height: calc(60vh - 100px);
        }
        .cmdk-item {
          display: flex; align-items: center; gap: 12px;
          padding: 10px 22px;
          cursor: pointer;
          color: #1a2a3a;
          font-size: 14px;
          user-select: none;
        }
        .cmdk-item-active { background: #fff3cd; }
        .cmdk-item-cat {
          font-size: 10.5px;
          font-weight: 700;
          text-transform: uppercase;
          letter-spacing: 0.06em;
          color: #ec971f;
          background: rgba(236, 151, 31, 0.12);
          padding: 3px 8px;
          border-radius: 4px;
          min-width: 60px;
          text-align: center;
          flex-shrink: 0;
        }
        .cmdk-item-label { flex: 1; }
        .cmdk-empty {
          padding: 18px 22px;
          color: #6b7280;
          font-style: italic;
          text-align: center;
        }
        .cmdk-hint {
          border-top: 1px solid #e5e7eb;
          padding: 8px 22px;
          font-size: 11.5px;
          color: #6b7280;
          background: #f9fafb;
        }
        .cmdk-hint kbd {
          display: inline-block;
          padding: 1px 6px;
          margin: 0 3px;
          background: #fff;
          border: 1px solid #d1d5db;
          border-radius: 3px;
          font-family: inherit;
          font-size: 11px;
          color: #374151;
        }
        @media (prefers-reduced-motion: reduce) {
          .cmdk-backdrop { backdrop-filter: none; }
        }

        /* --- Share-link toast --- */
        .link-toast {
          position: fixed;
          bottom: 32px;
          left: 50%;
          transform: translate(-50%, 16px);
          background: rgba(9, 42, 64, 0.95);
          color: #fff;
          padding: 10px 22px;
          border-radius: 24px;
          font-size: 14px;
          font-weight: 500;
          z-index: 99999;
          opacity: 0;
          pointer-events: none;
          transition: opacity 0.25s ease, transform 0.25s ease;
          box-shadow: 0 4px 14px rgba(0,0,0,0.25);
        }
        .link-toast.link-toast-show {
          opacity: 1;
          transform: translate(-50%, 0);
        }
        @media (prefers-reduced-motion: reduce) {
          .link-toast { transition: opacity 0.15s; transform: translate(-50%, 0); }
        }

        /* PM page: "Copy link" share button sits inline with "Back to Objective" */
        .pm-topbar .pm-share-btn {
          margin-left: auto;
        }
        .pm-share-btn > .fa { margin-right: 4px; }
        .pm-topbar {
          display: flex;
          align-items: center;
          gap: 12px;
        }

        /* --- Header breadcrumb (Variant 1: icons + chevrons + gold current)
           The header breadcrumb emits:
             <button class="bc-item">...</button>            -- clickable ancestor
             <span class="bc-item bc-current">...</span>     -- current page
             <span class="bc-sep"><i class="fa fa-chevron-right"></i></span>
           Each item contains <i class="fa fa-X"> followed by
           <span>label</span>. */
        .bc-item {
          display: inline-flex;
          align-items: center;
          gap: 6px;
          padding: 4px 10px;
          border-radius: 4px;
          color: rgba(255, 255, 255, 0.82);
          background: transparent;
          border: 0;
          cursor: pointer;
          font: inherit;
          line-height: 1;
          transition: background 0.15s, color 0.15s;
        }
        .bc-item:hover {
          background: rgba(255, 215, 0, 0.14);
          color: #fff;
          text-decoration: none;
        }
        .bc-item:focus-visible {
          outline: 2px solid #ffd700;
          outline-offset: 1px;
          background: rgba(255, 215, 0, 0.14);
          color: #fff;
        }
        .bc-item i {
          font-size: 12px;
          opacity: 0.75;
        }
        .bc-item.bc-current {
          color: #ffd700;
          font-weight: 600;
          background: rgba(255, 215, 0, 0.12);
          cursor: default;
        }
        .bc-item.bc-current:hover {
          background: rgba(255, 215, 0, 0.12);
        }
        .bc-item.bc-current i {
          opacity: 1;
          color: #ffd700;
        }
        .bc-sep {
          color: rgba(255, 255, 255, 0.3);
          margin: 0 2px;
          display: inline-flex;
          align-items: center;
        }
        .bc-sep i {
          font-size: 10px;
        }

        /* --- Loading indicator ---
           Shows when Shiny is busy, but with a 500 ms delay so quick
           operations don't flash a spinner. If the busy state clears
           before 500 ms, the overlay never becomes visible — users
           never see the spinner for operations that finish fast. */
        .shiny-busy .loading-overlay {
          display: flex;
          animation: overlay-delayed-show 0s linear 500ms forwards;
        }
        .loading-overlay {
          display: none;
          opacity: 0;
          position: fixed;
          top: 0; left: 0; right: 0; bottom: 0;
          background: rgba(9,42,64,0.3);
          z-index: 99998;
          align-items: center;
          justify-content: center;
        }
        @keyframes overlay-delayed-show {
          to { opacity: 1; }
        }
        .loading-spinner {
          width: 48px; height: 48px;
          border: 5px solid rgba(255,255,255,0.3);
          border-top-color: #ffd700;
          border-radius: 50%;
          animation: spin 0.8s linear infinite;
        }
        @keyframes spin { to { transform: rotate(360deg); } }
        @media (prefers-reduced-motion: reduce) {
          .loading-spinner { animation: none; border-top-color: #ffd700; opacity: 0.7; }
        }

/* ======================================================================
   Button system — 4 tiers (2026-04-19)
   ----------------------------------------------------------------------
   Tier 1 .btn-primary-cta   Hero / primary call-to-action (1 per page)
   Tier 2 .btn-content       Drill deeper into content
   Tier 3 .btn-nav           Back / prev / next navigation (outline)
   Tier 4 .btn-accent        Tutorials, Read More, ambient utilities
   ----------------------------------------------------------------------
   Selectors use `.btn.btn-*` so they beat Bootstrap 3's `.btn.btn-default`
   rule. Hierarchy cue: size + elevation + color saturation each drop one
   step per tier.
   ====================================================================== */

/* --- Tier 1: Primary CTA ------------------------------------------------- */
.btn.btn-primary-cta {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 30px;
  border: 0; border-radius: 8px;
  font-weight: 700; font-size: 15px; line-height: 1.2;
  color: #ffffff;
  background: linear-gradient(135deg, #ffb347 0%, #ec971f 100%);
  cursor: pointer;
  box-shadow: 0 6px 16px rgba(236,151,31,0.35);
  transition: transform 0.15s ease, box-shadow 0.2s ease, filter 0.2s ease;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .btn.btn-primary-cta:hover {
    color: #ffffff;
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(236,151,31,0.5);
    filter: brightness(1.05);
  }
}
.btn.btn-primary-cta:active {
  transform: translateY(0);
  box-shadow: 0 4px 10px rgba(236,151,31,0.4);
}

/* --- Tier 2: Content (drill deeper) ------------------------------------- */
.btn.btn-content {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 10px 22px;
  border: 0; border-radius: 6px;
  font-weight: 600; font-size: 14px; line-height: 1.2;
  color: #ffffff;
  background: #f0ad4e;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  transition: background 0.2s ease, transform 0.12s ease, box-shadow 0.2s ease;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .btn.btn-content:hover {
    color: #ffffff;
    background: #ec971f;
    transform: translateY(-1px);
    box-shadow: 0 3px 8px rgba(0,0,0,0.16);
  }
}
.btn.btn-content:active {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(0,0,0,0.14);
}

/* --- Tier 3: Navigation (outline) --------------------------------------- */
.btn.btn-nav {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 20px;
  border: 2px solid #ec971f; border-radius: 6px;
  font-weight: 600; font-size: 14px; line-height: 1.2;
  color: #ec971f;
  background: transparent;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
  text-decoration: none;
}
.btn.btn-nav:hover {
  background: #ec971f;
  color: #ffffff;
}
.btn.btn-nav:active {
  background: #d58512;
  color: #ffffff;
}

/* --- Tier 4: Accent (muted utility) ------------------------------------- */
.btn.btn-accent {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 16px;
  border: 1px solid #5eb8ff; border-radius: 6px;
  font-weight: 500; font-size: 13px; line-height: 1.2;
  color: #1d7cc6;
  background: transparent;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
  text-decoration: none;
}
.btn.btn-accent:hover {
  background: #e9f4ff;
  color: #1d7cc6;
}
.btn.btn-accent:active {
  background: #cfe5fb;
}

/* Shared focus ring (WCAG SC 2.4.7) */
.btn.btn-primary-cta:focus-visible,
.btn.btn-content:focus-visible,
.btn.btn-nav:focus-visible,
.btn.btn-accent:focus-visible {
  outline: 3px solid #005fcc;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .btn.btn-primary-cta, .btn.btn-content, .btn.btn-nav, .btn.btn-accent {
    transition: none;
  }
  .btn.btn-primary-cta:hover, .btn.btn-content:hover {
    transform: none;
  }
}

/* Back-compat aliases — any lingering `btn-unite-warning`/`btn-jelly-warning`
   resolves to Tier 3/2 respectively so old call sites don't break during
   the migration. Delete once every call site uses style = "nav"/"content". */
.btn.btn-unite-warning { composes: none; }
.btn.btn-unite-warning,
.btn.btn-unite-warning:hover,
.btn.btn-unite-warning:active,
.btn.btn-unite-warning:focus-visible {
  all: unset;
}
.btn.btn-unite-warning { display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 20px; border: 2px solid #ec971f; border-radius: 6px;
  font-weight: 600; font-size: 14px; color: #ec971f; background: transparent;
  cursor: pointer; text-decoration: none;
  transition: background 0.2s, color 0.2s; }
.btn.btn-unite-warning:hover { background: #ec971f; color: #fff; }
.btn.btn-jelly-warning { display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; padding: 10px 22px; border: 0; border-radius: 6px;
  font-weight: 600; font-size: 14px; color: #fff; background: #f0ad4e;
  cursor: pointer; text-decoration: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  transition: background 0.2s, transform 0.12s; }
@media (hover: hover) and (pointer: fine) {
  .btn.btn-jelly-warning:hover { background: #ec971f; transform: translateY(-1px);
    color: #fff; }
}
