/* ============================================================
   Cognitivv — shared components
   ------------------------------------------------------------
   Loaded by BOTH stylesheet families (pm.css pages and site.css
   pages), so anything in here has to stand on its own: it may
   only depend on colors_and_type.css tokens, never on a rule
   from pm.css or site.css.

   Contents:
     .gbox   — the general box. An inset rounded card with the
               page surface showing around it. Dark or light.
     .brand  — the big wordmark in a box that shrinks on scroll
               and lands on the nav's own logo.
     .picker — checkbox-style option cards inside a box, with a
               live answer line and a CTA that rewrites itself.
     .vs     — the with / without comparison.
   ============================================================ */

/* ------------------------------------------------------------
   The general box
   ------------------------------------------------------------ */

/* The frame. The padding here is the page surface you see around
   the card — that gap is the whole point of the component. */
/* The gutter around the card. Its colour is the page surface at rest and
   charcoal by the time you have scrolled the hero away, so the cream frame
   visibly closes down around a card that is already shrinking. JS sets
   --gbox-dim from 0 to 1; with no JS it stays 0 and the gutter is cream. */
.gbox-wrap {
  padding: 12px;
  background: color-mix(in srgb, var(--bg-charcoal) calc(var(--gbox-dim, 0) * 100%), var(--bg-cream));
}
.gbox-wrap-flush { padding: 12px 12px 0; }

.gbox {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  transform-origin: 50% 50%;
  transform: scale(var(--gbox-scale, 1));
}

/* Three glows, one per product (blue / green / orange, left to right),
   plus the top light. A box that carries a photograph (.gbox-has-photo)
   keeps these: the picture's top edge fades into them. */
.gbox-dark {
  background:
    radial-gradient(120% 90% at 50% 0%, var(--bg-charcoal-3) 0%, rgba(50, 46, 42, 0) 62%),
    radial-gradient(60% 55% at 12% 106%, color-mix(in srgb, var(--p-bug) 34%, transparent) 0%, transparent 72%),
    radial-gradient(58% 52% at 50% 112%, color-mix(in srgb, var(--p-pm) 30%, transparent) 0%, transparent 70%),
    radial-gradient(62% 55% at 88% 104%, color-mix(in srgb, var(--p-lms) 28%, transparent) 0%, transparent 72%),
    var(--bg-charcoal);
  color: var(--fg-on-dark-1);
}

/* Film grain. Generated, not a file — it costs about 300 bytes and it is
   what stops the gradients banding on a big dark surface. */
.gbox-dark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.4;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------
   The photograph at the foot of the box
   ------------------------------------------------------------
   A strip at rest, bottom-anchored and fading up into the dark.
   picker.js sets --photo-p from 0 to 1 over the first 60% of the
   box's height of scroll; the strip grows to take up to 55% of
   the box and the picture inside eases up in scale, so it swells
   as the copy above it leaves. Height, not transform, because the
   picture has to reveal more of itself, not just get bigger; it
   is absolutely positioned so nothing else reflows. With no JS
   the strip is the resting height and nothing moves.
   ------------------------------------------------------------ */
.gbox-has-photo { --photo-min: clamp(190px, 22vw, 310px); }
.gbox-inner-photo { padding-bottom: calc(var(--photo-min) + 8px); }

.gbox-photo {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  height: calc(var(--photo-min) + (100% - var(--photo-min)) * 0.55 * var(--photo-p, 0));
  overflow: hidden;
  pointer-events: none;
}
.gbox-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The lit band of mist sits a little above the picture's middle; keep it
     in the strip at rest, so the sky and the dark foreground arrive as the
     strip grows. */
  object-position: 50% 46%;
  transform-origin: 50% 100%;
  transform: scale(calc(1 + 0.1 * var(--photo-p, 0)));
  /* The top edge dissolves into the box: a mask to transparent, not a
     painted gradient. A painted charcoal edge over a background that is
     not quite charcoal there (the product glows) drew a hairline across
     the card; a mask lets the box's own surface show through instead. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.12) 24%, rgba(0, 0, 0, 0.55) 54%, #000 82%);
          mask-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.12) 24%, rgba(0, 0, 0, 0.55) 54%, #000 82%);
}
/* The picture also needs to be in shadow at its foot, or the card's bottom
   corner shows bright sky against the cream gutter. */
