/* ─── Site tokens: the values the Niro DS does not define ────────────────────
   Not a compat shim. Every legacy v1 alias that merely renamed a DS token has
   been migrated out of the markup, so what is left here are values the DS has
   no equivalent for and that still have to flip with the theme:

     - the status ramp, because the DS status tokens do not flip for light mode
       and the site needs AA contrast on paper surfaces (logged in
       DESIGN-MIGRATION.md);
     - the alpha ladder, because a component must not hard-code black or white
       to tint whatever surface it happens to sit on.

   Anything added here needs that same justification. If the DS names it, use
   the DS name in the markup instead. */

:root {
  /* Height of the sticky nav. Not a DS value — it is this site's chrome, and
     three separate things have to agree with it: the bar itself, the anchor
     offset that keeps a linked heading out from under it, and any section
     asking to fill the screen, which must ask for the screen minus this.
     It was a literal 74 in each, so the hero quietly sat a nav-height low. */
  --nav-h: 74px;
}

:root,
[data-theme="dark"] {
  /* status ramp — DS values in dark, darkened below for light */
  --accent-red:   var(--status-error);
  --accent-amber: var(--status-warning);
  --accent-indigo: var(--status-info);

  /* alpha ladder — tint of the surface underneath, not a colour of its own */
  --text-alpha-mid:   rgba(255,255,255,0.55);
  --text-alpha-faint: rgba(255,255,255,0.25);
  --border-alpha:     rgba(255,255,255,0.10);
  --surface-alpha-md: rgba(255,255,255,0.08);
}

[data-theme="light"] {
  --accent-red:   #DC2626;
  --accent-amber: #B45309;
  --accent-indigo: #4F46E5;

  --text-alpha-mid:   rgba(0,0,0,0.68);
  --text-alpha-faint: rgba(0,0,0,0.52);
  --border-alpha:     rgba(0,0,0,0.10);
  --surface-alpha-md: rgba(0,0,0,0.06);
}

/* No inner element may scroll the document sideways. A wide table or a fixed
   stage that outgrows its container used to put a scrollbar on <html>, and the
   page then opened already scrolled — clipping the logo and the first
   characters of every heading. Each such element still gets its own
   overflow-x: auto; this is the backstop, not the mechanism.

   It lives here rather than in site.css because this is the only stylesheet
   every page links — integrations.html loads the design system and this file
   and nothing else. */
/* A theme flip rewrites dozens of tokens at once. Every element carrying a
   colour transition then tries to *animate* between themes, and the animation
   does not converge: 129 properties across 119 elements were measured still
   holding the previous theme's colour indefinitely. The visible one was the
   beta email field, whose border sat at dark ink on a near-black ground.

   Transitions exist for interactions, not for repainting the whole page. The
   theme setters in chrome.js and component.js stamp this attribute, swap, and
   drop it after a paint. */
html[data-theme-switching] *,
html[data-theme-switching] *::before,
html[data-theme-switching] *::after { transition: none !important; }

html { overflow-x: clip; }
body { overflow-x: clip; max-width: 100vw; }

/* FAQ disclosure rows. Native <details>/<summary> — the open/close state, the
   keyboard handling and the aria-expanded a screen reader reads are all the
   platform's, so there is no accordion controller to load, break or version.
   name="faq" makes the group exclusive where the browser supports it, and
   simply allows several open where it does not, which is the harmless side of
   that fallback.

   It lives in this file rather than styles/site.css because this is the
   stylesheet every page links, integrations.html included. */

/* Two columns, because one is wrong here. A row of hairline questions run
   across the full 1400px shell sets 15px type on a 1272px line and leaves the
   right half of every row empty — the same dead-margin problem the `measure`
   rule exists to catch, one level up at the layout. The heading takes the left
   column and stays put while the answers move under the reader's eye. */
.faqsec .shell,
.faqsec .shellm {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  gap: var(--space-8) var(--space-16);
  align-items: start;
}
.faqsec .shell > :first-child,
.faqsec .shellm > :first-child {
  position: sticky; top: calc(var(--nav-h) + var(--space-8));
}
/* below this the two columns would each be too narrow to read, so stack them
   and let the heading scroll away like any other */
@media (max-width: 1080px) {
  .faqsec .shell,
  .faqsec .shellm { grid-template-columns: 1fr; gap: var(--space-6); }
  .faqsec .shell > :first-child,
  .faqsec .shellm > :first-child { position: static; }
}

.faq { border-top: 1px solid var(--border-alpha); }
.faq details { border-bottom: 1px solid var(--border-alpha); }
.faq summary {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-5); padding: var(--space-5) 0; cursor: pointer;
  list-style: none; /* Firefox's marker */
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary h3 {
  margin: 0; font-size: var(--size-lead); font-weight: var(--weight-semibold);
  line-height: var(--leading-snug); letter-spacing: var(--tracking-heading);
  color: var(--text-primary); text-wrap: pretty;
}
/* the chevron is a rotated corner rather than an svg, so it inherits colour
   and needs no per-page markup */
