/* =========================================================================
   CuratedBets — mobile navigation + shared mobile shell guards.

   Loaded by BOTH public surfaces: the shared premium base
   (templates/public_base.html) and the standalone homepage
   (templates/landing.html). It is a separate sheet on purpose:

     - public-brand.css is loaded by the base but NOT by the homepage;
     - home.css is loaded by the homepage but NOT by the base;
     - curatedbets-theme.css is the authoritative design handoff, shipped
       verbatim, and is not the place for product chrome.

   So one shared file is the only way to state these rules ONCE. It loads last
   on both pages, which is what lets the small number of deliberate overrides
   below win without !important.

   BREAKPOINT CONTRACT — 1010px (history below). The rail/burger parity
   switch itself now sits at 1080px; see the MOBILE BREAKPOINT block.
   public-brand.css, home.css and curatedbets-theme.css each already hide
   ``.cb-nav-links`` on small screens (at 1010px, 1010px and 767px). Nothing
   replaced it, so every viewport under 1010px lost the entire primary menu.
   This sheet introduces the replacement and pins it to the SAME 1010px line,
   so the desktop rail and the mobile trigger are never both visible and,
   more importantly, never both absent.

   Desktop (>=1011px) is deliberately untouched: every rule below is either
   inside ``@media (max-width:1010px)`` or targets an element that did not
   previously exist.
   ========================================================================= */

/* ---- Mobile trigger ---------------------------------------------------- */
/* Hidden by default so the desktop nav is byte-for-byte what it was. */
.cb-nav-burger{display:none;}

/* The desktop-only account/notification popovers. Same story: no effect until
   the mobile breakpoint takes over below. */
.cb-nav-desk-only{display:inline-flex;}

/* ---- The drawer itself ------------------------------------------------- */
/* Rendered on every page but inert until opened. ``hidden`` is the resting
   state in the markup; this rule makes sure a stylesheet can never win over
   it and flash the panel during load. */
.cb-mnav[hidden]{display:none;}

.cb-mnav{
  position:fixed; inset:0; z-index:200;
  display:flex; justify-content:flex-end;
  background:rgba(4,12,22,0.62);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}

/* The sheet. ``min(420px,100%)`` means it is a side sheet on a tablet and a
   full-bleed sheet on a phone — no 320px device gets a cramped 420px panel
   pushed off-screen. */
.cb-mnav-panel{
  position:relative;
  display:flex; flex-direction:column;
  width:min(420px, 100%);
  max-width:100%;
  height:100%;
  background:linear-gradient(168deg, #0A1F33 0%, #061522 62%, #0A1F33 100%);
  border-left:1px solid rgba(255,255,255,0.10);
  box-shadow:-24px 0 60px -20px rgba(0,0,0,0.6);
  /* Explicit ink for the panel. home.css declares `.cb-home a{color:inherit}`,
     so anything inheriting here must inherit a DARK-zone colour, never the
     light board's. */
  color:#E6F0FB;
  /* Long-device safe areas: the notch/status bar at the top and the home
     indicator at the bottom. Falls back to 0 where env() is unsupported. */
  padding-top:env(safe-area-inset-top, 0px);
  padding-bottom:env(safe-area-inset-bottom, 0px);
  padding-right:env(safe-area-inset-right, 0px);
}

/* Top bar of the sheet: brand + close, on the same 68px rhythm as the nav it
   replaces, so opening the menu does not feel like leaving the site. */
.cb-mnav-top{
  flex:none;
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; height:var(--nav-h, 68px); padding:0 16px;
  border-bottom:1px solid rgba(255,255,255,0.10);
}
.cb-mnav-top .cb-nav-brand img{height:34px; width:auto; display:block;}

.cb-mnav-close{
  width:44px; height:44px; flex:none;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:14px; border:1px solid rgba(255,255,255,0.16);
  background:rgba(255,255,255,0.06); color:#E6F0FB;
  font-size:20px; padding:0; cursor:pointer; font-family:inherit;
  transition:background 160ms ease, border-color 160ms ease;
}
.cb-mnav-close:hover{background:rgba(255,255,255,0.12);}
.cb-mnav-close:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}

