/* ==========================================================================
   NADIR — Apple-grade presentation layer (dark)
   --------------------------------------------------------------------------
   Design language notes
     · Type is the system SF stack, which renders true SF Pro on Apple devices.
     · Two text colours only: #f5f5f7 for primary, #86868b for secondary.
     · One accent, the NADIR orange, used exclusively for links and state.
     · Surfaces: #000 page, #1d1d1f panels, hairline #2a2a2c rules.
     · Restraint over decoration — no glows on text, no gradients on chrome.
   Loaded last so it wins over styles.css without needing !important.
   ========================================================================== */

body.ap-site {
  --ap-font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    "Inter", "Helvetica Neue", Arial, sans-serif;
  --ap-mono: "SF Mono", "JetBrains Mono", ui-monospace, Menlo, monospace;

  --ap-bg: #000000;
  --ap-panel: #1d1d1f;
  --ap-panel-2: #161617;
  --ap-rule: #2a2a2c;
  --ap-rule-soft: rgba(245, 245, 247, 0.09);

  --ap-text: #f5f5f7;
  --ap-text-dim: #86868b;
  --ap-accent: #ff7a45;
  --ap-accent-hover: #ff9a70;

  /* One measure for every bounded section. Two tiers read as sloppiness
     rather than hierarchy: the left edge visibly jumps as you scroll, which is
     the first thing that makes a page feel improvised. Full-bleed bands are
     the only permitted exception, and their copy still aligns to this measure.
     Long-form text is held to a readable line by ch-based caps on .ap-body and
     .ap-subhead; those caps are set in proportion to this measure so widening
     the container widens the text with it rather than just the whitespace. */
  --ap-page: 1280px;
  --ap-page-wide: 1280px;
  --ap-nav-h: 48px;

  --ap-radius: 18px;
  --ap-radius-lg: 28px;
  --ap-ease: cubic-bezier(0.28, 0.11, 0.32, 1);

  margin: 0;
  color: var(--ap-text);
  background: var(--ap-bg);
  font-family: var(--ap-font);
  font-size: 17px;
  line-height: 1.47;
  letter-spacing: -0.012em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

html.ap-site {
  background: #000;
  scroll-padding-top: calc(var(--ap-nav-h) + 12px);
}

/* styles.css assigns DM Sans across a long list of inline and nav selectors,
   which left 163 elements on the homepage rendering in a different face from
   the headings — the single biggest reason the type felt inconsistent. This
   sets font-family and nothing else; the mono rule directly below restores the
   deliberately monospaced labels at matching specificity. */
body.ap-site :where(*) {
  font-family: var(--ap-font);
}

body.ap-site
  :where(
    .ap-kicker, .ap-rule-label, .ap-stat em, .ap-step b, .ap-code-bar, code,
    pre, kbd, samp
  ) {
  font-family: var(--ap-mono);
}

body.ap-site .site-shell {
  background: var(--ap-bg);
}

body.ap-site ::selection {
  color: #fff;
  background: rgba(255, 122, 69, 0.32);
}

/* ==========================================================================
   1 — Type scale
   ========================================================================== */

body.ap-site h1,
body.ap-site h2,
body.ap-site h3,
body.ap-site h4 {
  font-family: var(--ap-font);
  font-weight: 600;
  color: var(--ap-text);
  text-wrap: balance;
}

.ap-headline {
  margin: 0;
  font-size: clamp(2.6rem, 6.2vw, 4.75rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.022em;
}

.ap-headline-xl {
  font-size: clamp(2.35rem, min(6.4vw, 7.4svh), 5rem);
  letter-spacing: -0.028em;
  line-height: 1.04;
}

.ap-title {
  margin: 0;
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  font-weight: 600;
  line-height: 1.09;
  letter-spacing: -0.018em;
}

.ap-title-sm {
  margin: 0;
  font-size: clamp(1.35rem, 2.2vw, 1.75rem);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.014em;
}

.ap-subhead {
  margin: 1.1rem 0 0;
  max-width: 40ch;
  color: var(--ap-text);
  font-size: clamp(1.15rem, 2vw, 1.6rem);
  font-weight: 500;
  line-height: 1.28;
  letter-spacing: -0.012em;
}

.ap-body {
  margin: 1rem 0 0;
  max-width: 72ch;
  color: var(--ap-text-dim);
  font-size: 1.0625rem;
  line-height: 1.55;
  letter-spacing: -0.008em;
}

.ap-eyebrow {
  margin: 0 0 0.75rem;
  color: var(--ap-accent);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.ap-kicker {
  margin: 0 0 1rem;
  color: var(--ap-text-dim);
  font-family: var(--ap-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.ap-footnote {
  margin: 1.5rem 0 0;
  color: #6e6e73;
  font-size: 0.75rem;
  line-height: 1.5;
  letter-spacing: 0;
}

.ap-center {
  text-align: center;
}

.ap-center .ap-subhead,
.ap-center .ap-body {
  margin-inline: auto;
}

/* ==========================================================================
   2 — Layout primitives
   ========================================================================== */

.ap-wrap {
  width: 100%;
  max-width: var(--ap-page);
  margin: 0 auto;
  padding: 0 22px;
}

.ap-wrap-wide {
  max-width: var(--ap-page-wide);
}

.ap-section {
  padding: clamp(4rem, 9vw, 7.5rem) 0;
}

.ap-section-tight {
  padding: clamp(2.5rem, 5vw, 4rem) 0;
}

/* —— Ambient depth ————————————————————————————————————————————————————————
   A page of flat #000 sections separated by hairlines is legible but airless:
   every band sits on the same plane, so nothing recedes and the panels look
   pasted on rather than lit. This adds an optional two-part backdrop to a
   section — wide colour washes underneath, a fine lattice on top of them — that
   gives the eye a sense of distance behind the content without becoming
   decoration in its own right.

   Alphas are deliberately at the edge of perception (0.03–0.08). The test is
   that toggling the class should not look like a design change; it should look
   like the section gained a floor. Both layers sit at z-index 0 inside an
   isolated stacking context, so no section's backdrop can reach another's.
   —————————————————————————————————————————————————————————————————————————— */
.ap-depth {
  position: relative;
  isolation: isolate;
}

.ap-depth > * {
  position: relative;
  z-index: 1;
}

/* Colour. Two off-axis washes rather than one centred glow: a single radial
   behind the middle of a section reads as a spotlight, whereas an unequal pair
   reads as ambient light arriving from somewhere. Cool and warm are held far
   apart so they never mix into a muddy band through the centre. */
.ap-depth::before {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(
      ellipse 48% 54% at 16% 20%,
      rgba(120, 138, 190, 0.075),
      transparent 66%
    ),
    radial-gradient(
      ellipse 54% 48% at 86% 82%,
      rgba(255, 122, 69, 0.05),
      transparent 68%
    );
  pointer-events: none;
  content: "";
}

/* Structure. The same 88px engineering lattice the hero uses, one size up and
   at a third of the alpha, masked to an ellipse so it never reaches a section
   edge — a grid that meets the edge reads as a texture applied to the page,
   while one that fades out reads as depth behind it. */
.ap-depth::after {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image:
    linear-gradient(to right, rgba(245, 245, 247, 0.026) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(245, 245, 247, 0.026) 1px, transparent 1px);
  background-size: 112px 112px;
  background-position: 50% 50%;
  mask-image: radial-gradient(
    ellipse 62% 58% at 50% 46%,
    #000 0%,
    rgba(0, 0, 0, 0.42) 58%,
    transparent 84%
  );
  pointer-events: none;
  content: "";
}

/* Warm-led: the accent wash comes forward and low, the cool one retreats. Used
   where the section below is dark and needs a warmer hand-off. */
.ap-depth-warm::before {
  background:
    radial-gradient(
      ellipse 60% 56% at 24% 84%,
      rgba(255, 122, 69, 0.07),
      transparent 68%
    ),
    radial-gradient(
      ellipse 46% 44% at 88% 14%,
      rgba(120, 138, 190, 0.045),
      transparent 68%
    );
}

/* Wash only. For sections whose own content is already a grid — a stat strip or
   a spec table — where a second lattice behind it would read as moiré. */
.ap-depth-flat::after {
  display: none;
}

/* —— Dividers: three distinct treatments —— */
.ap-rule {
  height: 1px;
  margin: 0;
  border: 0;
  background: var(--ap-rule);
}

.ap-rule-fade {
  height: 1px;
  margin: 0;
  border: 0;
  background: linear-gradient(
    90deg,
    transparent,
    var(--ap-rule) 18%,
    var(--ap-rule) 82%,
    transparent
  );
}

.ap-rule-label {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  color: var(--ap-text-dim);
  font-family: var(--ap-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.ap-rule-label::before,
.ap-rule-label::after {
  flex: 1;
  height: 1px;
  background: var(--ap-rule);
  content: "";
}

/* ==========================================================================
   3 — Links and buttons
   ========================================================================== */

.ap-link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.18em;
  color: var(--ap-accent);
  font-size: 1.3125rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: color 160ms var(--ap-ease);
}

.ap-link:hover {
  color: var(--ap-accent-hover);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.ap-link::after {
  content: "\203A";
  font-size: 1.05em;
  line-height: 1;
  transform: translateY(0.02em);
}

.ap-link-sm {
  font-size: 1.0625rem;
}

.ap-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 2rem;
  margin-top: 1.6rem;
}

.ap-links-start {
  justify-content: flex-start;
}

.ap-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 1.35rem;
  border: 1px solid transparent;
  border-radius: 100px;
  font-family: var(--ap-font);
  font-size: 1.0625rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  transition:
    background 180ms var(--ap-ease),
    border-color 180ms var(--ap-ease),
    color 180ms var(--ap-ease);
}

.ap-btn-primary {
  color: #1d1008;
  background: var(--ap-accent);
}

.ap-btn-primary:hover {
  background: var(--ap-accent-hover);
}

.ap-btn-secondary {
  color: var(--ap-text);
  border-color: rgba(245, 245, 247, 0.28);
  background: transparent;
}

.ap-btn-secondary:hover {
  border-color: var(--ap-text);
  background: rgba(245, 245, 247, 0.07);
}

.ap-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.ap-center .ap-btn-row {
  justify-content: center;
}

/* ==========================================================================
   4 — Navigation (Apple global nav)
   ========================================================================== */

body.ap-site .site-header {
  position: sticky;
  top: 0;
  z-index: 400;
  height: var(--ap-nav-h);
  border: 0;
  border-bottom: 1px solid rgba(245, 245, 247, 0.06);
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  box-shadow: none;
}

body.ap-site .site-header::before,
body.ap-site .site-header::after {
  display: none;
}

body.ap-site .site-header .nav-wrap {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  width: 100%;
  max-width: var(--ap-page);
  height: var(--ap-nav-h);
  margin: 0 auto;
  padding: 0 22px;
}

/* Brand shrinks to a quiet mark, Apple-style */
body.ap-site .site-header .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex: 0 0 auto;
  text-decoration: none;
}

body.ap-site .site-header .brand-mark img {
  width: 19px;
  height: 19px;
}

body.ap-site .site-header .brand-name,
body.ap-site .site-header .brand-text {
  color: var(--ap-text);
  font-family: var(--ap-font);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

body.ap-site .desktop-nav {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  gap: clamp(0.5rem, 2.2vw, 2rem);
  height: 100%;
}

body.ap-site .nav-cluster {
  position: static;
  display: flex;
  align-items: center;
  height: 100%;
}

body.ap-site .desktop-nav button,
body.ap-site .desktop-nav .nav-direct {
  display: inline-flex;
  align-items: center;
  height: 100%;
  padding: 0 0.2rem;
  border: 0;
  color: rgba(245, 245, 247, 0.82);
  background: none;
  font-family: var(--ap-font);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: -0.005em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color 160ms var(--ap-ease);
}

body.ap-site .desktop-nav .nav-direct:hover {
  color: #fff;
}

body.ap-site .desktop-nav button::after {
  display: none;
}

body.ap-site .desktop-nav button:hover,
body.ap-site .nav-cluster:hover button,
body.ap-site .desktop-nav button[aria-expanded="true"] {
  color: #fff;
}

/* Full-bleed translucent dropdown, matching Apple's global nav behaviour.
   The header carries a backdrop-filter, which makes it the containing block
   for fixed-position descendants — so absolute against the header is the
   correct tool here, not fixed. Selectors are scoped through .nav-cluster to
   outrank the legacy `.nav-cluster:hover .nav-popover` transform rules. */
body.ap-site .site-header {
  overflow: visible;
}

body.ap-site .nav-wrap {
  position: static;
}

body.ap-site .nav-cluster .nav-popover {
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  display: block;
  width: auto;
  min-width: 0;
  max-width: none;
  padding: 2.75rem 0 3.5rem;
  border: 0;
  border-bottom: 1px solid rgba(245, 245, 247, 0.07);
  border-radius: 0;
  /* Near-opaque on purpose. The header above already carries a
     backdrop-filter, which establishes a backdrop root, so a nested
     backdrop-filter here does not blur the page behind the panel — it just
     leaves the hero headline legible straight through the menu. */
  background: #161617;
  box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.72);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-6px);
  transition:
    opacity 220ms var(--ap-ease),
    transform 280ms var(--ap-ease),
    visibility 220ms linear;
}

body.ap-site .nav-cluster:hover .nav-popover,
body.ap-site .nav-cluster:focus-within .nav-popover,
body.ap-site .nav-cluster.open .nav-popover {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}

body.ap-site .nav-mega-intro,
body.ap-site .nav-mega-columns,
body.ap-site .nav-popover-list {
  width: 100%;
  max-width: var(--ap-page);
  margin: 0 auto;
  padding: 0 22px;
  border: 0;
  background: none;
}

body.ap-site .nav-mega-intro {
  margin-bottom: 2rem;
}

body.ap-site .nav-mega-intro small {
  display: block;
  margin-bottom: 0.4rem;
  color: var(--ap-text-dim);
  font-family: var(--ap-font);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

body.ap-site .nav-mega-intro strong {
  display: block;
  color: var(--ap-text);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.014em;
}

body.ap-site .nav-mega-intro p {
  max-width: 52ch;
  margin: 0.5rem 0 0.75rem;
  color: var(--ap-text-dim);
  font-size: 0.875rem;
}

body.ap-site .nav-mega-intro a {
  color: var(--ap-accent);
  font-size: 0.875rem;
  text-decoration: none;
}

body.ap-site .nav-mega-intro a:hover {
  text-decoration: underline;
}

body.ap-site .nav-mega-columns {
  display: grid;
  gap: 2rem 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

body.ap-site .nav-mega-column {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

body.ap-site .nav-mega-column > span {
  margin-bottom: 0.35rem;
  color: var(--ap-text-dim);
  font-family: var(--ap-font);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

body.ap-site .nav-popover-list {
  display: grid;
  gap: 1.6rem 2.5rem;
  /* Three fixed columns rather than auto-fit. auto-fit produced five columns at
     this measure, which left the smaller menus reading as a scattered row of
     links instead of a composed panel. Every menu now has three or six items,
     so the grid always fills. */
  /* Same three tracks as .nav-mega-columns, so every panel in the nav shares
     one column rhythm and items line up as you move between menus. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* subpages.css promotes the featured link into a full-width tinted card. That
   emphasis fights the Apple treatment, where every item in a menu is equal and
   the hierarchy comes from the column headings. */
body.ap-site .nav-popover .nav-featured {
  grid-column: auto;
  margin-bottom: 0;
  border: 0;
  border-radius: 0;
  background: none;
}

body.ap-site .nav-popover a {
  display: block;
  padding: 0;
  border: 0;
  border-radius: 0;
  color: var(--ap-text);
  background: none;
  text-decoration: none;
}

body.ap-site .nav-popover a strong {
  display: block;
  color: var(--ap-text);
  font-size: 1.3125rem;
  font-weight: 600;
  letter-spacing: -0.014em;
  transition: color 140ms var(--ap-ease);
}

body.ap-site .nav-popover a small {
  display: block;
  margin-top: 0.1rem;
  color: var(--ap-text-dim);
  font-size: 0.8125rem;
  letter-spacing: -0.004em;
}

body.ap-site .nav-popover a:hover strong {
  color: var(--ap-accent);
}

body.ap-site .nav-item-index {
  display: none;
}

body.ap-site .nav-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 1.1rem;
}

body.ap-site .nav-link-muted {
  color: rgba(245, 245, 247, 0.82);
  font-size: 0.75rem;
  font-weight: 400;
  text-decoration: none;
}

body.ap-site .nav-link-muted:hover {
  color: #fff;
}

body.ap-site .nav-actions .button-small,
body.ap-site .nav-actions .button-light {
  min-height: 30px;
  padding: 0 0.85rem;
  border: 0;
  border-radius: 100px;
  color: #1d1008;
  background: var(--ap-accent);
  box-shadow: none;
  font-family: var(--ap-font);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}

body.ap-site .nav-actions .button-small:hover {
  background: var(--ap-accent-hover);
}

body.ap-site .menu-button span {
  background: var(--ap-text);
}

/* Opaque, not translucent-with-blur: the header's own backdrop-filter is the
   backdrop root here, so a blur on this panel never samples the page behind it
   and the hero copy read straight through the menu. */
body.ap-site .mobile-menu {
  background: #161617;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* styles.css sizes this panel with `position: fixed; top: var(--header-height);
   bottom: 0`, which assumes the viewport is the containing block. It is not:
   .site-header carries a backdrop-filter, and that establishes a containing
   block for fixed descendants — so the panel resolved against the 44px header
   and collapsed to 44px tall with its links overflowing invisibly behind the
   page. Size it against the header instead: 100% puts the top edge at the
   header's bottom, and the height is stated explicitly. */
@media (max-width: 1100px) {
  body.ap-site .mobile-menu {
    top: 100%;
    right: 0;
    bottom: auto;
    left: 0;
    height: calc(100svh - var(--ap-nav-h));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* ==========================================================================
   5 — Hero
   ========================================================================== */

/* The hero is sized to land whole in the first screen: headline, laptop and
   chapter rail with no scrolling. It is a flex column filling the viewport
   minus the sticky header, so the leftover space goes to the device rather
   than to arbitrary padding. svh, not vh, so mobile browser chrome collapsing
   does not crop the laptop. */
.ap-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: calc(100svh - var(--ap-header-h, 48px));
  padding: clamp(1rem, 2.4vh, 2.25rem) 0 clamp(1rem, 2vh, 1.75rem);
  overflow: hidden;
  text-align: center;
}

/* Backdrop: a wide warm horizon low behind the device, a cooler wash above it,
   and a faint engineering grid that fades out before it reaches the copy.
   Layered rather than one radial so the hero has some depth without becoming
   a gradient showpiece. */
.ap-hero::before {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(245, 245, 247, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(245, 245, 247, 0.045) 1px, transparent 1px);
  background-size: 88px 88px;
  /* Holds the grid to the lower half, so it reads as a floor the device sits
     on instead of graph paper behind the headline. */
  mask-image: radial-gradient(
    ellipse 78% 58% at 50% 88%,
    #000 0%,
    rgba(0, 0, 0, 0.55) 46%,
    transparent 78%
  );
  opacity: 0.9;
  pointer-events: none;
  content: "";
}

.ap-hero::after {
  position: absolute;
  top: -12%;
  left: 50%;
  width: min(150vw, 1900px);
  height: 118%;
  transform: translateX(-50%);
  background:
    radial-gradient(
      ellipse 42% 34% at 50% 74%,
      rgba(255, 122, 69, 0.2),
      transparent 68%
    ),
    radial-gradient(
      ellipse 62% 46% at 50% 96%,
      rgba(255, 101, 52, 0.11),
      transparent 72%
    ),
    radial-gradient(
      ellipse 54% 40% at 50% 6%,
      rgba(120, 138, 190, 0.09),
      transparent 70%
    );
  pointer-events: none;
  content: "";
}

.ap-hero > * {
  position: relative;
  z-index: 1;
}

.ap-hero .ap-headline {
  margin-inline: auto;
  max-width: 20ch;
}

.ap-hero-lede {
  margin: clamp(0.85rem, 1.8vh, 1.35rem) auto 0;
  max-width: 54ch;
  color: var(--ap-text-dim);
  font-size: clamp(1rem, min(1.6vw, 2.2svh), 1.25rem);
  line-height: 1.42;
  letter-spacing: -0.01em;
}

/* Short windows — most laptops at their default resolution. Everything above
   the device competes with it for the same first screen, and the device is the
   part that has to stay readable, so the type and the gaps give ground first.
   Without this the chapter rail lands just below the fold on a 768px window,
   which defeats the point of having built a visible rail. */
@media (max-height: 880px) {
  .ap-hero {
    padding: clamp(0.5rem, 1.4vh, 1.25rem) 0 clamp(0.5rem, 1.2vh, 1rem);
  }

  .ap-headline-xl {
    font-size: clamp(2.1rem, min(6.4vw, 6.6svh), 5rem);
  }

  .ap-hero .ap-hero-lede {
    margin-top: clamp(0.6rem, 1.3vh, 1rem);
  }

  .ap-hero .ap-links {
    margin-top: clamp(0.55rem, 1.2vh, 1rem);
  }

  .ap-hero .ap-link {
    font-size: 1.125rem;
  }
}

/* —— Device stage —————————————————————————————————————————————————————————
   A laptop drawn in CSS rather than a device mockup image: it stays sharp at
   any density, costs nothing to download, and the screen is real DOM, so the
   product demo inside it is selectable, accessible and pixel-crisp.

   Proportions follow a 14" MacBook Pro closely enough to read as one without
   inviting a trademark argument: 16:10 panel, thin uniform bezel, camera in
   the top bezel, a visible hinge, and a deck that tapers to a lighter front
   edge. The lid is unrotated — a perspective tilt looks impressive in a
   screenshot but softens every glyph on the screen, which defeats the point of
   putting a live UI in there.
   —————————————————————————————————————————————————————————————————————————— */
.ap-stage {
  position: relative;
  /* Width is driven by the height still available in the first screen: the panel
     is 16:10, so a given leftover height implies a maximum width. The subtracted
     constant covers the header, headline, lede, links and the chapter controls
     beneath the device — without it the laptop grows to its max width on short
     screens and pushes itself below the fold.

     The 600px floor matters as much as the cap. The console inside is a real UI
     drawn on a 1200px surface and scaled down, so below roughly half scale its
     10px labels stop being readable, and an illegible demo is worse than one
     whose caption needs a single scroll notch on a short window. */
  width: min(1180px, 100%, max(600px, calc((100svh - 31.5rem) * 1.6)));
  min-width: 0;
  margin: clamp(1rem, 2.2vh, 1.85rem) auto 0;
  padding: 0 22px;
}

/* Contact shadow on the floor beneath the deck. */
.ap-stage::before {
  position: absolute;
  bottom: 2.5%;
  left: 50%;
  width: 78%;
  height: 16%;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(0, 0, 0, 0.85),
    transparent 74%
  );
  filter: blur(22px);
  pointer-events: none;
  content: "";
}

/* Warm bounce light, as if the screen were lighting the surface. */
.ap-stage::after {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 64%;
  height: 22%;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse 50% 50% at 50% 0%,
    rgba(255, 122, 69, 0.16),
    transparent 70%
  );
  filter: blur(26px);
  pointer-events: none;
  content: "";
}

.ap-device {
  position: relative;
  z-index: 1;
}

/* Lid: brushed aluminium edge. Three stops rather than two so there is a
   specular band along the top edge and the sides fall off darker. */
.ap-device-lid {
  position: relative;
  z-index: 2;
  padding: clamp(6px, 0.85vw, 11px);
  border-radius: clamp(10px, 1.1vw, 15px) clamp(10px, 1.1vw, 15px) 4px 4px;
  background:
    linear-gradient(
      177deg,
      #6a6a70 0%,
      #3c3c41 3%,
      #2a2a2e 28%,
      #202024 72%,
      #16161a 100%
    );
  box-shadow:
    /* outer contact shadow */
    0 34px 60px -26px rgba(0, 0, 0, 0.92),
    /* crisp edge against the page */
    0 0 0 1px rgba(0, 0, 0, 0.6),
    /* top specular highlight */
    0 1px 0 rgba(255, 255, 255, 0.14) inset,
    /* left and right edge light */
    1px 0 0 rgba(255, 255, 255, 0.05) inset,
    -1px 0 0 rgba(255, 255, 255, 0.05) inset;
}

.ap-device-bezel {
  position: relative;
  overflow: hidden;
  /* 16:10, matching both a MacBook panel and the walkthrough stage's own
     design ratio, so the demo fills it without letterboxing. */
  aspect-ratio: 16 / 10;
  border-radius: clamp(5px, 0.6vw, 8px);
  background: #000;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.95) inset,
    0 2px 12px rgba(0, 0, 0, 0.7) inset;
}

/* Camera, centred in the top bezel. Small and dark — a bright dot would read
   as a dead pixel. */
.ap-device-camera {
  position: absolute;
  top: clamp(2px, 0.32vw, 4px);
  left: 50%;
  z-index: 4;
  width: clamp(3px, 0.4vw, 5px);
  height: clamp(3px, 0.4vw, 5px);
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #34343a, #0a0a0c 70%);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.8);
}

.ap-device-screen {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #0a0a0b;
}

/* Screen reflection. Kept very low: a strong diagonal sheen is the fastest way
   to make a real UI look like a stock mockup, and it hurts legibility. */
.ap-device-glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  background:
    linear-gradient(
      118deg,
      rgba(255, 255, 255, 0.055) 0%,
      rgba(255, 255, 255, 0.014) 16%,
      transparent 38%
    ),
    /* faint darkening into the corners, as glass does */
      radial-gradient(
        ellipse 96% 90% at 50% 46%,
        transparent 62%,
        rgba(0, 0, 0, 0.26) 100%
      );
  pointer-events: none;
}

/* Hinge: the dark seam between lid and deck. */
.ap-device-hinge {
  position: relative;
  z-index: 3;
  width: 26%;
  height: clamp(3px, 0.4vw, 5px);
  margin: 0 auto;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(180deg, #0b0b0d 0%, #1c1c20 60%, #0d0d0f 100%);
}

/* Deck: wider than the lid, tapering to a bright front lip. The clip-path
   trims the lower corners so the front edge reads as a chamfer rather than a
   slab. */
/* Only slightly wider than the lid. At 114% it read as a shelf the laptop was
   sitting on rather than as the body of the machine. */
.ap-device-deck {
  position: relative;
  z-index: 1;
  width: 103.5%;
  height: clamp(7px, 0.85vw, 11px);
  margin: 0 auto;
  transform: translateX(-1.69%);
  border-radius: 1px 1px clamp(4px, 0.5vw, 7px) clamp(4px, 0.5vw, 7px);
  background: linear-gradient(
    180deg,
    #48484d 0%,
    #333338 30%,
    #202025 66%,
    #101013 100%
  );
  box-shadow:
    0 16px 26px -14px rgba(0, 0, 0, 0.95),
    0 1px 0 rgba(255, 255, 255, 0.1) inset;
  /* Chamfered front edge. */
  clip-path: polygon(0 0, 100% 0, 98.8% 100%, 1.2% 100%);
}

/* The lip you press to open the lid. */
.ap-device-deck::before {
  position: absolute;
  top: 0;
  left: 50%;
  width: 14%;
  height: 42%;
  transform: translateX(-50%);
  border-radius: 0 0 5px 5px;
  background: linear-gradient(180deg, rgba(8, 8, 10, 0.9), transparent);
  content: "";
}

/* —— Demo chapter rail —————————————————————————————————————————————————————
   Six named segments, each of which fills as its chapter plays. The earlier
   version of this was six 6px dots, which was honest about the chapter count
   and nothing else: it gave no names, no sense of how long a chapter runs, and
   no hint that the dots were clickable. A segmented scrubber answers all three
   at a glance and is the shape people already read as "parts of a thing".
   —————————————————————————————————————————————————————————————————————————— */
.ap-demo-controls {
  width: min(1020px, 100%);
  margin: clamp(0.7rem, 1.5vh, 1rem) auto 0;
  padding: 0 22px;
}

.ap-demo-bar {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ap-demo-nav,
.ap-demo-play {
  display: grid;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  color: #a1a1a6;
  cursor: pointer;
  place-items: center;
  transition:
    border-color 0.2s ease,
    background-color 0.2s ease,
    color 0.2s ease;
}

.ap-demo-nav:hover,
.ap-demo-play:hover {
  border-color: rgba(255, 122, 69, 0.5);
  background: rgba(255, 122, 69, 0.1);
  color: #fff;
}

.ap-demo-nav svg,
.ap-demo-play svg {
  width: 13px;
  height: 13px;
}

.ap-demo-nav svg {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.ap-demo-play svg {
  fill: currentColor;
}

/* One icon is shown at a time; which one depends on the paused state. */
.ap-demo-play .ap-demo-icon-play,
.ap-demo-controls.is-paused .ap-demo-play .ap-demo-icon-pause {
  display: none;
}

.ap-demo-controls.is-paused .ap-demo-play .ap-demo-icon-play {
  display: block;
}

.ap-demo-controls.is-paused .ap-demo-play {
  border-color: rgba(255, 122, 69, 0.55);
  color: var(--ap-accent);
}

.ap-demo-rail {
  display: flex;
  flex: 1;
  gap: 6px;
  min-width: 0;
  /* Horizontal overflow is the fallback on narrow screens; hero-demo.js keeps
     the active chapter scrolled into view. */
  overflow-x: auto;
  scrollbar-width: none;
}

.ap-demo-rail::-webkit-scrollbar {
  display: none;
}

.ap-demo-chip {
  position: relative;
  display: flex;
  flex: 1 1 0;
  align-items: baseline;
  gap: 7px;
  min-width: 92px;
  padding: 9px 2px 0;
  border: 0;
  background: none;
  color: #6e6e73;
  cursor: pointer;
  font: inherit;
  text-align: left;
  transition: color 0.25s ease;
}

.ap-demo-chip:hover {
  color: #d6d6da;
}

.ap-demo-chip.is-active {
  color: var(--ap-text);
}

.ap-demo-chip.is-done {
  color: #8b8b90;
}

/* The progress track sits above the label, so the row of tracks reads as one
   continuous scrubber broken into chapters. */
.ap-demo-chip-track {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 3px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.11);
}

.ap-demo-chip-track i {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: var(--ap-accent);
  transform: scaleX(0);
  transform-origin: left center;
}

.ap-demo-chip.is-done .ap-demo-chip-track i {
  background: rgba(255, 122, 69, 0.45);
}

.ap-demo-chip-num {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  opacity: 0.75;
}

.ap-demo-chip-label {
  overflow: hidden;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: -0.008em;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ap-demo-caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.65rem;
  margin: 0.6rem 0 0;
}

.ap-demo-step {
  color: var(--ap-accent);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
}

.ap-demo-caption strong {
  color: var(--ap-text);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.012em;
}

.ap-demo-caption > span:last-of-type {
  color: var(--ap-muted);
  font-size: 0.8125rem;
  line-height: 1.45;
}

.ap-demo-expand {
  margin-left: auto;
  color: var(--ap-accent);
  font-size: 0.8125rem;
  text-decoration: none;
  white-space: nowrap;
}

.ap-demo-expand:hover {
  text-decoration: underline;
}

@media (max-width: 760px) {
  .ap-demo-chip-label {
    display: none;
  }

  .ap-demo-chip {
    min-width: 0;
  }

  .ap-demo-caption {
    justify-content: center;
  }
}

/* The walkthrough card's own frame would be a second bezel inside the laptop's
   bezel, so it is flattened to fill the screen exactly. */
.ap-device-screen .ap-demo-wrap {
  position: absolute;
  inset: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: #0a0b0a;
  aspect-ratio: auto;
}

.ap-device-screen .ap-demo-wrap::after {
  display: none;
}

/* No layout overrides are needed here any more. The walkthrough's design canvas
   now derives its height from whatever stage it is mounted in, so the console
   fills this 16:10 panel exactly instead of being letterboxed inside it. */

/* ==========================================================================
   6 — Tile grid
   ========================================================================== */

.ap-tiles {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ap-tiles-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Top-lit, not flat-filled. A single hairline of light along the top edge plus a
   short gradient falling away beneath it is what separates a surface that looks
   raised from one that looks like a rectangle of a different grey. The outer
   shadow is wide and weak, so the tile appears to float a few millimetres off
   the page rather than casting a card shadow. */
.ap-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 480px;
  border-radius: var(--ap-radius-lg);
  background:
    linear-gradient(
      180deg,
      rgba(245, 245, 247, 0.05) 0%,
      rgba(245, 245, 247, 0) 44%
    ),
    var(--ap-panel);
  box-shadow:
    inset 0 1px 0 rgba(245, 245, 247, 0.07),
    0 1px 2px rgba(0, 0, 0, 0.45),
    0 26px 52px -30px rgba(0, 0, 0, 0.9);
  color: var(--ap-text);
  text-decoration: none;
  isolation: isolate;
}

.ap-tile-span {
  grid-column: 1 / -1;
  min-height: 420px;
}

.ap-tile-copy {
  position: relative;
  z-index: 2;
  padding: clamp(1.75rem, 3vw, 2.75rem);
  text-align: center;
}

.ap-tile-copy-start {
  text-align: left;
}

.ap-tile-copy .ap-kicker {
  margin-bottom: 0.6rem;
}

.ap-tile-copy .ap-title-sm {
  max-width: 30ch;
  margin-inline: auto;
}

.ap-tile-copy-start .ap-title-sm {
  margin-inline: 0;
}

.ap-tile-copy p {
  margin: 0.6rem auto 0;
  max-width: 48ch;
  color: var(--ap-text-dim);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.ap-tile-copy-start p {
  margin-inline: 0;
}

.ap-tile-media {
  position: relative;
  z-index: 1;
  flex: 1;
  min-height: 200px;
  overflow: hidden;
}

.ap-tile-media img,
.ap-tile-media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.001);
  transition: transform 900ms var(--ap-ease);
}

.ap-tile:hover .ap-tile-media img,
.ap-tile:hover .ap-tile-media video {
  transform: scale(1.035);
}

/* Full-bleed image tile with overlaid copy */
.ap-tile-immersive {
  justify-content: flex-end;
  min-height: 540px;
}

.ap-tile-immersive .ap-tile-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.ap-tile-immersive .ap-tile-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ap-tile-immersive::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.88) 0%,
    rgba(0, 0, 0, 0.45) 38%,
    rgba(0, 0, 0, 0.06) 70%
  );
  pointer-events: none;
  content: "";
}

.ap-tile-link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.2em;
  margin-top: 1.1rem;
  color: var(--ap-accent);
  font-size: 1rem;
}

.ap-tile-link::after {
  content: "\203A";
}

.ap-tile:hover .ap-tile-link {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* ==========================================================================
   7 — Full-bleed band
   ========================================================================== */

.ap-band {
  position: relative;
  overflow: hidden;
  min-height: clamp(420px, 62vh, 640px);
  display: flex;
  align-items: center;
}

.ap-band-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.ap-band-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ap-band::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    100deg,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(0, 0, 0, 0.62) 42%,
    rgba(0, 0, 0, 0.22) 78%
  );
  content: "";
}

/* —— Right-edge falloff ————————————————————————————————————————————————————
   A full-bleed plate reads as a stock banner when its detail runs hard into
   both viewport edges: the photograph is wider than every other element on the
   page, so the eye clocks the mismatch. This lands a second scrim on top of the
   legibility gradient that takes the right side down to page black just past
   the content measure, plus a shallow top and bottom falloff. The visible
   subject then occupies roughly the same width as the copy above and below it,
   and the band dissolves into the page rather than being cut off by it.

   Stops are expressed against the measure, not in percentages, so the falloff
   begins at the same place on a 1440px display as on a 2560px one instead of
   creeping inward as the viewport grows. */
.ap-band-fade-right::before {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      to right,
      transparent 0,
      transparent calc(50% + var(--ap-page) * 0.12),
      rgba(0, 0, 0, 0.42) calc(50% + var(--ap-page) * 0.34),
      rgba(0, 0, 0, 0.82) calc(50% + var(--ap-page) * 0.5),
      #000 100%
    ),
    linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.55) 0%,
      transparent 22%,
      transparent 74%,
      rgba(0, 0, 0, 0.7) 100%
    );
  pointer-events: none;
  content: "";
}

.ap-band-inner {
  position: relative;
  z-index: 2;
  width: 100%;
}

.ap-band-copy {
  max-width: 54ch;
}

/* —— Generated backdrop ————————————————————————————————————————————————————
   A canvas figure fades its own four edges to transparency, so the band needs
   no full-frame scrim — one would flatten the lit core the figure exists to
   produce. What is left is a scrim over the left third only, sized to the copy
   measure, which is the one place artwork and text actually overlap. */
.ap-band-figure {
  min-height: clamp(440px, 66vh, 700px);
}

.ap-band-figure::after {
  background: linear-gradient(
    100deg,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(0, 0, 0, 0.8) 24%,
    rgba(0, 0, 0, 0.45) 44%,
    rgba(0, 0, 0, 0.14) 58%,
    transparent 70%
  );
}

.ap-band-bg canvas {
  position: absolute;
  inset: 0;
}

/* Real capture frames carry HUD overlays and saturated detection boxes, which
   compete with the copy laid over them. Desaturating and darkening the plate
   demotes it to a background, and a heavier scrim keeps the body text at a
   readable contrast across the full measure rather than only at the left edge. */
.ap-band-photo .ap-band-bg img {
  filter: saturate(0.45) brightness(0.6) contrast(1.04);
}

.ap-band-photo::after {
  background: linear-gradient(
    100deg,
    rgba(0, 0, 0, 0.94) 0%,
    rgba(0, 0, 0, 0.82) 46%,
    rgba(0, 0, 0, 0.5) 100%
  );
}

/* ==========================================================================
   8 — Stat strip
   ========================================================================== */

.ap-stats {
  display: grid;
  gap: 2.5rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  padding: clamp(2.5rem, 5vw, 4rem) 0;
  border-top: 1px solid var(--ap-rule);
  border-bottom: 1px solid var(--ap-rule);
}

.ap-stat strong {
  display: block;
  color: var(--ap-text);
  font-size: clamp(1.9rem, 3.1vw, 2.7rem);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.028em;
  white-space: nowrap;
}

.ap-stat span {
  display: block;
  margin-top: 0.65rem;
  max-width: 30ch;
  color: var(--ap-text-dim);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.ap-stat em {
  display: block;
  margin-top: 0.4rem;
  color: #6e6e73;
  font-family: var(--ap-mono);
  font-size: 0.6875rem;
  font-style: normal;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ==========================================================================
   9 — Numbered steps
   ========================================================================== */

.ap-steps {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: clamp(2rem, 4vw, 3.25rem);
  border: 1px solid var(--ap-rule);
  border-radius: var(--ap-radius);
  background: var(--ap-rule);
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(245, 245, 247, 0.06),
    0 24px 52px -32px rgba(0, 0, 0, 0.9);
}

/* The four cells share one light source, so the sheen is per-cell but faint
   enough that the row still reads as a single slab broken by its dividers
   rather than four separately lit cards. */
.ap-step {
  padding: clamp(1.5rem, 2.6vw, 2.15rem);
  background:
    linear-gradient(
      180deg,
      rgba(245, 245, 247, 0.026) 0%,
      rgba(245, 245, 247, 0) 56%
    ),
    var(--ap-panel-2);
}

.ap-step b {
  display: block;
  margin-bottom: 1.35rem;
  color: var(--ap-accent);
  font-family: var(--ap-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
}

.ap-step strong {
  display: block;
  color: var(--ap-text);
  font-size: 1.1875rem;
  font-weight: 600;
  letter-spacing: -0.012em;
}

.ap-step p {
  margin: 0.5rem 0 0;
  color: var(--ap-text-dim);
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* ==========================================================================
   9b — Offer panel
   ========================================================================== */

.ap-panel {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: center;
  padding: clamp(1.75rem, 3.4vw, 3rem);
  border-radius: var(--ap-radius-lg);
  background:
    linear-gradient(
      180deg,
      rgba(245, 245, 247, 0.05) 0%,
      rgba(245, 245, 247, 0) 38%
    ),
    var(--ap-panel);
  box-shadow:
    inset 0 1px 0 rgba(245, 245, 247, 0.07),
    0 1px 2px rgba(0, 0, 0, 0.45),
    0 26px 52px -30px rgba(0, 0, 0, 0.9);
}

.ap-panel-copy p {
  margin: 0.7rem 0 0;
  max-width: 54ch;
  color: var(--ap-text-dim);
  font-size: 0.9375rem;
  line-height: 1.55;
}

.ap-checklist {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ap-checklist li {
  position: relative;
  padding-left: 1.6rem;
  color: var(--ap-text);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.ap-checklist li::before {
  position: absolute;
  top: 0.42em;
  left: 0;
  width: 0.85rem;
  height: 0.46rem;
  border-left: 1.6px solid var(--ap-accent);
  border-bottom: 1.6px solid var(--ap-accent);
  transform: rotate(-45deg);
  content: "";
}

/* ==========================================================================
   10 — Split feature row
   ========================================================================== */

.ap-split {
  display: grid;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ap-split-media {
  overflow: hidden;
  border-radius: var(--ap-radius);
  background: var(--ap-panel);
}

.ap-split-media img {
  display: block;
  width: 100%;
  height: auto;
}

.ap-split-reverse .ap-split-media {
  order: -1;
}

/* ==========================================================================
   10b — Code surface
   --------------------------------------------------------------------------
   Shown beside integration copy. Deliberately plain: a syntax theme with six
   colours would fight the one-accent rule, so this uses the two text greys
   plus the accent for string literals only.
   ========================================================================== */

.ap-code {
  overflow: hidden;
  border: 1px solid var(--ap-rule);
  border-radius: var(--ap-radius);
  background: var(--ap-panel-2);
  box-shadow: 0 24px 52px -32px rgba(0, 0, 0, 0.9);
}

.ap-code-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 1.1rem;
  border-bottom: 1px solid var(--ap-rule);
  color: var(--ap-text-dim);
  font-family: var(--ap-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ap-code-tag {
  color: #30d158;
}

.ap-code pre {
  margin: 0;
  overflow-x: auto;
  padding: 1.15rem 1.1rem 1.35rem;
}

.ap-code code {
  color: var(--ap-text-dim);
  font-family: var(--ap-mono);
  font-size: 0.8125rem;
  line-height: 1.65;
  letter-spacing: 0;
  white-space: pre;
}

.ap-code .k {
  color: var(--ap-text);
}

.ap-code .s {
  color: var(--ap-accent);
}

.ap-code .n {
  color: #ff9a70;
}

.ap-code .c {
  color: rgba(134, 134, 139, 0.62);
}

/* Inline code inside spec definitions. */
body.ap-site .ap-spec dd code {
  color: var(--ap-text);
  font-family: var(--ap-mono);
  font-size: 0.8em;
  letter-spacing: 0;
}

/* Centred body copy needs its ch cap re-centred, not removed. */
.ap-body-center {
  margin-left: auto;
  margin-right: auto;
}

/* ==========================================================================
   11 — Spec list
   ========================================================================== */

.ap-specs {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border-top: 1px solid var(--ap-rule);
  background: var(--ap-rule);
}

.ap-spec {
  padding: 1.5rem 0 1.5rem;
  padding-inline: 0 1.5rem;
  background: var(--ap-bg);
}

.ap-spec dt {
  color: var(--ap-text-dim);
  font-size: 0.8125rem;
  font-weight: 500;
}

.ap-spec dd {
  margin: 0.35rem 0 0;
  color: var(--ap-text);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* ==========================================================================
   12 — Logo row
   ========================================================================== */

.ap-logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem 2.75rem;
  margin-top: 2rem;
}

.ap-logos span {
  color: #6e6e73;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  transition: color 200ms var(--ap-ease);
}

.ap-logos span:hover {
  color: var(--ap-text-dim);
}

/* ==========================================================================
   13 — Accordion (Apple support style)
   ========================================================================== */

body.ap-site .faq-grid {
  display: block;
  max-width: 960px;
  margin: clamp(1.5rem, 3vw, 2.5rem) auto 0;
  border-top: 1px solid var(--ap-rule);
}

body.ap-site .faq-item {
  border: 0;
  border-bottom: 1px solid var(--ap-rule);
  border-radius: 0;
  background: none;
}

body.ap-site .faq-item > button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
  padding: 1.35rem 0;
  border: 0;
  color: var(--ap-text);
  background: none;
  font-family: var(--ap-font);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-align: left;
  cursor: pointer;
}

body.ap-site .faq-item > button:hover {
  color: var(--ap-accent);
}

body.ap-site .faq-item > button i {
  position: relative;
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
}

body.ap-site .faq-item > button i::before,
body.ap-site .faq-item > button i::after {
  position: absolute;
  top: 50%;
  left: 0;
  width: 13px;
  height: 1.5px;
  background: currentColor;
  content: "";
  transition: transform 240ms var(--ap-ease);
}

body.ap-site .faq-item > button i::after {
  transform: rotate(90deg);
}

body.ap-site .faq-item > button[aria-expanded="true"] i::after {
  transform: rotate(0deg);
}

body.ap-site .faq-answer {
  padding: 0 0 1.5rem;
}

body.ap-site .faq-answer p {
  margin: 0;
  max-width: 78ch;
  color: var(--ap-text-dim);
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* ==========================================================================
   14 — Closing CTA
   ========================================================================== */

.ap-closing {
  position: relative;
  overflow: hidden;
  padding: clamp(4.5rem, 9vw, 8rem) 0;
  text-align: center;
}

.ap-closing::before {
  position: absolute;
  bottom: -40%;
  left: 50%;
  width: min(140vw, 1600px);
  height: 100%;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(255, 101, 52, 0.16),
    transparent 68%
  );
  pointer-events: none;
  content: "";
}

.ap-closing > * {
  position: relative;
  z-index: 1;
}

.ap-closing-mark {
  display: block;
  width: 46px;
  height: 46px;
  margin: 0 auto 1.75rem;
}

/* ==========================================================================
   15 — Footer (Apple fine print)
   ========================================================================== */

body.ap-site .site-footer {
  padding: 0;
  border-top: 1px solid var(--ap-rule);
  background: var(--ap-bg);
}

body.ap-site .site-footer .container {
  max-width: var(--ap-page);
  padding: 2.5rem 22px 3rem;
}

body.ap-site .footer-top {
  display: block;
  padding: 0;
  border: 0;
}

body.ap-site .footer-brand {
  max-width: 72ch;
  margin-bottom: 2.25rem;
}

body.ap-site .footer-brand .brand-name,
body.ap-site .footer-brand .brand-text {
  color: var(--ap-text);
  font-family: var(--ap-font);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none;
}

body.ap-site .footer-brand p {
  margin: 0.85rem 0 0;
  color: #6e6e73;
  font-size: 0.75rem;
  line-height: 1.55;
  letter-spacing: 0;
}

body.ap-site .footer-location {
  display: inline-block;
  margin-top: 0.65rem;
  color: #6e6e73;
  font-size: 0.75rem;
  letter-spacing: 0;
}

body.ap-site .footer-links {
  display: grid;
  gap: 1.75rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  padding-top: 1.75rem;
  border-top: 1px solid var(--ap-rule);
}

body.ap-site .footer-links > div {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

body.ap-site .footer-links strong {
  margin-bottom: 0.25rem;
  color: var(--ap-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
}

body.ap-site .footer-links a {
  color: #86868b;
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0;
  text-decoration: none;
}

body.ap-site .footer-links a:hover {
  color: var(--ap-text);
  text-decoration: underline;
}

body.ap-site .footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--ap-rule);
}

body.ap-site .footer-bottom,
body.ap-site .footer-bottom span,
body.ap-site .footer-bottom a {
  color: #6e6e73;
  font-size: 0.75rem;
  letter-spacing: 0;
}

body.ap-site .footer-bottom a {
  text-decoration: none;
}

body.ap-site .footer-bottom a:hover {
  text-decoration: underline;
}

body.ap-site .footer-bottom > div {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
}

/* ==========================================================================
   16 — Scroll reveal
   ========================================================================== */

body.ap-site .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 900ms var(--ap-ease),
    transform 900ms var(--ap-ease);
}

body.ap-site .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   17 — Subpage harmonisation
   --------------------------------------------------------------------------
   Generated product/article pages reuse legacy component classes; these rules
   pull them into the same palette and rhythm without touching the generator.
   ========================================================================== */

body.ap-site.subpage .page-hero {
  padding: clamp(3.5rem, 7vw, 6rem) 0 clamp(2.5rem, 5vw, 4rem);
  background: radial-gradient(
      ellipse 70% 60% at 50% 0%,
      rgba(255, 101, 52, 0.1),
      transparent 68%
    ),
    var(--ap-bg);
}

body.ap-site.subpage .page-hero h1 {
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.06;
}

body.ap-site.subpage .page-hero p,
body.ap-site.subpage .page-hero .page-lede {
  color: var(--ap-text-dim);
  letter-spacing: -0.008em;
}

body.ap-site .breadcrumbs,
body.ap-site .breadcrumbs a,
body.ap-site .breadcrumbs span {
  color: #6e6e73;
  font-family: var(--ap-font);
  font-size: 0.75rem;
  letter-spacing: 0;
  text-transform: none;
}

body.ap-site .bento-card,
body.ap-site .detail-card,
body.ap-site .spec-card,
body.ap-site .product-media-frame,
body.ap-site .comparison-shell,
body.ap-site .module-card {
  border: 1px solid var(--ap-rule);
  border-radius: var(--ap-radius);
  background: var(--ap-panel);
  box-shadow: none;
}

body.ap-site .section-heading h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.85rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.1;
}

body.ap-site .section-heading p {
  color: var(--ap-text-dim);
}

body.ap-site .eyebrow {
  color: var(--ap-accent);
  font-family: var(--ap-font);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

body.ap-site .button-primary {
  min-height: 44px;
  border: 0;
  border-radius: 100px;
  color: #1d1008;
  background: var(--ap-accent);
  box-shadow: none;
  font-family: var(--ap-font);
  font-size: 1.0625rem;
  font-weight: 400;
}

body.ap-site .button-primary:hover {
  background: var(--ap-accent-hover);
}

body.ap-site .button-ghost {
  min-height: 44px;
  border: 1px solid rgba(245, 245, 247, 0.28);
  border-radius: 100px;
  color: var(--ap-text);
  background: transparent;
  font-family: var(--ap-font);
  font-size: 1.0625rem;
  font-weight: 400;
}

body.ap-site .button-ghost:hover {
  border-color: var(--ap-text);
  background: rgba(245, 245, 247, 0.07);
}

body.ap-site .text-link {
  color: var(--ap-accent);
  font-weight: 400;
}

/* ==========================================================================
   18 — Responsive
   ========================================================================== */

@media (max-width: 1180px) {
  body.ap-site .desktop-nav {
    justify-content: flex-end;
    gap: 1.15rem;
  }

  /* Below this the band's copy is no longer confined to the left half of the
     measure, so the scrim has to follow it right. The figure mutes itself over
     the same threshold; the two are a pair. */
  .ap-band-figure::after {
    background: linear-gradient(
      100deg,
      rgba(0, 0, 0, 0.9) 0%,
      rgba(0, 0, 0, 0.85) 32%,
      rgba(0, 0, 0, 0.62) 56%,
      rgba(0, 0, 0, 0.24) 74%,
      transparent 88%
    );
  }
}

/* Collapse to the hamburger at the same 1100px breakpoint styles.css uses.
   These need the same `body.ap-site` prefix as the rules above, because a
   media query adds no specificity of its own. */
@media (max-width: 1100px) {
  body.ap-site .desktop-nav,
  body.ap-site .nav-actions .nav-link-muted {
    display: none;
  }

  body.ap-site .site-header .nav-wrap {
    justify-content: space-between;
    gap: 0.75rem;
  }

  body.ap-site .menu-button {
    display: grid;
    width: 40px;
    height: 40px;
    border: 0;
    background: transparent;
  }

  body.ap-site .nav-actions {
    gap: 0.6rem;
    margin-left: auto;
  }
}

@media (max-width: 520px) {
  body.ap-site .nav-actions .button-small,
  body.ap-site .nav-actions .button-light {
    padding: 0 0.7rem;
    font-size: 0.7rem;
  }
}

@media (max-width: 900px) {
  .ap-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ap-panel {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 860px) {
  .ap-tiles,
  .ap-tiles-3 {
    grid-template-columns: 1fr;
  }

  .ap-tile {
    min-height: 400px;
  }

  .ap-split,
  .ap-split-reverse {
    grid-template-columns: 1fr;
  }

  .ap-split-reverse .ap-split-media {
    order: 0;
  }

  .ap-band {
    min-height: 460px;
  }

  .ap-band::after {
    background: linear-gradient(
      to top,
      rgba(0, 0, 0, 0.92) 0%,
      rgba(0, 0, 0, 0.6) 52%,
      rgba(0, 0, 0, 0.35) 100%
    );
  }

  /* No composition left to protect on a phone — the copy covers the canvas
     edge to edge — so the directional scrim becomes an even one. The figure
     mutes itself to match; both are needed, because at this width the body
     copy runs over the lit core rather than beside it. */
  .ap-band-figure::after {
    background: linear-gradient(
      to top,
      rgba(0, 0, 0, 0.9) 0%,
      rgba(0, 0, 0, 0.78) 50%,
      rgba(0, 0, 0, 0.72) 100%
    );
  }

  /* The copy runs the full width here, so a right-edge falloff would only be
     darkening the text. The vertical blend into the page is kept. */
  .ap-band-fade-right::before {
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.45) 0%,
      transparent 24%,
      transparent 76%,
      rgba(0, 0, 0, 0.6) 100%
    );
  }
}

@media (max-width: 600px) {
  body.ap-site {
    font-size: 16px;
  }

  .ap-steps {
    grid-template-columns: 1fr;
  }

  .ap-links {
    flex-direction: column;
    align-items: center;
    gap: 0.85rem;
  }

  .ap-stage {
    padding: 0 14px;
  }

  .ap-device-lid {
    padding: 6px 6px 8px;
    border-radius: 12px;
  }

  .ap-tile-copy {
    padding: 1.5rem 1.25rem;
  }
}

/* ==========================================================================
   Generative figure sections
   ========================================================================== */

body.ap-site .fig-grid {
  display: grid;
  gap: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* A band figure is 64:21 and carries its own detail, so it never shares a row. */
body.ap-site .fig-grid-band {
  grid-template-columns: 1fr;
}

body.ap-site .fig-card {
  margin: 0;
  padding: 0;
  border: 1px solid rgba(245, 245, 247, 0.08);
  border-radius: 18px;
  background: rgba(245, 245, 247, 0.02);
  overflow: hidden;
}

body.ap-site .fig-card .nadir-figure {
  border-bottom: 1px solid rgba(245, 245, 247, 0.06);
}

body.ap-site .fig-card figcaption {
  padding: 0.9rem 1.15rem 1.05rem;
  color: var(--ap-text-dim);
  font-family: var(--ap-font);
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: -0.004em;
}

@media (max-width: 640px) {
  body.ap-site .fig-grid {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Planned nav entries — text, not links
   ========================================================================== */

/* Centred on the same track as .nav-popover-list, with the list's 22px gutter
   plus the item's own 0.9rem inset, so the note sits flush with the titles. */
body.ap-site .nav-planned-note {
  width: 100%;
  max-width: var(--ap-page);
  margin: 0 auto 0.5rem;
  padding: 0 calc(22px + 0.9rem);
  color: var(--ap-orange);
  font-family: var(--ap-font);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Matches .nav-popover-list a geometry so planned menus and Company line up. */
body.ap-site .nav-planned-item {
  display: block;
  padding: 0.6rem 0.9rem;
  border-radius: 12px;
  cursor: default;
}

body.ap-site .nav-planned-item strong {
  display: block;
  color: rgba(245, 245, 247, 0.58);
  font-family: var(--ap-font);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

body.ap-site .nav-planned-item small {
  display: block;
  margin-top: 0.15rem;
  color: rgba(245, 245, 247, 0.32);
  font-family: var(--ap-font);
  font-size: 0.75rem;
  letter-spacing: -0.004em;
}

/* styles.css fonts the mobile panel's links via `.mobile-menu nav a`, which a
   span does not match — without this the planned names fell back to the mono
   stack and read as code. */
body.ap-site .mobile-menu .mobile-planned {
  display: flex;
  align-items: center;
  min-height: 40px;
  color: rgba(245, 245, 247, 0.42);
  font-family: var(--ap-font);
  font-size: 0.92rem;
  font-weight: 400;
  letter-spacing: -0.01em;
}