.faq summary::after {
  content: ''; flex: 0 0 auto; width: 10px; height: 10px; margin-top: 9px;
  border-right: 1.5px solid var(--text-faint);
  border-bottom: 1.5px solid var(--text-faint);
  transform: rotate(45deg);
  transition: transform var(--dur-mid) var(--ease-niro), border-color var(--dur-fast) var(--ease-niro);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover h3 { color: var(--a0i); }
.faq summary:hover::after { border-color: var(--a0i); }
.faq summary:focus-visible { outline: 2px solid var(--a0i); outline-offset: 4px; border-radius: var(--radius-xs); }
.faq details > p {
  margin: 0 0 var(--space-5); max-width: 62ch;
  font-size: var(--size-ui); line-height: var(--leading-prose);
  color: var(--text-muted); text-wrap: pretty;
}
@media (prefers-reduced-motion: reduce) {
  .faq summary::after { transition: none; }
}

/* ─── The site footer ────────────────────────────────────────────────────────
   One block, duplicated into every page for the same reason the nav is: markup
   the page ships beats markup JS paints in afterwards. Duplication rots, so
   test/nav-parity.test.js asserts the copies carry the same links in the same
   order, and that every one of them resolves.

   Classes rather than inline styles, unlike the rest of this site: fourteen
   inline copies of forty declarations is exactly the thing that drifts. It
   lives in this file because this is the stylesheet every page links. */
.n-foot {
  position: relative; z-index: 1;
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-page);
  padding: var(--space-24) 0 var(--space-12);
}
.n-fgrid {
  display: grid;
  grid-template-columns: 1.6fr repeat(4, 1fr);
  gap: var(--space-12);
  margin-bottom: var(--space-14);
}
.n-fmark { display: block; width: 112px; height: 34px; margin-bottom: 20px; color: var(--text-primary); }
.n-fsay { font-size: 14px; line-height: 1.7; color: var(--text-muted); max-width: 300px; }
.n-fcol { display: flex; flex-direction: column; gap: 12px; }
.n-fhead {
  font-family: var(--font-mono); font-size: var(--size-eyebrow);
  font-weight: var(--weight-bold); letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px;
}
.n-flink { font-size: 14px; color: var(--text-muted); transition: color 0.2s var(--ease-niro); }

/* The legal bar. A registered office and a company number are what a buyer's
   procurement team looks for, and all four legal pages assert them, so they
   belong on every page rather than only on the pages that repeat them. */
.n-fbar {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
  padding-top: var(--space-6);
  border-top: 1px solid var(--border-subtle);
  font-family: var(--font-mono); font-size: var(--size-eyebrow);
  line-height: 1.9; color: var(--text-muted);
}
.n-fbar a { color: inherit; transition: color 0.2s var(--ease-niro); }
.n-freg { max-width: 68ch; }

/* The hero install surface. The command box is a hairline panel rather than a
   terminal chrome: the hero already carries a canvas behind it, and a second
   dark rectangle in front of that reads as a hole. Sized off the command, not
   the column, so it does not stretch to the hero's full measure. */
.n-inst { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-bottom: clamp(14px, 3vh, 28px); max-width: 100%; }
.n-inst-lab {
  font-family: var(--font-mono); font-size: var(--size-eyebrow);
  font-weight: var(--weight-bold); letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase; color: var(--text-muted);
}
/* Opaque, not a tint: the hero paints an animated node field behind this, and
   a translucent panel let the moving lines read straight through the command.
   The shadow is what lifts it off that field rather than a heavier border. */
.n-inst-box {
  display: flex; align-items: center; gap: var(--space-4);
  max-width: 100%; padding: 12px 14px 12px 18px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface-card); box-shadow: var(--shadow-panel);
}
.n-inst-cmd {
  font-family: var(--font-mono); font-size: var(--size-body);
  color: var(--text-primary); white-space: nowrap;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.n-inst-caret { color: var(--a0); margin-right: 8px; }
.n-inst-copy {
  flex-shrink: 0; border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-mono); font-size: var(--size-micro);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--text-muted); padding: 4px 6px;
}

/* Social under the tagline. Each brand path fills its 24-unit viewBox
   differently - LinkedIn is a solid square, YouTube and Discord are shorter
   glyphs - so the svg boxes differ in order to make the drawn ink match.
   The chips give the three marks one shared silhouette: without them a bare
   Discord mascot sits next to two badges and reads as the odd one out. */
.n-fsoc { display: flex; align-items: center; gap: var(--space-3); margin-top: 20px; }
.n-fsoc a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle); color: var(--text-muted);
  transition: color 0.2s var(--ease-niro), border-color 0.2s var(--ease-niro), background 0.2s var(--ease-niro);
}

@media (hover: hover) and (pointer: fine) {
  .n-flink:hover, .n-fbar a:hover { color: var(--text-primary); }
  .n-fsoc a:hover { color: var(--text-primary); border-color: var(--border-strong); background: var(--surface-wash); }
}
@media (max-width: 1180px) { .n-fgrid { grid-template-columns: 1fr 1fr 1fr; } }
@media (max-width: 900px)  { .n-fgrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px)  { .n-fgrid { grid-template-columns: 1fr; } }

/* Visually hidden, still read aloud. A section whose heading is carried by the
   design rather than by type — the deployment picker sits under the hero and
   needs no title above it — still owes a screen reader one, and skipping the
   level would break the document outline instead. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