.gbox-photo::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 28%;
  z-index: 1;
  background: linear-gradient(to top, rgba(26, 24, 22, 0.55), transparent);
}

/* Over the photograph the picker needs a surface of its own: the options
   sit on a tinted, blurred pane rather than a 4% wash, and the answer line
   and the trust row give up the dimmest grey. */
.gbox-has-photo .pick {
  background: rgba(26, 24, 22, 0.55);
  border-color: rgba(250, 246, 239, 0.22);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
}
.gbox-has-photo .pick:hover { background: rgba(26, 24, 22, 0.72); border-color: rgba(250, 246, 239, 0.4); }
.gbox-has-photo .picker-out { color: var(--fg-on-dark-2); font-size: 15px; }
.gbox-has-photo .gbox-trust {
  font-size: 15px;
  color: var(--fg-on-dark-2);
  border-top-color: rgba(250, 246, 239, 0.18);
}
.gbox-has-photo .gbox-trust b { color: var(--fg-on-dark-1); }

.gbox-light {
  background: var(--bg-cream-soft);
  border: 1px solid var(--line-1);
  color: var(--fg-1);
}

.gbox-inner {
  position: relative;
  z-index: 1;
  max-width: 960px;
  margin: 0 auto;
  padding: clamp(40px, 5.5vw, 76px) 24px clamp(30px, 3.6vw, 52px);
  text-align: center;
}
/* Room for the wordmark sitting in the box's top-left corner. */
.gbox-inner-brand { padding-top: clamp(140px, 15vw, 204px); }
.gbox-inner-wide { max-width: 1120px; }

.gbox-eyebrow {
  margin: 0 0 clamp(16px, 2.6vw, 26px);
  font-family: var(--font-ui);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-soft);
}
.gbox-light .gbox-eyebrow { color: var(--accent-press); }

.gbox-h {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5.4vw, 70px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: inherit;
  text-wrap: balance;
}
.gbox-h em { display: block; font-style: italic; color: var(--accent-soft); }
.gbox-light .gbox-h em { color: var(--accent); }
.gbox-h-sm { font-size: clamp(28px, 3.6vw, 46px); }

.gbox-sub {
  max-width: 34em;
  margin: clamp(16px, 2vw, 22px) auto 0;
  font-size: clamp(15px, 1.4vw, 17px);
  line-height: 1.6;
  color: var(--fg-on-dark-2);
}
.gbox-light .gbox-sub { color: var(--fg-2); }

.gbox-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px 22px;
  margin-top: clamp(24px, 3vw, 34px);
  padding-top: 18px;
  border-top: 1px solid var(--line-on-dark-1);
  font-size: 13px;
  color: var(--fg-on-dark-3);
}
.gbox-trust b { font-family: var(--font-ui); font-weight: 700; color: var(--fg-on-dark-2); }
.gbox-trust .gbox-sep { width: 1px; height: 14px; background: var(--line-on-dark-2); }

/* ------------------------------------------------------------
   The brandmark
   ------------------------------------------------------------
   Two elements, one logo. `.gbox-brand` is the real one, in flow
   at the top-left of the box — that is what renders with no JS,
   on a phone, and under reduced motion, and it is complete on
   its own. `.brandmark` is a fixed decorative copy that JS flies
   from the slot's rect to the nav logo's rect as you scroll; the
   slot and the nav logo are hidden (but still laid out, because
   their rects are what the animation reads) only while it runs.
   ------------------------------------------------------------ */

.gbox-brand {
  position: absolute;
  /* Seated well down in the box: with no bar above the box at the top of
     the page, the wordmark's flight is exactly this distance minus the nav
     logo's resting height — at 32px it was a 27px flight, i.e. instant. */
  top: clamp(56px, 6.8vw, 98px);
  left: clamp(20px, 3vw, 40px);
  z-index: 2;
  line-height: 0;
}
.gbox-brand img { display: block; height: var(--brand-h); width: auto; filter: var(--brand-halo); }
/* A dark halo around the cream ink so the wordmark stands off the picture
   (safe.com does the same over its hero). Goes with the dark artwork, so it
   fades out with it as the mark lands on the cream bar. */
