/* ---- pipNova-Ai: site-wide glass + motion layer ----
   ONE shared stylesheet for every surface: the marketing pages, the
   420 generated articles, the category hubs, /mobile/, /terminal/,
   /nextgen/ and the order-flow desk.

   WHY A SEPARATE FILE
   -------------------
   The glass look touches every panel on the site. Inlining it into
   each page would mean editing 463 hand-written documents, and the
   next build would overwrite half of them. One file, loaded after the
   page's own CSS, styles all of them and can be re-tuned without
   touching a single page.

   It is loaded LAST on purpose. Equal-specificity rules win on source
   order, so this sheet can correct a layout bug (a grid that never
   collapsed on a phone) without editing the page that owns it.

   PALETTE
   -------
   Everything here is palette-agnostic. The marketing pages are still
   purple (--quantum:#b967ff) and the order-flow surfaces are lime
   (--quantum:#d2ef6c), so the layer reads --quantum / --panel / --edge
   from whatever page it lands on and inherits that page's identity.

   COLOUR-MIX
   ----------
   color-mix() lets a surface be built from the page's own --panel
   colour. Browsers that do not support it fall back to the plain
   rgba() declared immediately above each one. */

:root {
  --glass-blur: 18px;
  --glass-sat: 150%;
  --glass-fg: rgba(255, 255, 255, .92);
  --glass-line: rgba(255, 255, 255, .09);
  --glass-line-2: rgba(255, 255, 255, .05);
  --glass-shadow: 0 10px 30px -12px rgba(0, 0, 0, .65);
  --glass-shadow-sm: 0 4px 14px -8px rgba(0, 0, 0, .55);
  --glass-dur: .28s;
  --glass-ease: cubic-bezier(.22, .61, .36, 1);
  --glass-radius: 0px;
}

/* ── The ambient field ───────────────────────────────────────────
   A glass panel is only glass if there is something behind it to
   refract. The page body was a flat --bg fill, so every "glass"
   surface had nothing to blur and read as plain grey.

   This paints two slow, very low-contrast light fields behind the
   content. They are fixed, so they do not scroll, and they are
   attached to the BODY rather than to a wrapper, so they survive
   every page's own layout without an extra element in the markup.

   z-index:-1 puts the field behind the body's content but above the
   root background, which is the standard way to do this without a
   wrapper element. The body background has to be transparent for it
   to show through. */
