/* ============================================================
   GLOBAL NAV + MENU
   - Topbar: logo (left) + burger (right), sticky.
   - Menu : right-side yellow ticket panel, drops from top
     with a bounce. Locked v8 design.
============================================================ */

/* ============================================================
   TOPBAR — sticky at top, doesn't hide on scroll.

   § POST-AUDIT BUG 22 — Pass 7 Round A.4 — note on positioning.
   position: sticky establishes a positioning context for
   absolute children, so the DEMO MODE pill (absolute-centered
   in demo state) anchors to the topbar without needing an
   extra position:relative declaration.
============================================================ */
.nbs-topbar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--cream);
  padding: 10px 40px 10px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.nbs-logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  line-height: 1;
}
.nbs-logo img {
  display: block;
  height: 60px;
  width: auto;
}
@media (max-width: 480px) {
  .nbs-logo img { height: 46px; }
}

/* ============================================================
   TOPBAR SKELETON — placeholder div used by include.js as the
   mount point for the nav partial. Matches the real .nbs-topbar
   slot exactly so the swap is visually invisible. Cream
   background covers any flash before the SVG logo paints.
============================================================ */
.nbs-topbar-skeleton {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--cream);
  min-height: 80px;
}
@media (max-width: 480px) {
  .nbs-topbar-skeleton { min-height: 66px; }
}

/* ============================================================
   NAV LINKS — "New brief" CTA + "Leaked briefs" bait. Sit
   between the logo (left) and the burger (right) in the
   auth'd topbar. Hidden on mobile in favor of the menu drawer
   for bait; CTA shrinks but stays visible at all viewports.
============================================================ */
.nbs-nav-right {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
  margin-right: 10px;
}

/* Base nav link — used by the bait. Inter 14, ink color. No
   default hover lift; lift is reserved for the chunky CTA. */
.nbs-nav-link {
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.2px;
  text-decoration: none;
  color: var(--ink);
  padding: 8px 14px;
  border-radius: 999px;
  white-space: nowrap;
  transition: color 0.15s ease;
}

/* Primary CTA — same chunky-pill button-language as the .back-cta
   "Take it" button on result.html, recolored purple-on-white as
   the primary variant. Same dimensions desktop AND mobile per
   the consistency rule. Phase 2: this is the "start a new brief"
   action across every auth'd page. */
.nbs-nav-link.is-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 1px;
  /* text-indent nudges the text rightward to compensate for the
     trailing letter-spacing offset. 2px lands at true optical
     center (1px undershoots; this is calibrated by eye). */
  text-indent: 2px;
  text-transform: uppercase;
  background: var(--purple);
  color: #ffffff;
  /* Asymmetric vertical padding (13/11 instead of 12/12) corrects
     for Inter 800 uppercase optical center sitting slightly above
     the geometric center of the line box. Looks "level" by eye. */
  padding: 13px 22px 11px;
  border-radius: 999px;
  border: 2.5px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  line-height: 1;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.nbs-nav-link.is-cta:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--ink);
  color: #ffffff;
  background: var(--purple);
}

/* Bait link — plain text in the topbar, styled like the menu's
   settings rows (Edit profile / Change donation / Log out): quiet
   Inter, ink color, no decoration. The off-pattern feeling comes
   from the COPY, not the styling. Hover turns purple, no transform
   — a lift would conflict with the chunky CTA's offset hover.

   Bait stays INK in every state except hover:
   - :visited — browser default would force purple; we override.
   - .is-active — nav.js adds this when body[data-page="arcade"]
     matches; the generic .is-active rule below would turn it
     purple, but the bait is a one-shot prank, not a destination
     to highlight. Keep ink.
   The combined selector below wins over both. */
.nbs-nav-link.is-bait,
.nbs-nav-link.is-bait:visited,
.nbs-nav-link.is-bait.is-active {
  color: var(--ink);
  padding: 8px 4px;
}
.nbs-nav-link.is-bait:hover {
  color: var(--purple);
}

/* Mobile: bait drops out of the topbar (drawer no longer carries
   it either — Option A: arcade has no path on mobile until the
   real game ships). CTA stays at full size for cross-device
   consistency. */