.gbox-dark { --brand-halo: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85)) drop-shadow(0 0 14px rgba(0, 0, 0, 0.6)); }
.brandmark .brand-on-dark { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.85)) drop-shadow(0 0 14px rgba(0, 0, 0, 0.6)); }

.brandmark {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 70;
  pointer-events: none;
  transform-origin: 0 0;
  will-change: transform;
  /* Invisible until JS is actually flying it. Without this it sat at (0,0)
     on every phone, over the nav, on top of the real logo. */
  visibility: hidden;
  /* A one-cell grid, not absolute children: the two artworks have to stack
     AND the box has to take their width, which an absolutely positioned
     replaced element inside a zero-width fixed box does not give you
     (Chrome resolves its auto width to 0 and nothing paints). */
  display: grid;
}
.brandmark img {
  grid-area: 1 / 1;
  display: block;
  height: var(--brand-h);
  width: auto;
}
.brandmark .brand-on-dark  { opacity: var(--brand-dark, 1); }
.brandmark .brand-on-light { opacity: var(--brand-light, 0); }

/* Hidden, not removed: the flight path is measured from these two rects
   every frame, so both have to keep taking up space. */
.has-brandmark .brandmark { visibility: visible; }
.has-brandmark .gbox-brand img { visibility: hidden; }
.has-brandmark .nav-logo img { opacity: 0; }

/* A mega panel is an overlay, and the brandmark sits above the nav so it can
   land on the nav logo — which would draw it straight over an open panel.
   While one is open the real nav logo takes over, which is also the only
   logo that makes sense in that state. */
.menu-open .brandmark { opacity: 0; visibility: hidden; }
.menu-open.has-brandmark .nav-logo img { opacity: 1; }

/* ------------------------------------------------------------
   The phone drawer — the mega menu's structure, stacked
   ------------------------------------------------------------
   On a wide screen the nav is two panels: Products (each product
   with its status and its two sub-pages) and Company. The drawer
   is the same information in one column, not a flat list of every
   URL on the site — so a phone reader gets the same map a desktop
   reader does. Its own classes, so neither pm.css's drawer rules
   nor site.css's `.nav-mobile-link` reach into it.
   ------------------------------------------------------------ */

/* Never taller than the screen below the bar. */
.nav-mobile { max-height: calc(100svh - 58px); overflow-y: auto; overscroll-behavior: contain; }

/* Each level is its own column. Without this the links inside a panel are
   inline boxes (they used to be flex children of the drawer itself) and the
   sub-pages run together across the line. The [hidden] guard has to come
   after, or `display: flex` would override it and every panel would show. */
.nav-m-panel { display: flex; flex-direction: column; gap: 2px; }
.nav-m-panel[hidden] { display: none; }

/* The two top-level rows, and the header that walks back from a section. */
.nav-m-row, .nav-m-back {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 14px 12px;
  border: none;
  background: none;
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 600;
  color: var(--fg-1);
  text-align: left;
  cursor: pointer;
}
.nav-m-row { justify-content: space-between; }
.nav-m-row:hover, .nav-m-row:active,
.nav-m-back:hover, .nav-m-back:active { background: var(--bg-cream-deep); }
.nav-m-chev { flex: none; color: var(--fg-3); }

.nav-m-back {
  gap: 10px;
  margin-bottom: 4px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-1);
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  font-size: 15px;
  color: var(--fg-2);
}
.nav-m-back .nav-m-chev-back { color: var(--accent); }

.nav-m-head {
  margin: 14px 0 6px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.nav-m-head:first-child { margin-top: 4px; }

/* A product: its name, a status tag, and the product's own hue as a dot. */
.nav-m-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  text-decoration: none;
  --c: var(--accent);
}
.nav-m-item[data-accent="bug"] { --c: var(--p-bug); }
.nav-m-item[data-accent="pm"]  { --c: var(--p-pm); }
.nav-m-item[data-accent="lms"] { --c: var(--p-lms); }
.nav-m-item:hover, .nav-m-item:active { background: var(--bg-cream-deep); }

