/* ===== from main.css lines 186-198 ===== */
    /* ---------- Shell ---------- */
    .shell {
      width: min(1240px, calc(100% - 32px));
      margin: 36px auto 64px;
      position: relative;
      z-index: 2;
      /* NOTE: do NOT set `overflow-x: clip` here — it clips the .hero full-
         bleed extension (negative margins that push the header to the
         viewport edges on wide screens), producing visible "borders" on
         the sides. The clip needs to live on the specific grid containers
         that create the overflow in the first place (see .results below). */
    }

/* ===== from main.css lines 2674-2741 ===== */
    /* ---------- Layout ---------- */
    .layout {
      display: flex;
      gap: 24px;
      /* Tightened from 32 → 12 px so the search-results page doesn't have
         a wide empty band between the site header and the filter/sort row.
         Detail page panels also benefit from the snugger spacing. */
      margin-top: 12px;
      align-items: start;
    }
    /* Empeche les flex items de grossir pour contenir du contenu intrinsequement
       large (ex: .home-row avec cards en scroll horizontal). Sans min-width:0,
       la largeur intrinseque du contenu propage jusqu'au flex item et elargit
       la page. */
    .layout > .panel { min-width: 0; }

    .panel {
      padding: 22px;
      border: 1px solid var(--line);
      border-radius: var(--radius);
      background: var(--panel);
    }

    .layout > .panel:last-child {
      flex: 1 1 0;
      min-width: 0;
      background: transparent;
      border: 0;
      padding: 0;
    }

    .results-panel {
      flex: 1 1 0;
      min-width: 0;
      background: transparent;
      border: 0;
      padding: 0;
    }

    .results-header {
      display: flex;
      align-items: center;
      margin-bottom: 2px;
    }
    .results-controls {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 12px;
      margin-bottom: 10px;
    }
    .results-controls > .results-filters { margin-right: auto; }
    .results-controls-label {
      font-size: 0.9rem;
      font-weight: 600;
      color: var(--muted);
      letter-spacing: 0.04em;
      white-space: nowrap;
      flex: 0 0 auto;
    }
    .results-sort {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      font-size: 0.9rem;
      font-weight: 600;
      color: var(--muted);
    }
    .results-sort .season-select {
      min-height: var(--control-pill-height);
      padding: 0 30px 0 14px;
      font-size: var(--fs-sm);
    }

    /* ---------- Page glow halo (purple accent) ---------- */
     /* A single half-disc of purple light blooming up from the bottom edge of
       the document. Diameter = 200vw, so radius = 100vw. The element
      rectangle is 200vw wide × 300vw tall (aspect-ratio 2/3), anchored to
       the body bottom — only the upper half of the circle exists in the
       layout, so the halo cannot extend `body.scrollHeight` and add a
       phantom vertical scroll area. Horizontal overflow (the 50vw spilling
       past each viewport edge) is absorbed by `overflow-x: clip` on
       `<html>` / `<body>`. The radial gradient is anchored at the bottom-
       center of the rectangle, so the visible glow looks like a
      horizontally-centered half disc emerging from the page bottom. */
    body::after {
      content: "";
      position: absolute;
      bottom: 0;
      left: 50%;
      width: 200vw;
      aspect-ratio: 2 / 3;
      transform: translateX(-50%);
      pointer-events: none;
      z-index: -1;
      background: radial-gradient(
        circle 100vw at 50% 100%,
        rgba(var(--accent-rgb), 0.55) 0%,
        rgba(var(--accent-rgb), 0.32) 30%,
        rgba(var(--accent-rgb), 0.12) 65%,
        rgba(var(--accent-rgb), 0.00) 100%
      );
    }


    /* ---------- Bottom floating navigation bar ---------- */
    /* Glass-chip pill anchored to the bottom-center of the viewport. Holds
       four sections (Streaming, Sports, Podcast, TV); only Streaming is
       enabled today. Sits above the shell content, below modals (z:200+).
       safe-area-inset-bottom handles iOS home indicator. */
    .bottom-nav {
      position: fixed;
      left: 50%;
      /* Mobile: sit closer to the bottom edge so the bar doesn't compete
         with the home indicator gesture area. Desktop bumps it up via
         the @media (min-width: 768px) override below. */
      bottom: env(safe-area-inset-bottom, 0px);
      transform: translateX(-50%);
      z-index: var(--z-app-chrome, 200);
      display: flex;
      align-items: stretch;
      gap: 6px;
      padding: 7px;
      border-radius: 999px;
      box-shadow: 0 14px 36px rgba(0, 0, 0, 0.5);
      max-width: calc(100vw - 24px);
      /* Drop the white outline that .glass-chip ships by default — design
         calls for a clean dark pill with no border. */
      border: 0;
    }
    body.onboarding-active .bottom-nav,
    body.interest-onboarding .bottom-nav { display: none !important; }
    /* Sliding white pill behind the active button. Position + size are
       written by JS (via transform/width) on click, so the move animates
       independently of the buttons themselves. top/bottom must match the
       parent's padding so the pill fits flush inside the bar. */
    .bottom-nav-indicator {
      position: absolute;
      top: 7px;
      bottom: 7px;
      left: 0;
      width: 0;
      border-radius: 999px;
      background: #ffffff;
      transform: translateX(0);
      transition: transform 0.35s cubic-bezier(0.32, 0.72, 0.26, 1),
                  width 0.35s cubic-bezier(0.32, 0.72, 0.26, 1);
      /* The pill itself doesn't intercept events — pointerdown is listened
         on the nav, which hit-tests against the pill's bounding box. This
         avoids z-index fights with the buttons (which sit above the pill
         visually). */
      pointer-events: none;
      z-index: 0;
    }
    /* While dragging, kill the slide transition so the pill follows the
       pointer 1:1 instead of lerping behind it. */
    .bottom-nav.is-dragging .bottom-nav-indicator {
      transition: none;
    }
    /* Show a grab cursor on the active button (the one the pill sits over)
       so it's discoverable that the pill is draggable. */
    .bottom-nav-item.is-active {
      cursor: grab;
    }
    .bottom-nav.is-dragging,
    .bottom-nav.is-dragging .bottom-nav-item {
      cursor: grabbing;
    }
    /* Prevent Safari from hijacking horizontal swipes for back-navigation
       or vertical drags for page scroll while interacting with the nav. */
    .bottom-nav {
      touch-action: none;
    }
    .bottom-nav-item {
      flex: 0 0 auto;
      display: inline-flex;
      align-items: center;
      gap: 10px;
      padding: 10px 21px;
      border: 0;
      border-radius: 999px;
      background: transparent;
      color: var(--text-80);
      font-family: var(--font);
      font-size: var(--fs-sm);
      font-weight: var(--fw-semi);
      letter-spacing: 0.01em;
      cursor: pointer;
      transition: color 0.25s ease;
      white-space: nowrap;
      position: relative;
      z-index: 1;
    }
    .bottom-nav-item:hover:not(.is-pill-over) {
      color: #fff;
    }
    /* The button currently sitting under the white pill flips its icon +
       label to dark for legibility against the bright pill. .is-pill-over
       is set live by JS during click animation and drag, so the color
       follows the pill rather than staying glued to the active button. */
    .bottom-nav-item.is-pill-over {
      color: #0d131a;
    }
    .bottom-nav-icon {
      flex: 0 0 auto;
      width: 25px;
      height: 25px;
      /* display: block prevents inline baseline alignment from shifting
         the SVG up relative to the label glyphs. */
      display: block;
    }
    /* Label hidden via display: none on inactive items (no transition on the
       label width). This keeps button widths stable as soon as the class
       swap happens, so the JS measurement of the active button's bounds
       returns the final layout — no mid-transition mismatch with the pill.
       line-height matches the icon height so the text glyphs (especially
       all-caps labels like "TV" / "TV+") render centered next to the icon
       instead of biased toward the top of the line box. */
    .bottom-nav-label {
      line-height: 25px;
    }
    .bottom-nav-item:not(.is-active) .bottom-nav-label {
      display: none;
    }
    /* Desktop: a touch larger so the bar feels intentional on roomy
       screens without dominating mobile viewports. The bottom offset
       also grows back so the bar lifts off the bottom edge. */
    @media (min-width: 768px) {
      .bottom-nav {
        gap: 8px;
        padding: 9px;
        bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
      }
      .bottom-nav-indicator { top: 9px; bottom: 9px; }
      .bottom-nav-item {
        gap: 12px;
        padding: 12px 25px;
        font-size: var(--fs-base);
      }
      .bottom-nav-icon {
        width: 27px;
        height: 27px;
      }
      .bottom-nav-label {
        line-height: 27px;
      }
    }