@media (max-width: 640px) {
  .nbs-nav-right .is-bait { display: none; }
  .nbs-nav-right { gap: 10px; margin-right: 6px; }
}

/* Active-link highlight — set by nav.js based on body[data-page]. */
.nbs-nav-link.is-active {
  color: var(--purple);
}

/* ============================================================
   AUTH-AWARE VISIBILITY
   shared/nav.js sets body[data-auth="in"|"out"] on boot.
   Elements with .nbs-auth-only are shown ONLY when auth'd.
   The Leaked briefs link has NO marker — it's visible in both
   states. Single nav partial, dual behavior.

   Default (no data-auth yet) keeps auth-only hidden — prevents
   a flash of "logged in" chrome on initial paint for guests.

   Specific element overrides re-establish each element's
   natural display when shown:
     - .is-cta is an <a> styled with inline-flex (button-like)
     - .nbs-toggle is a <button>, block-ish flex child
============================================================ */
.nbs-auth-only { display: none; }
body[data-auth="in"] a.nbs-auth-only.is-cta { display: inline-flex; }
body[data-auth="in"] button.nbs-auth-only.nbs-toggle { display: block; }

/* ============================================================
   BURGER ↔ X — chunky bars purple/lime/pink, morphs to X
   (purple+pink diagonals).
============================================================ */
.nbs-toggle {
  position: relative;
  width: 36px;
  height: 36px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
}
/* When the menu is open, hide the burger — the in-ticket close
   button (.nbs-menu-close) takes over as the way to dismiss. */
body.nbs-menu-open .nbs-toggle { visibility: hidden; }
/* § PASS 6 STEP 5 — §1.C lock background scroll while the menu
   is open. Previously the mouse wheel scrolled the page underneath
   and the ticket drifted off-screen. Pattern consistent with
   body.pc-locked (register passcode overlay) and the per-overlay
   body.style.overflow='hidden' pattern used by forgot/su-delete/
   ref-overlay. Class is added by shared/menu.js openMenu() and
   removed by closeMenu() — see those two functions for the
   lifecycle owner. */
body.nbs-menu-open { overflow: hidden; }
.nbs-toggle-bar {
  position: absolute;
  left: 4px;
  width: 28px;
  height: 5px;
  border-radius: 999px;
  transform-origin: 50% 50%;
  transition:
    transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
    top       0.32s cubic-bezier(0.4, 0, 0.2, 1),
    opacity   0.18s ease;
}
.nbs-toggle-bar:nth-child(1) { top: 6px;  background: var(--purple); }
.nbs-toggle-bar:nth-child(2) { top: 16px; background: var(--lime);   }
.nbs-toggle-bar:nth-child(3) { top: 26px; background: var(--pink);   }
/* Hover: rotate colors down — purple→lime→pink→purple */
.nbs-toggle:not(.is-open):hover .nbs-toggle-bar:nth-child(1) { background: var(--pink);   }
.nbs-toggle:not(.is-open):hover .nbs-toggle-bar:nth-child(2) { background: var(--purple); }
.nbs-toggle:not(.is-open):hover .nbs-toggle-bar:nth-child(3) { background: var(--lime);   }
.nbs-toggle.is-open .nbs-toggle-bar:nth-child(1) { top: 16px; transform: rotate(45deg);  background: var(--purple); }
.nbs-toggle.is-open .nbs-toggle-bar:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nbs-toggle.is-open .nbs-toggle-bar:nth-child(3) { top: 16px; transform: rotate(-45deg); background: var(--pink); }

/* ============================================================
   SCRIM
============================================================ */
.nbs-scrim {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.32);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease;
  z-index: 199;
}
.nbs-scrim.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* ============================================================
   THE TICKET — drops from top with bounce, scalloped both ends