.nav-m-name {
  position: relative;
  padding-left: 15px;
  font-family: var(--font-ui);
  font-size: 16px;
  font-weight: 600;
  color: var(--fg-1);
}
.nav-m-name::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.44em;
  width: 7px;
  height: 7px;
  background: var(--c);
}
/* --- Kept, not used (founder, 2026-09-18) ---------------------------------
   A status word beside a product's name in the drawer ("Live", "In pilot").
   Drop <span class="nav-m-tag">…</span> back inside .nav-m-item to use it. */
.nav-m-tag { font-family: var(--font-ui); font-size: 12px; color: var(--fg-3); }

/* A product's sub-pages, indented under it. */
.nav-m-sub {
  padding: 8px 12px 8px 39px;
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--fg-2);
  text-decoration: none;
}
.nav-m-sub:hover, .nav-m-sub:active { background: var(--bg-cream-deep); color: var(--fg-1); }

/* Company: one level, no dots. */
.nav-m-link {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: 15px;
  color: var(--fg-1);
  text-decoration: none;
}
.nav-m-link:hover, .nav-m-link:active { background: var(--bg-cream-deep); }

/* ------------------------------------------------------------
   The revealed nav
   ------------------------------------------------------------
   On a page that opts in (.nav-reveal), the bar is not there at
   the top: the general box owns the top of the page, wordmark
   and all. As you scroll, the bar fades in beneath the wordmark's
   landing point BEFORE the wordmark gets there, so the logo never
   crosses the bar's edge half-in, half-out. Fixed rather than
   sticky so the box can sit at the top edge; only under html.js,
   because without the script nothing would ever reveal it.
   ------------------------------------------------------------ */

html.js .nav.nav-reveal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  opacity: var(--nav-reveal, 0);
  pointer-events: none;
}
html.js .nav.nav-reveal.is-shown { pointer-events: auto; }
/* The mobile drawer opens below the bar; keep it usable once revealed. */
html.js .nav.nav-reveal.is-shown .nav-mobile { pointer-events: auto; }

/* ------------------------------------------------------------
   The menu widget — the way in before the bar arrives
   ------------------------------------------------------------
   On the homepage the bar is not there at the top, which is the
   point, but it left no visible way into the menu until you
   scrolled. This sits in the top-right corner over the dark hero
   card and fades out on exactly the progress that fades the bar
   in (--nav-reveal), so the two are never both on screen.

   Pressing it pins the bar open and opens the same drill-down
   panel the phone burger opens, at any width. Without JS it is
   never shown, because there is no nav to open and the bar is
   the ordinary sticky one.
   ------------------------------------------------------------ */

.nav-widget { display: none; }

html.js .nav-widget {
  position: fixed;
  top: clamp(14px, 1.6vw, 22px);
  right: clamp(14px, 2vw, 30px);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid rgba(250, 246, 239, 0.28);
  border-radius: var(--r-sm);
  background: rgba(26, 24, 22, 0.55);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  color: var(--fg-on-dark-1);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  /* The inverse of the bar's own progress. */
  opacity: calc(1 - var(--nav-reveal, 0));
  transition: background var(--dur-2) ease, border-color var(--dur-2) ease;
}
html.js .nav-widget[hidden] { display: none; }
html.js .nav-widget:hover { background: rgba(26, 24, 22, 0.75); border-color: rgba(250, 246, 239, 0.45); }

/* Two bars, the brand's square ends rather than a rounded burger. */
.nav-widget-glyph { display: grid; gap: 4px; width: 16px; }
.nav-widget-glyph i { display: block; height: 2px; background: currentColor; }

/* Open: it sits on the cream bar, so it swaps to ink. */
html.js .nav-widget[aria-expanded="true"] {
  background: var(--bg-cream-deep);
  border-color: var(--line-2);
  color: var(--fg-1);
  opacity: 1;
}