/* The scroll region. This is what satisfies "allow normal scrolling if menu
   content exceeds viewport height" — the sheet itself never scrolls, its
   contents do, so the close button stays pinned and reachable. */
.cb-mnav-scroll{
  flex:1 1 auto; min-height:0;
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
  padding:18px 16px 28px;
}

/* ---- Sport rail inside the drawer -------------------------------------- */
.cb-mnav-sportrail{
  display:grid; grid-template-columns:1fr 1fr; gap:4px;
  padding:4px; margin:0 0 18px;
  border-radius:999px; background:rgba(255,255,255,0.07);
  border:1px solid rgba(255,255,255,0.12);
}
.cb-mnav .cb-mnav-sport{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:40px; border-radius:999px;
  font-family:var(--font-display, inherit); font-weight:700; font-size:14px;
  letter-spacing:.04em; text-transform:uppercase;
  color:#9FBCD8; text-decoration:none;
}
.cb-mnav .cb-mnav-sport.active{background:#E9F2FC; color:#061522;}
.cb-mnav .cb-mnav-sport:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}

/* ---- Destination rows -------------------------------------------------- */
.cb-mnav-links{display:flex; flex-direction:column; gap:4px;}

/* 52px rows: comfortably above the 44px minimum tap target the theme already
   declares in --tap-min, with room for the label to breathe. */
.cb-mnav .cb-mnav-link{
  position:relative;
  display:flex; align-items:center; gap:10px;
  min-height:52px; padding:0 14px;
  border-radius:14px;
  font-family:var(--font-display, inherit); font-weight:700; font-size:17px;
  color:#C9DCEE; text-decoration:none;
  transition:background 160ms ease, color 160ms ease;
}
.cb-mnav .cb-mnav-link:hover{background:rgba(255,255,255,0.06); color:#FFFFFF;}
.cb-mnav .cb-mnav-link:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}

/* Current page: filled, not just tinted — on a phone a 3px underline of the
   kind the desktop rail uses is far too quiet to find. */