============================================================ */
.nbs-menu {
  position: fixed;
  top: 0;
  right: 20px;
  width: 440px;
  max-width: calc(100vw - 20px);
  height: 84vh;
  background: #FCFF00;
  color: var(--ink);
  z-index: 200;

  transform: translateY(-100%);
  transition: transform 0.46s cubic-bezier(0.34, 1.56, 0.64, 1);

  -webkit-mask-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='14' viewBox='0 0 28 14'><polygon points='0,14 14,0 28,14' fill='black'/></svg>"),
    linear-gradient(black, black),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='14' viewBox='0 0 28 14'><polygon points='0,0 14,14 28,0' fill='black'/></svg>");
  -webkit-mask-position: top, center, bottom;
  -webkit-mask-size: 28px 14px, 100% calc(100% - 28px), 28px 14px;
  -webkit-mask-repeat: repeat-x, no-repeat, repeat-x;
  mask-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='14' viewBox='0 0 28 14'><polygon points='0,14 14,0 28,14' fill='black'/></svg>"),
    linear-gradient(black, black),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='14' viewBox='0 0 28 14'><polygon points='0,0 14,14 28,0' fill='black'/></svg>");
  mask-position: top, center, bottom;
  mask-size: 28px 14px, 100% calc(100% - 28px), 28px 14px;
  mask-repeat: repeat-x, no-repeat, repeat-x;

  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.nbs-menu.is-open { transform: translateY(0); }

@media (max-width: 480px) {
  .nbs-menu { right: 0; width: 100vw; max-width: 100vw; }
}

/* ============================================================
   MENU BODY
============================================================ */
/* In-ticket close button — always visible when menu is open,
   sits inside the ticket so it's automatically on top of all
   ticket content. Two spans rendered as crossed diagonal bars
   form the X (purple + pink to match the burger morph). */
.nbs-menu-close {
  position: absolute;
  top: 22px;
  right: 18px;
  width: 36px;
  height: 36px;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  z-index: 5;
}
.nbs-menu-close span {
  position: absolute;
  top: 50%;
  left: 4px;
  width: 28px;
  height: 5px;
  border-radius: 999px;
  transform-origin: 50% 50%;
}
.nbs-menu-close span:nth-child(1) { background: var(--purple); transform: translateY(-50%) rotate( 45deg); }
.nbs-menu-close span:nth-child(2) { background: var(--pink);   transform: translateY(-50%) rotate(-45deg); }
/* Hover: swap the two diagonal colors */
.nbs-menu-close:hover span:nth-child(1) { background: var(--pink); }
.nbs-menu-close:hover span:nth-child(2) { background: var(--purple); }

.nbs-menu-body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding-top: 38px;
  padding-bottom: 32px;
}
.nbs-section {
  padding: 32px 26px 36px;
  position: relative;
}
.nbs-section::after {
  content: '';
  position: absolute;
  left: 26px; right: 26px; bottom: 0;
  background: var(--ink);
}
.nbs-section.div-thick::after { height: 3.5px; }
.nbs-section.div-thin::after  { height: 1.5px; }
.nbs-section.div-none::after  { display: none; }

.nbs-menu [hidden] { display: none !important; }

/* ============================================================
   RECENT BRIEFS
============================================================ */
.nbs-recents { display: flex; flex-direction: column; }

.nbs-recent-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px dashed rgba(10, 10, 10, 0.35);
  text-decoration: none;
  color: var(--ink);
  transition: padding-left 0.14s ease, opacity 0.14s ease;
}
.nbs-recent-row:hover { padding-left: 6px; }
.nbs-recent-row:first-of-type { padding-top: 4px; }
.nbs-recent-row:last-of-type  { border-bottom: 0; padding-bottom: 4px; }

/* § POST-AUDIT BUG 43 — Pass 7 Round B Naique revision 2.
   § POST-AUDIT BUG 45 — Pass 7 Round B Naique revision 3.
   Lorem ipsum placeholder rows: visually present at full
   opacity, but no hover lift and no click. Honest visual
   signal that these are decorative ballast (real entries
   land in Phase 2). Opacity removed per Portuga's call —
   the PLACEHOLDER pill is the lone "this is decorative" cue. */