@media (max-width: 620px) {
  html.js .nav-widget { padding: 9px 12px; font-size: 13px; }
  html.js .nav-widget .nav-widget-label { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .nav-widget { transition: none; }
}

/* While the widget holds the menu open, the bar is pinned on regardless of
   scroll — the panel hangs off it. */
html.js .nav.nav-reveal.is-pinned { opacity: 1; pointer-events: auto; }
html.js .nav.nav-reveal.is-pinned .nav-mobile { pointer-events: auto; }

/* On a wide screen the drawer is a panel under the widget, not a drawer
   across the whole bar: full width, it runs over the hero's wordmark and the
   CTAs stretch to a metre wide. It keeps its own two-level behaviour. */
@media (min-width: 861px) {
  html.js .nav.nav-reveal.is-pinned .nav-mobile {
    position: absolute;
    top: calc(100% + 8px);
    right: clamp(14px, 2vw, 30px);
    left: auto;
    width: min(340px, calc(100vw - 32px));
    max-width: none;
    margin: 0;
    padding: 10px 14px 16px;
    max-height: calc(100vh - 92px);
    border: 1px solid var(--line-1);
    border-radius: var(--r-md);
    box-shadow: 0 30px 60px -28px rgba(42, 38, 34, 0.5);
  }
}

/* ------------------------------------------------------------
   The picker
   ------------------------------------------------------------
   Every .pick is a real <button aria-pressed>, so with no JS the
   box still reads as a list and the box's default CTA is already
   the right destination.
   ------------------------------------------------------------ */

.picker { margin-top: clamp(24px, 3.4vw, 38px); }
.picker-q {
  margin: 0 0 16px;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  color: var(--fg-on-dark-1);
}
.gbox-light .picker-q { color: var(--fg-1); }

.picks {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 780px;
  margin: 0 auto;
}
.picks-wide { max-width: 900px; }

.pick {
  flex: 1 1 210px;
  max-width: 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--line-on-dark-2);
  border-radius: var(--r-md);
  background: rgba(250, 246, 239, 0.04);
  color: var(--fg-on-dark-1);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  cursor: pointer;
  transition: background var(--dur-2) ease, border-color var(--dur-2) ease,
              transform var(--dur-2) ease;
}
.pick:hover { background: rgba(250, 246, 239, 0.09); border-color: rgba(250, 246, 239, 0.34); }
.pick:active { transform: translateY(1px); }

.gbox-light .pick {
  border-color: var(--line-2);
  background: var(--bg-cream);
  color: var(--fg-1);
}
.gbox-light .pick:hover { background: var(--bg-cream-deep); border-color: var(--line-strong); }

.pick-box {
  position: relative;
  display: block;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--accent-soft);
  border-radius: var(--r-xs);
}
.gbox-light .pick-box { border-color: var(--accent); }

/* A selected option wears its product's hue, so the box answers "which one
   is this" before the answer line has said anything. */
.pick { --c: var(--accent); --c-tint: var(--accent-tint); }
.pick[data-key="bug"] { --c: var(--p-bug); --c-tint: var(--p-bug-tint); }
.pick[data-key="pm"]  { --c: var(--p-pm);  --c-tint: var(--p-pm-tint); }
.pick[data-key="lms"] { --c: var(--p-lms); --c-tint: var(--p-lms-tint); }

/* Mixed toward transparent, not toward cream: on the dark box a cream mix
   washes all three hues out to the same pale grey. */
.pick-box { border-color: color-mix(in srgb, var(--c) 80%, transparent); }
.gbox-light .pick-box { border-color: var(--c); }
.pick[aria-pressed="true"] {
  background: color-mix(in srgb, var(--c) 22%, transparent);
  border-color: var(--c);
}
.gbox-light .pick[aria-pressed="true"] { background: var(--c-tint); }
.pick[aria-pressed="true"] .pick-box { background: var(--c); border-color: var(--c); }

/* The tick is a rotated two-sided box — no icon font, no inline SVG per option. */
.pick[aria-pressed="true"] .pick-box::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 3px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.picker-out {
  min-height: 1.5em;
  max-width: 40em;
  margin: 18px auto 0;
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg-on-dark-3);
}
.picker-out b { color: var(--fg-on-dark-1); font-weight: 700; }
.gbox-light .picker-out { color: var(--fg-2); }
.gbox-light .picker-out b { color: var(--fg-1); }

.picker-cta { margin-top: 18px; }

.btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: min(100%, 460px);
  padding: 17px 30px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--bg-cream-soft);
  color: var(--fg-1);
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 700;
  text-decoration: none;
  transition: background var(--dur-2) ease, transform var(--dur-2) ease;
}
.btn-pill:hover { background: #fff; transform: translateY(-1px); }
.gbox-light .btn-pill { background: var(--accent); color: #fff; }
.gbox-light .btn-pill:hover { background: var(--accent-hover); }

/* ------------------------------------------------------------
   With / without
   ------------------------------------------------------------ */

.vs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(28px, 3.6vw, 42px);
  text-align: left;
  background: var(--line-on-dark-1);
  border: 1px solid var(--line-on-dark-1);
  border-radius: var(--r-md);
  overflow: hidden;
}
.gbox-light .vs { background: var(--line-1); border-color: var(--line-1); }

.vs-col { padding: 24px 22px; background: var(--bg-charcoal); }
.gbox-light .vs-col { background: var(--bg-cream-soft); }
.vs-col-with { background: var(--bg-charcoal-2); }
.gbox-light .vs-col-with { background: var(--bg-cream); }

.vs-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 4px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-on-dark-3);
}
.gbox-light .vs-head { color: var(--fg-3); }
.vs-head::before { content: ""; width: 9px; height: 9px; background: var(--fg-4); }
.vs-col-with .vs-head { color: var(--accent-soft); }
.gbox-light .vs-col-with .vs-head { color: var(--accent-press); }
.vs-col-with .vs-head::before { background: var(--accent); }

.vs-line {
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 1.15;
  color: var(--fg-on-dark-1);
}
.gbox-light .vs-line { color: var(--fg-1); }

.vs-list { margin: 0; padding: 0; list-style: none; }
.vs-list li {
  padding: 11px 0;
  border-top: 1px solid var(--line-on-dark-1);
  font-family: var(--font-ui);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--fg-on-dark-2);
}
.gbox-light .vs-list li { border-top-color: var(--line-1); color: var(--fg-2); }
.vs-list li b { font-weight: 700; color: var(--fg-on-dark-1); }
.gbox-light .vs-list li b { color: var(--fg-1); }

/* ------------------------------------------------------------
   Responsive
   ------------------------------------------------------------ */

@media (max-width: 760px) {
  .vs { grid-template-columns: minmax(0, 1fr); }
  .vs-line { font-size: 21px; }
}

@media (max-width: 620px) {
  .gbox-has-photo { --photo-min: clamp(150px, 40vw, 220px); }
  .gbox-brand { top: 52px; }
  .gbox-inner-brand { padding-top: clamp(104px, 26vw, 128px); }
  .gbox-trust .gbox-sep { display: none; }
  .gbox-wrap, .gbox-wrap-flush { padding-left: 8px; padding-right: 8px; }
  .gbox-wrap { padding-top: 8px; padding-bottom: 8px; }
  .gbox-wrap-flush { padding-top: 8px; }
  .gbox { border-radius: var(--r-lg); transform: none; }
  .pick { flex-basis: calc(50% - 5px); max-width: none; padding: 13px 10px; font-size: 13px; }
  .btn-pill { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .gbox { transform: none; }
  .gbox-wrap { background: var(--bg-cream); }
  .gbox-photo { height: var(--photo-min); }
  .gbox-photo img { transform: none; }
}

/* The *_trim.png wordmarks are cropped to their ink (89% of image height),
   so --brand-h is very nearly the type size you see. */
:root { --brand-h: 30px; }
@media (min-width: 620px) { :root { --brand-h: clamp(40px, 5.2vw, 74px); } }

/* ============================================================
   THE MEGA MENU
   ------------------------------------------------------------
   Lives in components.css because both stylesheet families use
   the same nav. The trigger is a real <button aria-expanded>
   and the panel is a real [hidden] region, so with no JS every
   destination is still reachable from the footer and the mobile
   drawer — the panel simply never opens.
   ============================================================ */

.mega { position: static; }

.mega-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: none;
  border-radius: var(--r-sm);
  background: none;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--fg-2);
  cursor: pointer;
  transition: color var(--dur-2) ease, background var(--dur-2) ease;
}
.mega-trigger:hover,
.mega-trigger[aria-expanded="true"] { color: var(--fg-1); background: var(--bg-cream-deep); }
.mega-caret { transition: transform var(--dur-2) ease; }
.mega-trigger[aria-expanded="true"] .mega-caret { transform: rotate(180deg); }