.cb-mnav .cb-mnav-link.active{background:rgba(46,139,255,0.18); color:#FFFFFF;}
.cb-mnav .cb-mnav-link.active::before{
  content:''; position:absolute; left:0; top:12px; bottom:12px;
  width:3px; border-radius:3px; background:#4FA6FF;
}

/* The primary product destination. Visually distinct so "where the product
   is" reads instantly, without shouting over the active state. */
.cb-mnav .cb-mnav-link.is-primary{font-size:19px; color:#FFFFFF;}
.cb-mnav .cb-mnav-link.is-primary::after{
  content:''; margin-left:auto; width:7px; height:7px; border-radius:50%;
  background:#4FA6FF; box-shadow:0 0 0 4px rgba(79,166,255,0.18);
}
.cb-mnav .cb-mnav-link.is-primary.active::after{box-shadow:0 0 0 4px rgba(79,166,255,0.28);}

/* Coming-soon row: honest and inert, matching the desktop nav's posture. Not
   a link, not focusable, not tappable. */
.cb-mnav .cb-mnav-link.is-soon{color:#6F8CA8; cursor:default;}
.cb-mnav .cb-mnav-link.is-soon:hover{background:none; color:#6F8CA8;}
.cb-mnav .cb-mnav-link.is-soon em{
  margin-left:auto; font-style:normal; font-size:11.5px; font-weight:700;
  letter-spacing:.10em; text-transform:uppercase; color:#5B7691;
}

/* ---- Account block ----------------------------------------------------- */
.cb-mnav-account{
  display:flex; flex-direction:column; gap:10px;
  margin-top:20px; padding-top:20px;
  border-top:1px solid rgba(255,255,255,0.10);
}
.cb-mnav-signout{margin:0; display:flex;}
.cb-mnav .cb-mnav-signout .cb-mnav-btn{width:100%;}

.cb-mnav .cb-mnav-btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:48px; padding:0 18px; border-radius:14px;
  font-family:var(--font-text, inherit); font-weight:700; font-size:15px;
  line-height:1; text-decoration:none; cursor:pointer;
  border:1px solid transparent;
  transition:background 160ms ease, border-color 160ms ease;
}
.cb-mnav .cb-mnav-btn:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}
.cb-mnav .cb-mnav-btn-primary{
  color:#FFFFFF; border-color:rgba(31,111,214,0.5);
  background:linear-gradient(180deg,#4FA6FF 0%,#2E8BFF 48%,#1F6FD6 100%);
  box-shadow:0 12px 24px -10px rgba(46,139,255,0.7);
}
.cb-mnav .cb-mnav-btn-ghost{
  color:#E6F0FB; background:rgba(255,255,255,0.07);
  border-color:rgba(255,255,255,0.18);
}
.cb-mnav .cb-mnav-btn-ghost:hover{background:rgba(255,255,255,0.13);}
.cb-mnav .cb-mnav-btn-quiet{
  color:#9FBCD8; background:none; border-color:rgba(255,255,255,0.14);
}
.cb-mnav .cb-mnav-btn-quiet:hover{color:#E6F0FB; border-color:rgba(255,255,255,0.26);}

/* ---- Secondary / legal links ------------------------------------------- */
.cb-mnav-meta{
  display:flex; flex-wrap:wrap; gap:8px 18px;
  margin-top:22px; padding-top:18px;
  border-top:1px solid rgba(255,255,255,0.10);
}
.cb-mnav .cb-mnav-meta a{
  min-height:32px; display:inline-flex; align-items:center;
  font-size:13px; color:#8AA6C0; text-decoration:none;
}
.cb-mnav .cb-mnav-meta a:hover{color:#D6E6F5;}
.cb-mnav .cb-mnav-meta a:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}

/* =========================================================================
   MOBILE BREAKPOINT — the parity switch.
   ========================================================================= */
/* 1080px, not 1010px (Brand System v1.0): the desktop rail needs ~1076px once
   the 160px navigation lockup sits beside it (the kit's minimum, 34px tall),
   so between 1011px and 1075px three labels wrapped onto two lines. 1080px
   reuses an existing breakpoint value (home.css board grid). ONLY this parity
   switch moved. The fixed-header block below deliberately stays at 1010px,
   because page layouts (nfl-game-intel.css's sticky rail, .cb-shell-top
   padding) compensate for the fixed bar at exactly that line — between 1011px
   and 1080px the header is in flow, as desktop is, with the burger instead of
   the rail. public-nav.js's desktop media query moves with this block. */
@media (max-width:1080px){
  /* THE RAIL AND THE TRIGGER SWITCH IN ONE PLACE.
     This sheet owns BOTH halves of the parity switch, in the same block, so
     they cannot desynchronise. They previously could not not desynchronise:
     the hide lived in curatedbets-theme.css at 767px and in home.css at
     1010px, while the burger appeared here at 1010px -- so every public_base
     page between 768px and 1010px rendered a full desktop rail AND a
     hamburger, two competing navigations in one header. Stating the hide
     beside the rule that reveals its replacement is what makes that
     impossible. This sheet loads last, after every per-page sheet, so it wins
     without !important. */
  .cb-nav-links{display:none;}

  /* The trigger appears exactly where the desktop rail disappears. 44px square
     is the theme's own --tap-min, which the 38px .cb-icon-btn never met. */
  .cb-nav-burger{
    width:44px; height:44px; flex:none;
    display:inline-flex; align-items:center; justify-content:center;
    border-radius:14px; border:1px solid var(--border-hairline);
    background:var(--surface-glass); color:var(--text-muted);
    font-size:20px; padding:0; cursor:pointer; font-family:inherit;
    transition:background 160ms ease, color 160ms ease;
  }
  .cb-nav-burger:hover{background:var(--accent-wash); color:var(--accent-strong);}
  .cb-nav-burger:focus-visible{outline:2px solid #7FB8FF; outline-offset:2px;}

  /* One account affordance per viewport: the drawer carries Join / Sign In /
     Account / Sign Out, so the duplicate popovers stand down. This also buys
     back ~90px of header width on a 375px phone. */
  .cb-nav-desk-only{display:none;}

  /* The nav grid's centre track is empty once .cb-nav-links is hidden, and its
     24px gaps were still being paid for. Collapse to brand | actions. */
  .cb-nav-inner{grid-template-columns:1fr auto; gap:12px;}
}

/* =========================================================================
   PART 1 (pass #2) — THE MOBILE HEADER STAYS REACHABLE.

   Pass #1 shipped the drawer but left the header non-sticky, so on a long
   board the only way back to the menu was to scroll to the very top.

   ``position:sticky`` is NOT available here and it is worth recording why, so
   nobody "fixes" this back: .cb-shell-top (curatedbets-theme.css) sets
   ``overflow:hidden``, which makes it a scroll container — a sticky child
   sticks INSIDE the navy zone and leaves with it. Switching that ancestor to
   ``overflow:clip`` does not help either: clip still clips, so the bar would
   be painted away the moment the navy zone scrolled past.

   ``position:fixed`` is the one thing an ancestor's overflow does not affect,
   because its containing block is the viewport. That is the same property the
   drawer already relies on, verified in pass #1.

   Desktop is untouched: the whole block is inside the 1010px media query, and
   at 1011px and up .cb-nav goes back to being an ordinary in-flow element.
   ========================================================================= */
@media (max-width:1010px){
  .cb-nav{
    position:fixed; top:0; left:0; right:0; z-index:150;
    /* The bar grows by the notch inset rather than sliding under it. */
    height:calc(var(--nav-h) + env(safe-area-inset-top, 0px));
    padding-top:env(safe-area-inset-top, 0px);
    /* At rest the bar is invisible and the hero reads exactly as it did
       before — the navy zone behind it IS the background, unchanged. The
       solid treatment arrives only once the page has scrolled (.is-stuck,
       set in public-nav.js), so nothing about the first paint changes. */
    background:transparent;
    border-bottom-color:transparent;
    transition:background var(--dur, .18s) var(--ease-out, ease),
               border-color var(--dur, .18s) var(--ease-out, ease);
  }
  /* Scrolled state: a real app bar over whatever is behind it — the light
     board included, which is why this is opaque enough to carry white text. */
  .cb-nav.is-stuck{
    background:rgba(6,21,34,0.92);
    -webkit-backdrop-filter:blur(14px) saturate(1.4);
            backdrop-filter:blur(14px) saturate(1.4);
    border-bottom:1px solid rgba(255,255,255,0.10);
    box-shadow:0 10px 24px -18px rgba(0,0,0,0.9);
  }
  /* The fixed bar is out of flow, so the navy zone reclaims its height here.
     Without this the hero's first line would sit underneath the bar. */
  .cb-shell-top{padding-top:calc(var(--nav-h) + env(safe-area-inset-top, 0px));}

  /* In-page anchors (#week-attention, #week-slate, …) must not land under the
     bar. Applied to the scroll target, not to the scroller. */
  [id]{scroll-margin-top:calc(var(--nav-h) + env(safe-area-inset-top, 0px) + 8px);}
}

/* Landscape on a notched phone puts the camera cutout in the LEFT or RIGHT
   inset, so the rail gutter has to be at least the inset. max() keeps the
   normal gutter everywhere else. Paired with viewport-fit=cover in the two
   page templates — without that meta value every env() above resolves to 0
   and these rules are inert rather than wrong. */
/* ---- THE RAIL GUTTER, AS A TOKEN --------------------------------------
   `--cb-shell-gutter` publishes the rail's CURRENT horizontal padding to its
   descendants. Nothing needed it until a full-bleed child appeared: the game
   page's sticky section rail cancels the gutter with a negative margin
   (`.gi-nav { margin: 0 -32px; padding: 0 32px }`) so its glass band can run
   edge to edge. That bleed was a hardcoded copy of the gutter, and the two
   drifted the moment pass #1 stepped the gutter down to 16px at 430px — the
   rail then bled 20px into a 16px gutter and pushed the page 4px sideways.
   Measured at 390px: `.gi-nav` right edge 394 against a 390 viewport.

   A bleeding child now reads the value instead of restating it. The padding
   below is still declared literally, because `padding: 0 var(--x)` cannot set
   the variable it reads. Keep the pairs in step. */
.cb-shell{--cb-shell-gutter:32px;}

/* Pinned to 767px, NOT 1010px, so it lines up with the existing 32px -> 20px
   step in public-brand.css. At 1010px it would have quietly narrowed the
   tablet gutter from 32px to 20px, which is a change nobody asked for. */
@media (max-width:767px){
  .cb-shell{
    --cb-shell-gutter:20px;
    padding-left:max(20px, env(safe-area-inset-left, 0px));
    padding-right:max(20px, env(safe-area-inset-right, 0px));
  }
}

/* Body scroll lock while the sheet is open. Applied by public-nav.js; without
   it the page behind the drawer scrolls under the user's finger. */
body.cb-menu-open{overflow:hidden;}

/* =========================================================================
   SHARED MOBILE SHELL GUARDS
   Global, page-agnostic fixes only. Page-specific density work is a separate
   pass — see the handoff notes accompanying this change.
   ========================================================================= */

/* Horizontal-overflow backstop. A single wide descendant anywhere on a long
   public page (a fixed-width card, an un-wrapped table, a nowrap stat row)
   currently drags the WHOLE document sideways, which on a phone reads as a
   broken site rather than a wide element. ``clip`` contains it without
   creating a scroll container, so ``position:sticky`` inside the page — the
   NFL board's identity column, for one — keeps working. `overflow-x:hidden`
   would have silently killed it. */
@media (max-width:1010px){
  html{overflow-x:clip;}
  body.cb-public,
  body.cb-home{overflow-x:clip;}
}

/* Rail gutters. The shell already steps 32px -> 20px at 767px; below 430px
   that 40px of combined padding is ~12% of a 320px screen. Two more steps,
   applied to the rail and the footer together so they stay aligned. */
@media (max-width:430px){
  .cb-shell{
    --cb-shell-gutter:16px;
    padding-left:max(16px, env(safe-area-inset-left, 0px));
    padding-right:max(16px, env(safe-area-inset-right, 0px));
  }
  .cb-footer-inner{padding:36px 16px 22px;}
}
@media (max-width:360px){
  .cb-shell{
    --cb-shell-gutter:14px;
    padding-left:max(14px, env(safe-area-inset-left, 0px));
    padding-right:max(14px, env(safe-area-inset-right, 0px));
  }
  .cb-footer-inner{padding:32px 14px 20px;}
}

/* The "back to board" link is a primary navigation action on every public
   detail page, and it rendered as a 358x20 strip — full bleed but only 20px
   tall. Given a real 44px band; it is already `inline-flex` in
   public-brand.css, so only the height changes. */
@media (max-width:1010px){
  .cb-back-link{min-height:var(--tap-min, 44px); align-items:center;}
}

/* Tables: the reusable wrapper already exists (.cb-table-wrap) but a public
   table that is not wrapped still escapes its card. Give every public table a
   floor on font size and let its own container scroll rather than letting it
   push the document. Identity columns that already use position:sticky are
   preserved by the ``clip`` choice above. */
@media (max-width:767px){
  .cb-table-wrap{-webkit-overflow-scrolling:touch;}
  .cb-board table{font-size:13px;}
}

/* Media never escapes its container. The single most common cause of a
   phone-width horizontal scrollbar. Scoped to the mobile breakpoint on
   purpose: applying it globally would silently reflow any desktop figure that
   is deliberately wider than its box, and desktop is explicitly not in scope
   for this pass. */
@media (max-width:1010px){
  img, svg, video, canvas{max-width:100%;}
  .cb-nav-brand img,
  .cb-mnav-top .cb-nav-brand img{max-width:none;}
}

@media (prefers-reduced-motion:reduce){
  .cb-mnav, .cb-mnav-panel{animation:none !important; transition:none !important;}
}

/* One-time auth completion notice (partials/auth_notice.html) -------------
   "Your email is verified…" / "You're signed in." Renders once, directly under
   the nav inside the navy command zone, on BOTH layouts — which is why it lives
   in this shared sheet. Deliberately quiet: a slim tinted line in the house
   electric blue, no icon, no close button, no motion. */
.cb-auth-notice-wrap{padding-top:12px;}
.cb-auth-notice{
  display:inline-block;
  margin:0;
  padding:9px 14px;
  border:1px solid rgba(77,163,255,.32);
  border-left:3px solid var(--cb-blue-500);
  border-radius:8px;
  background:rgba(46,139,255,.10);
  color:var(--text-strong);
  font-family:var(--font-text);
  font-size:14px;
  font-weight:600;
  line-height:1.4;
}