.nbs-recent-row.is-placeholder {
  pointer-events: none;
  cursor: default;
}
.nbs-recent-row.is-placeholder:hover { padding-left: 0; }
.nbs-recent-pill {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 6px;
  border: 1px solid rgba(10, 10, 10, 0.4);
  border-radius: 3px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0.7;
  vertical-align: middle;
}

.nbs-recent-text {
  display: flex; flex-direction: column;
  gap: 4px; min-width: 0; flex: 1;
}
.nbs-recent-name {
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 22px; letter-spacing: 0.5px;
  line-height: 1; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nbs-recent-meta {
  font-family: 'Inter', sans-serif;
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--ink); opacity: 0.65; line-height: 1.3;
}
.nbs-recent-cut {
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 22px; letter-spacing: 0.5px;
  line-height: 1; color: var(--ink); flex-shrink: 0;
}

.nbs-empty { padding: 4px 0 0; }
.nbs-empty[hidden] { display: none; }
/* § PASS 52 CONCERN 1 — defensive cricket-flash kill. Pass 51's
   is-loading hide relied solely on [hidden] attribute toggling
   from JS, which can race with menu-open animations and CSS state
   transitions. These rules force-hide the empty/recents/CTA wrap
   during the loading interim regardless of [hidden] state — the
   CRICKETS / list / "Add a brief" CTA cannot leak even if a
   timing edge case strips the [hidden] attribute prematurely.
   On fetch resolve menu.js removes .is-loading and the correct
   state's [hidden]=false reveals it. Demo path is byte-identical:
   willFetchReal=false in renderMenu → .is-loading never added. */
.nbs-section.is-loading .nbs-empty,
.nbs-section.is-loading .nbs-recents,
.nbs-section.is-loading .nbs-see-all-wrap {
  display: none !important;
}
.nbs-empty-title {
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal;
  color: var(--ink);
  margin: 0;
  line-height: 0.95;
  text-transform: uppercase;
  font-size: 56px;
  letter-spacing: 1.5px;
}
.nbs-section.is-empty .nbs-see-all-wrap { margin-top: 8px; }

.nbs-see-all-wrap { margin-top: 18px; display: flex; }
.nbs-see-all {
  display: inline-block;
  padding: 11px 22px;
  background: var(--cream);
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  box-shadow: 4px 4px 0 var(--ink);
  font-family: 'Inter', sans-serif;
  font-weight: 800; font-size: 12px;
  letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--ink); text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  line-height: 1;
}
.nbs-see-all:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--ink);
}

/* ============================================================
   STATS
============================================================ */
.nbs-stats { display: flex; flex-direction: column; gap: 24px; }
.nbs-bs-block { display: flex; flex-direction: column; gap: 10px; }

.nbs-bar {
  position: relative;
  width: 100%;
  aspect-ratio: 229 / 33;
  background: url('../assets/icons/poo_bar_timeline.png') center/contain no-repeat;
}
.nbs-bar-track {
  position: absolute;
  left: 4.4%; top: 18%;
  width: 92.9%; height: 64%;
  overflow: hidden;
}
.nbs-bar-fill {
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 0%;
  background: var(--cream);
  transition: width 2.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.nbs-bar-text {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  gap: 8px;
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 19px;
  letter-spacing: 1.4px; text-transform: uppercase;
  line-height: 1; white-space: nowrap;
  z-index: 2; pointer-events: none;
  transform: translateY(2px);
  color: var(--cream);
}
.nbs-bar-text-over {
  color: #7E380C;
  clip-path: inset(0 0 0 calc(100% - var(--cut, 0%)));
  transition: clip-path 2.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.nbs-stats-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.nbs-stat { display: flex; flex-direction: column; gap: 4px; }
.nbs-stat-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.nbs-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--ink);
  flex-shrink: 0;
  /* -5px nudge for optical centering — Sugra numbers carry visual
     weight low, so the icon needs to ride a touch higher to feel level. */
  transform: translateY(-5px);
}
.nbs-stat-icon svg { width: 100%; height: 100%; display: block; }
.nbs-stat-num {
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 36px;
  letter-spacing: 0.5px; line-height: 1;
  color: var(--ink);
}
.nbs-stat-label {
  font-family: 'Inter', sans-serif;
  font-weight: 700; font-size: 11px;
  letter-spacing: 1px; text-transform: uppercase;
  color: var(--ink); opacity: 0.65;
}