.mega-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 80;
  background: var(--bg-cream-soft);
  border-bottom: 1px solid var(--line-1);
  box-shadow: 0 18px 32px -22px rgba(42, 38, 34, 0.5);
}
.mega-panel[hidden] { display: none; }

.mega-inner {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  /* Matches .wrap on the pm.css pages and .nav-inner on the site.css ones,
     so the panel's first column lines up with the wordmark above it. */
  max-width: 1240px;
  margin: 0 auto;
  padding: 20px 32px 24px;
}
.mega-inner-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 760px; }

/* A product column, keyed to that product's hue. */
.mega-col { --c: var(--accent); --c-ink: var(--accent-press); --c-tint: var(--accent-tint); }
.mega-col[data-accent="bug"] { --c: var(--p-bug); --c-ink: var(--p-bug-ink); --c-tint: var(--p-bug-tint); }
.mega-col[data-accent="pm"]  { --c: var(--p-pm);  --c-ink: var(--p-pm-ink);  --c-tint: var(--p-pm-tint); }
.mega-col[data-accent="lms"] { --c: var(--p-lms); --c-ink: var(--p-lms-ink); --c-tint: var(--p-lms-tint); }

.mega-card {
  display: block;
  padding: 14px 16px;
  border-radius: var(--r-md);
  text-decoration: none;
  transition: background var(--dur-2) ease;
}
.mega-card:hover { background: var(--c-tint); }

/* The product's hue as a blinking square in the card's corner — the same
   cursor that sits on the homepage plates, and the colour cue the status
   line used to carry. The mark's own i-dots are squares, so this is the
   brand's shape rather than a decoration. Keyframes live in pm.css with the
   plates; site.css pages get their own copy. Out of step across the three. */
.mega-card { position: relative; }
.mega-card::after {
  content: "";
  position: absolute;
  top: 14px;
  right: 14px;
  width: 8px;
  height: 8px;
  background: var(--c);
  animation: prod-blink 2.8s steps(1, end) infinite;
}
.mega-col[data-accent="pm"]  .mega-card::after { animation-delay: -0.9s; }
.mega-col[data-accent="lms"] .mega-card::after { animation-delay: -1.9s; }

/* The keyframes, so a page loading site.css (no pm.css) animates too. */
@keyframes prod-blink {
  0%, 62% { opacity: 0.92; }
  62.01%, 78% { opacity: 0.18; }
  78.01%, 100% { opacity: 0.92; }
}
@media (prefers-reduced-motion: reduce) {
  .mega-card::after { animation: none; }
}

/* --- Kept, not used (founder, 2026-09-18) ---------------------------------
   The status line above a product's name in the mega panel. Same pattern as
   .prod-status in pm.css: the markup is gone, the style waits. */
.mega-kicker {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 5px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  color: var(--c-ink);
}
.mega-kicker::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--c); }

.mega-name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  line-height: 1.15;
  color: var(--fg-1);
}
.mega-blurb {
  margin: 5px 0 0;
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-2);
}

.mega-subs { margin: 6px 0 0; padding: 0 0 0 16px; list-style: none; }
.mega-subs a {
  display: block;
  position: relative;
  padding: 7px 0 7px 16px;
  font-family: var(--font-ui);
  font-size: 13.5px;
  color: var(--fg-2);
  text-decoration: none;
  transition: color var(--dur-2) ease;
}
.mega-subs a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 13px;
  width: 6px;
  height: 6px;
  background: var(--c);
  opacity: 0.45;
  transition: opacity var(--dur-2) ease;
}
.mega-subs a:hover { color: var(--c-ink); }
.mega-subs a:hover::before { opacity: 1; }

/* The company column is a plain list, not product cards. */
.mega-links { margin: 0; padding: 0; list-style: none; }
.mega-links a {
  display: block;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--fg-1);
  text-decoration: none;
  transition: background var(--dur-2) ease;
}
.mega-links a:hover { background: var(--bg-cream-deep); }
.mega-links span {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--fg-3);
}

@media (max-width: 900px) {
  .mega { display: none; }
  .mega-panel { display: none !important; }
}