html {
  background: var(--bg, #080808);
  /* The ambient field is a fixed layer that deliberately paints
     outside the viewport. `clip` stops it creating a horizontal
     scrollbar WITHOUT turning the root into a scroll container —
     `hidden` would, and that breaks `position:sticky` inside the
     terminal's toolbar. `hidden` is kept as the fallback for
     browsers that do not know `clip`. */
  overflow-x: hidden;
  overflow-x: clip;
}
body {
  /* The body stays OPAQUE. The ambient field paints on top of it
     (see body::below) so the text keeps its full contrast, and the
     glass panels sit above the field and refract it. */
  background: var(--bg, #080808);
  position: relative;
  z-index: 0;
  isolation: isolate;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* The parallax and the slow drift both move the BACKGROUND
     POSITION, not the element. A transform would create scrollable
     overflow (a scaled fixed layer grows the scroll area) and would
     also make the element a containing block for its fixed
     descendants. Moving the background is cheaper and safer. */
  background:
    /* A faint grid. Without something with structure behind them,
       the glass panels have nothing to refract and read as flat
       grey. This is the texture the blur is for. */
    repeating-linear-gradient(0deg,
      rgba(255, 255, 255, .022) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(90deg,
      rgba(255, 255, 255, .022) 0 1px, transparent 1px 44px),
    radial-gradient(46% 38% at 12% 8%,
      color-mix(in srgb, var(--quantum, #d2ef6c) 15%, transparent) 0%,
      transparent 68%),
    radial-gradient(42% 34% at 88% 22%,
      color-mix(in srgb, var(--accent, #d2ef6c) 11%, transparent) 0%,
      transparent 66%),
    radial-gradient(60% 44% at 50% 108%,
      color-mix(in srgb, var(--up, #c3f236) 8%, transparent) 0%,
      transparent 70%);
  background-position:
    var(--glass-px, 0px) var(--glass-py, 0px),
    var(--glass-px, 0px) var(--glass-py, 0px),
    calc(var(--glass-px, 0px) * 1.4) calc(var(--glass-py, 0px) * 1.4),
    calc(var(--glass-px, 0px) * .6) calc(var(--glass-py, 0px) * .6),
    var(--glass-px, 0px) var(--glass-py, 0px);
  opacity: .9;
  animation: glass-drift 34s ease-in-out infinite alternate;
}

/* The drift is a slow wander of the light fields, not of the grid.
   The keyframes only touch the gradient layers, so the texture stays
   put and the light appears to move behind it. */
@keyframes glass-drift {
  0%   { background-position: 0 0, 0 0, 0 0, 0 0, 0 0; }
  50%  { background-position: 0 0, 0 0, -1.6% 1.2%, 1.4% -1%, 0 0; }
  100% { background-position: 0 0, 0 0, 1.6% -1.2%, -1.4% 1%, 0 0; }
}

/* ── The glass surface ───────────────────────────────────────────
   One class, used by every panel type below. The blur is expensive
   on a phone, so the blur radius drops on small screens and the
   surface leans on its translucent fill and border instead. */
.glass {
  background: rgba(14, 15, 16, .66);
  background: color-mix(in srgb, var(--panel, #0e0f10) 72%, transparent);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-line);
  box-shadow: var(--glass-shadow-sm), inset 0 1px 0 var(--glass-line-2);
}

/* ── Chrome: nav, mega menu, toolbars, bars ─────────────────────── */
nav:not(.appnav),
.appnav.topbar,
.topbar,
.app-toolbar,
.info-bar,
.bottom-bar {
  background: rgba(8, 8, 8, .74);
  background: color-mix(in srgb, var(--bg, #080808) 74%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
}

nav:not(.appnav),
.appnav.topbar,
.topbar {
  border-bottom: 1px solid var(--glass-line);
  box-shadow: 0 8px 26px -18px rgba(0, 0, 0, .9);
}

/* The mega menu is a full sheet, so it needs to be readable, not
   merely glassy. */
.mega {
  background: rgba(8, 8, 8, .93);
  background: color-mix(in srgb, var(--menu-bg, #0a0d12) 93%, transparent);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  backdrop-filter: blur(22px) saturate(140%);
  border-bottom: 1px solid var(--glass-line);
}

/* ── Content surfaces ───────────────────────────────────────────
   The card families that exist across the site. Each one is listed
   explicitly because these are different names on different pages:
   .feat on the marketing pages, .card on /mobile/, .panel on the
   terminal, .desk-live-panel on the order-flow desk. */
.feat,
.weak-card,
.stat,
.card,
.metric,
.panel,
.desk-card,
.desk-live-panel,
.desk-stat,
.blog-card,
.faq,
.toc,
.cta-box,
.comparison,
.compare,
.acc,
.grid2 > .panel,
.grid3 > .panel {
  background: rgba(14, 15, 16, .6);
  background: color-mix(in srgb, var(--panel, #0e0f10) 66%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--glass-line);
  box-shadow: var(--glass-shadow-sm), inset 0 1px 0 var(--glass-line-2);
}

/* A panel that sits on the 1px-gap grid of the terminal has no
   radius of its own and no border: the grid's 1px gap IS the
   separation, and a border would double it. */
.app-work .panel,
.app-work .desk-live-panel {
  box-shadow: none;
  border: 0;
}

/* The comparison table carries its own border, so it keeps it and
   only gains the glass fill. */
.compare,
.comparison { border-color: var(--glass-line); }

/* ── Motion ─────────────────────────────────────────────────────
   Every rule here is opt-in from the markup or from glass.js, so
   nothing animates until the script has decided it should. A
   visitor with JavaScript disabled sees a static, complete page. */
.rv {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition: opacity .6s var(--glass-ease), transform .6s var(--glass-ease);
  will-change: opacity, transform;
}
.rv.rv-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* A soft lift on the surfaces that can be pointed at. */
.feat,
.weak-card,
.blog-card,
.card,
.desk-card,
.desk-live-panel {
  transition: transform var(--glass-dur) var(--glass-ease),
              border-color var(--glass-dur) var(--glass-ease),
              box-shadow var(--glass-dur) var(--glass-ease),
              background var(--glass-dur) var(--glass-ease);
}
@media (hover: hover) {
  .feat:hover,
  .weak-card:hover,
  .blog-card:hover,
  .card:hover,
  .desk-card:hover,
  .desk-live-panel:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--quantum, #d2ef6c) 42%, transparent);
    box-shadow: var(--glass-shadow), inset 0 1px 0 var(--glass-line-2);
  }
}

/* Press feedback for touch. */
@media (hover: none) {
  .feat:active,
  .weak-card:active,
  .blog-card:active,
  .card:active,
  .desk-card:active,
  .desk-live-panel:active,
  .btn:active,
  .menu-btn:active {
    transform: scale(.985);
  }
}

/* The brand mark gets a slow specular sweep. */
nav:not(.appnav) .brand .mark,
.appnav .brand .mark,
.topbar .brand .mark {
  position: relative;
  overflow: hidden;
}
nav:not(.appnav) .brand .mark::after,
.appnav .brand .mark::after,
.topbar .brand .mark::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 45%;
  background: linear-gradient(100deg, transparent,
              rgba(255, 255, 255, .34), transparent);
  transform: translateX(-160%);
  animation: glass-sheen 7s var(--glass-ease) infinite;
  pointer-events: none;
}
@keyframes glass-sheen {
  0%, 72% { transform: translateX(-160%); }
  88%, 100% { transform: translateX(260%); }
}

/* The live status dot already pulses in the page's own CSS. This is
   the shared fallback for pages that do not define their own. */
.glass-pulse { animation: glass-pulse 2.4s ease-in-out infinite; }
@keyframes glass-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

/* ── Mobile: the layer that actually matters ─────────────────────
   Phones get a smaller blur (a big blur radius on a phone GPU is
   the difference between smooth and hot), larger tap targets, and
   the font-size floor that the audit found missing. */
@media (max-width: 768px) {
  :root {
    --glass-blur: 12px;
    --glass-sat: 130%;
  }

  /* WCAG 2.2 asks for a 24px minimum target. The shared controls
     were 14px tall. */
  nav:not(.appnav) .menu-btn,
  .appnav .menu-btn,
  .menu-btn,
  .tb-link,
  .tb-seg > *,
  .detail-toggle,
  .btn {
    min-height: 44px;
  }
  .app-toolbar .tb-seg > *,
  .app-toolbar .tb-link {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
  }

  /* A row of link labels in the footer's article columns. */
  footer .fcol li a,
  footer .flinks a {
    display: inline-block;
    padding: 3px 0;
    line-height: 1.5;
  }

  /* The 11px labels were the most common sub-12px text on the
     site. */
  .fsub,
  .fh,
  footer .fcol h5,
  footer .fcol .fh,
  .mega .mh,
  .mega h4 {
    font-size: 12px;
  }
  .status-text,
  .topbar-state,
  .tb-badge {
    font-size: 11px;
  }

  /* The menu button's chevron is a decorative glyph, but the page's
     own rule (`nav:not(.appnav) .menu-btn .chev`) is more specific
     than a bare `.chev`, so this has to match it to win. */
  nav:not(.appnav) .menu-btn .chev,
  .appnav .menu-btn .chev,
  .menu-btn .chev {
    font-size: 11px;
  }

  /* The dense data labels on the terminal and the order-flow desk
     were 9-11px, which is below the readable floor on a phone even
     though it is fine on a desktop monitor at arm's length. Those
     two surfaces are fixed at source instead — the phone shell
     already renders the same class names at 12px, and a rule here
     would have had to fight with it.

     The NUMBERS are left alone: a price must keep its precise,
     compact shape, and growing it would break the column alignment
     the table depends on. */
}

/* ── Mobile layout repairs ─────────────────────────────────────
   These are real bugs the audit found, not cosmetic preferences.

   1. The order-flow desk's live grid asked for a 420px minimum
      column. On a 390px phone that is wider than the screen, so
      the page scrolled sideways and the right-hand panel was cut
      off. A grid track cannot shrink below its own minmax(), so
      the fix has to override the track itself.

      The desk page's own CSS has been fixed at source (its minmax()
      now uses min(420px,100%)), so this rule is the safety net for
      a copy of the page that is out of date. It is deliberately
      narrow: below 640px a single column is the only thing that
      fits, but between 640px and 900px two columns are fine and
      forcing one would waste the width. */
@media (max-width: 640px) {
  .desk-live-grid,
  .desk-live-grid.enhanced,
  .desk-grid {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

@media (max-width: 820px) {
  /* The next-generation terminal's responsive rules targeted
     .main-grid, but the page's DOM uses .app-work, so the mobile
     breakpoint never fired and the terminal kept its 300px + 320px
     side columns on a 320px phone — which is why it rendered 830px
     wide. The builder is the source of truth for that page and
     carries the same fix; this is the safety net for a copy of the
     page that is out of date. */
  .app-work {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  .app-work .left-col,
  .app-work .center-col,
  .app-work .right-col {
    grid-column: 1 / -1;
  }
  /* The toolbar is a single row of timeframes and links. It cannot
     fit a phone, so it scrolls sideways on purpose rather than being
     squeezed into unreadable columns. */
  .app-toolbar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .app-toolbar::-webkit-scrollbar { display: none; }
  .app-toolbar .tb-seg,
  .app-toolbar .tb-badge,
  .app-toolbar .tb-link {
    flex: 0 0 auto;
  }
}

@media (max-width: 768px) {
  /* The mega menu is a fixed sheet. On a phone it must be able to
     reach the bottom of the screen. */
  .mega { max-height: calc(100vh - var(--mega-top, 56px)); }
}

/* ── Reduced motion ─────────────────────────────────────────────
   The site already carries a prefers-reduced-motion block on the
   terminal. This covers every page: the ambient field stops
   drifting, the reveal animation becomes a plain fade, and the
   sheen does not sweep. */
@media (prefers-reduced-motion: reduce) {
  body::before {
    animation: none !important;
    translate: none !important;
  }
  .rv {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .rv.rv-in { opacity: 1 !important; transform: none !important; }
  nav:not(.appnav) .brand .mark::after,
  .appnav .brand .mark::after,
  .topbar .brand .mark::after {
    animation: none !important;
    transform: none !important;
  }
  .feat, .weak-card, .blog-card, .card, .desk-card, .desk-live-panel {
    transition: none !important;
  }
}

/* ── Print ─────────────────────────────────────────────────────
   A glass panel over a white page is unreadable, and the backdrop
   filter would be wasted ink. */
@media print {
  body::before { display: none !important; }
  .feat, .weak-card, .stat, .card, .metric, .panel, .desk-card,
  .desk-live-panel, .blog-card, .faq, .toc, .cta-box, .comparison,
  .compare, .acc {
    background: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    box-shadow: none !important;
  }
}