/* ============================================================
   PROFILE
============================================================ */
.nbs-profile-head {
  display: flex; align-items: center;
  gap: 14px; margin-bottom: 22px;
}
.nbs-profile-avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--purple);
  border: 2.5px solid var(--ink);
  display: flex; align-items: center; justify-content: center;
  color: var(--cream);
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 26px;
  flex-shrink: 0;
  overflow: hidden;
}
/* When user has picked a poo avatar (set by menu.js as .has-poo
   + an inner <img> + a data-poo attribute), the image fills the
   circular frame (object-fit: cover via the inline style on the
   img element) and the ink border is replaced by a brand color
   matched to the chosen poo. Cream background stays as a subtle
   ground in case the PNG has any transparency at edges. */
.nbs-profile-avatar.has-poo {
  background: var(--cream);
  padding: 0;
  /* Slightly thicker ring so the color reads at 56px. The .has-poo
     state overrides .nbs-profile-avatar's 2.5px ink default. */
  border-width: 3px;
  border-style: solid;
}
.nbs-profile-avatar[data-poo="1"] { border-color: var(--purple); }
.nbs-profile-avatar[data-poo="2"] { border-color: var(--pink); }
.nbs-profile-avatar[data-poo="3"] { border-color: var(--yellow); }
.nbs-profile-avatar[data-poo="4"] { border-color: var(--lime); }
.nbs-profile-avatar[data-poo="5"] { border-color: var(--peach); }
.nbs-profile-id {
  display: flex; flex-direction: column;
  gap: 6px; min-width: 0; flex: 1;
}
.nbs-profile-name {
  font-family: 'Sugra', 'Archivo Black', 'Impact', sans-serif;
  font-weight: normal; font-size: 24px;
  letter-spacing: 0.5px; line-height: 1;
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nbs-profile-tier {
  font-family: 'Inter', sans-serif;
  font-weight: 800; font-size: 11px;
  letter-spacing: 1px; text-transform: uppercase;
  color: var(--ink); opacity: 0.7;
  line-height: 1;
}

.nbs-settings { display: flex; flex-direction: column; }
.nbs-setting-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px dashed rgba(10, 10, 10, 0.35);
  text-decoration: none;
  color: var(--ink);
  font-family: 'Inter', sans-serif;
  font-size: 14px; font-weight: 700;
  letter-spacing: 0.3px;
  transition: padding-left 0.14s ease;
}
.nbs-setting-row:hover { padding-left: 6px; }
.nbs-setting-row:first-of-type { padding-top: 4px; }
.nbs-setting-row:last-of-type  { border-bottom: 0; padding-bottom: 4px; }
.nbs-setting-row .chev {
  font-family: 'Inter', sans-serif;
  font-weight: 700; font-size: 18px;
  line-height: 1; opacity: 0.45;
}

@media (max-width: 720px) {
  .nbs-topbar { padding: 12px 24px; }
}

/* ============================================================
   § POST-AUDIT BUG 11 — Pass 7 Round A.2 — DEMO-MODE NAV RULES.

   Activated by body.is-demo (set in shared/nav.js when
   NoBS.demos.isActive() returns true). Affects every page that
   includes /partials/nav.html — single source of truth.

   Visual logic:
     - Topbar background flips from cream to light pink (#FBCFE8).
       Loud-enough signal that the user CAN'T mistake this for the
       real product. Not so saturated that 5-minute walkthroughs
       fatigue the eye.
     - DEMO MODE pill (center) appears: hot pink ground, cream text,
       ink border + ink shadow. Status badge style.
     - Exit demo button (right) appears: cream pill, ink border,
       ink shadow, matches the canonical .back-cta family.
     - New brief CTA + burger HIDDEN (auth-aware buttons don't make
       sense inside a frozen demo flow).

   Default (no .is-demo) state: every demo-only element is
   display:none. Every non-demo element behaves as before.

   Phase 2: same rules; the React port reads useDemoSession()
   and applies the .is-demo class to a top-level wrapper instead
   of body, but the CSS targets remain identical.
============================================================ */

/* Demo-only / not-demo-only visibility primitives.
   Used by demo-pill, demo-exit, and the "swap" of New brief/burger.

   § POST-AUDIT BUG 15 — Pass 7 Round A.3.
   Specificity fix: the hide rule on .nbs-demo-only originally read
   `.nbs-demo-only { display: none }` (specificity 0,1,0) which LOST
   to `.nbs-nav-link.is-cta { display: inline-flex }` (0,2,0). Net
   effect: Exit demo button stayed visible after session ended (when
   body.is-demo class was removed). Rewriting the hide selector with
   :not(.is-demo) on body lifts the specificity to (0,2,1), beating
   .is-cta cleanly. The show rule stays as before. */
body:not(.is-demo) .nbs-demo-only { display: none !important; }
body.is-demo       .nbs-demo-only { display: inline-flex; }
body.is-demo .nbs-not-demo-only { display: none !important; }

/* Topbar background flips to light pink inside demo.
   § BUG 15 — color is #FFD9EE per spec, no bottom border (cleaner
   visual continuity between topbar and menu, both pink grounds). */
body.is-demo .nbs-topbar {
  background: #FFD9EE;
}

/* DEMO MODE pill — center of topbar, BOTH AXES.
   § POST-AUDIT BUG 22 — Pass 7 Round A.4.
   Switched from flex-grow centering to absolute positioning so
   the pill is perfectly centered horizontally AND vertically
   regardless of:
     - logo width (varies with breakpoint)
     - right-side content width (Leaked briefs + Exit demo + burger)
     - topbar vertical padding
   The wrapper now uses position:absolute + transform-center,
   which anchors to the .nbs-topbar (sticky establishes a
   positioning context). pointer-events:none on the slot lets
   clicks pass through to whatever's underneath (logo etc.),
   while the pill itself stays a static label.

   Hidden by default (no demo session). Shown when body.is-demo. */
.nbs-demo-pill-slot {
  display: none;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 1;
}
body.is-demo .nbs-demo-pill-slot { display: block; }

.nbs-demo-pill {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  background: #EC4899;
  color: #FCFAF7;
  padding: 7px 14px 5px;
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  box-shadow: 3px 3px 0 var(--ink);
  line-height: 1;
  white-space: nowrap;
}

/* Exit demo button — replaces New brief inside demo.
   Uses the existing .nbs-nav-link.is-cta sizing/positioning so
   it sits exactly where the New brief CTA usually sits, but
   overrides the visual to cream-pill (the .back-cta family).

   § POST-AUDIT BUG 15 — Pass 7 Round A.3.
   Padding now MATCHES .nbs-nav-link.is-cta exactly (13px 22px 11px
   + text-indent 2px) so the Exit demo pill has the same vertical
   height + horizontal weight as the New brief CTA it replaces.
   Previously 10px 18px which read visibly smaller. */
.nbs-nav-link.is-demo-exit {
  background: var(--cream);
  color: var(--ink);
  border: 2.5px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  border-radius: 999px;
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 1px;
  text-indent: 2px;
  text-transform: uppercase;
  padding: 13px 22px 11px;
  text-decoration: none;
  line-height: 1;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.nbs-nav-link.is-demo-exit:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--ink);
}

/* § POST-AUDIT BUG 15 — Burger visible inside demo mode even
   though the user is technically logged-out. The auth-only show
   rule on line 177 fires only on body[data-auth="in"], which
   doesn't apply to demo visitors. This rule restores the burger
   so the demo's tailored menu (Poo Glitter persona, sessionStorage
   stats, hidden settings rows) is reachable. */
body.is-demo button.nbs-toggle {
  display: block;
}

/* Mobile tuning — DEMO MODE pill shrinks but stays visible.
   The right-side Exit demo abbreviates is handled by JS at narrow
   widths if needed (Phase 1: same label everywhere — "Exit demo"
   is short enough not to need truncation at 320px+). */
@media (max-width: 720px) {
  .nbs-demo-pill {
    font-size: 10px;
    letter-spacing: 1.5px;
    padding: 6px 10px 4px;
  }
  .nbs-nav-link.is-demo-exit {
    font-size: 11px;
    padding: 11px 16px 9px;
  }
}
@media (max-width: 480px) {
  /* At very narrow widths, the DEMO MODE pill can collide with
     logo/exit. Center slot's flex:1 0 0 already lets it shrink;
     letter-spacing tightens to keep the word readable. */
  .nbs-demo-pill {
    letter-spacing: 1px;
    padding: 5px 8px 3px;
  }
}

/* ============================================================
   § POST-AUDIT BUG 12 — Pass 7 Round A.2 — DEMO-MODE MENU PINK.

   The menu panel flips from yellow (#FCFF00) to the same light
   pink as the demo topbar (#FBCFE8) when body.is-demo. This
   preserves visual continuity: the topbar is pink, the menu
   slides out of the topbar and inherits the same ground.

   Internal contrast review:
     - All menu text is var(--ink) → high contrast on light pink
       (~13:1, well above WCAG AAA)
     - Dashed dividers at rgba(10,10,10,0.35) → still visible
     - .nbs-recent-cut, .nbs-stat-num, .nbs-recent-name → all ink
       on pink, no change needed
     - BS bar uses image background — independent of menu ground
     - .nbs-bar-text "BS CUT IN" cream text is over the brown bar
       fill image, not the menu ground — unaffected
     - .nbs-see-all button (cream pill) reads fine on pink
     - .nbs-setting-row hover state (padding-left shift) works
       identically — no color change to the rows themselves

   Profile avatar:
     - Real users picking poo:1..5 get colored borders matched to
       their avatar. Demo persona ("poo:demo") gets a CREAM border
       so the avatar stands out on pink and is visually distinct
       from the 5 real avatars.

   Scrim:
     - Stays the same (dark backdrop behind the menu). Affects
       the page behind the menu, not the menu itself.
============================================================ */
body.is-demo .nbs-menu {
  background: #FFD9EE;
}

/* Demo persona avatar — cream border, ink ring. Reads as
   "special" persona without competing with the 5 real avatars'
   palette colors. The .has-poo selector still applies its
   cream-background-for-PNG-transparency rule. */
/* § POST-AUDIT BUG 23 — Pass 7 Round A.4.
   Demo persona avatar now uses PINK border (was ink) to match the
   demo-mode visual language (pink topbar, pink menu, pink accents).
   Accepts both 'glitter' (canonical, current) and 'demo' (legacy,
   kept for one-release backward compat) as data-poo values. The
   .has-poo selector still applies its cream-background-for-PNG-
   transparency rule. */
body.is-demo .nbs-profile-avatar[data-poo="glitter"],
body.is-demo .nbs-profile-avatar[data-poo="demo"] {
  border-color: var(--pink);
  background: var(--cream);
}

/* § POST-AUDIT BUG 33 — Pass 7 Round A.4.
   Demo mode: hide the "Delete this brief" button on All Briefs
   cards. The 4 demo cards are a frozen curated reference; allowing
   deletion would either break the demo (delete one, page renders
   3) or be a confusing no-op. Hidden via CSS so the markup stays
   identical to the real-user path. */
body.is-demo .ab-card-delete {
  display: none !important;
}

/* § POST-AUDIT BUG 24 — Pass 7 Round A.4.
   Demo LOBBY (pages/demo.html, body data-page="demo") must NEVER
   show the burger, even if sessionStorage carries a demo flag from
   a previous start (e.g. user clicks Start the demo, lands in demo,
   browser-backs to the lobby). The lobby is an entry surface, not
   a content surface — its menu would show "Poo Glitter" persona
   which is incongruent here (you haven't started yet). Specificity
   of [data-page] selector + !important guarantees this wins over
   the demo-burger-show rule above. */
body[data-page="demo"] .nbs-toggle {
  display: none !important;
}
