/* ==================================================================== *
 * COMPOSITION BASE, folded in 2026-09-05.
 *
 * The ten preview routes used to load capability-composition.css and then
 * spend a whole layer undoing its character caps. The base is now carried
 * here, ONCE, with those caps removed at the source rather than
 * out-specified: no 62ch measure, no 72ch intro, no auto margins that
 * centre a capped block, no 72ch on a centred paragraph. Those pages link
 * this file alone.
 *
 * capability-composition.css is no longer linked by any page (lane
 * one-sheet, 2026-09-05): this file is the one band stylesheet for every
 * page except Home.
 * ==================================================================== */

/* The shell owns horizontal gutters; avoid stacking fixed section gutters
   on top, so desktop gutters remain the same viewport proportion at 4K. */
.ptrcx-section { padding-inline: 0 !important; }
.ptrcx-shell {
  width: 100%;
  box-sizing: border-box;
  padding-inline: clamp(20px, 4vw, 240px);
  max-width: 6000px;
  margin-inline: auto;
}
.ptrcx-shell > * { min-width: 0; }

/* The legacy block names keep their LAYOUT part (they occupy their column)
   and lose their cap and auto-centring, which the base used to carry here
   as 62ch / 72ch measures and margin-inline:auto. The block spans the
   column; the type keeps the site scale. */
.ptrcx-measure, .ptrcx-center, .ptrcx-intro { width: 100%; box-sizing: border-box; }

/* ---------- feature (media + copy) ---------- */
.ptrcx-feature {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.ptrcx-feature--reverse { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
.ptrcx-feature--reverse .ptrcx-feature__media { order: 2; }
.ptrcx-feature--reverse .ptrcx-feature__copy { order: 1; }
.ptrcx-feature__media { min-width: 0; overflow: hidden; border-radius: clamp(16px, 2vw, 24px); }
.ptrcx-feature__media img, .ptrcx-feature__media video {
  width: 100%; height: 100%; display: block; object-fit: cover;
}
.ptrcx-feature__copy { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
@media (max-width: 900px) {
  .ptrcx-feature, .ptrcx-feature--reverse { grid-template-columns: minmax(0, 1fr) !important; }
  .ptrcx-feature__media, .ptrcx-feature--reverse .ptrcx-feature__media,
  .ptrcx-feature__copy, .ptrcx-feature--reverse .ptrcx-feature__copy { order: initial !important; }
}

/* ---------- balanced card grids ---------- */
.ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
.ptrcx-grid-7, .ptrcx-grid-8 {
  display: grid;
  gap: clamp(16px, 2.2vw, 26px);
}
.ptrcx-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ptrcx-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ptrcx-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ptrcx-grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ptrcx-grid-8 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* 5 -> 3+2 and 7 -> 4+3: a twelve-unit track for 7 (four items span three
   units for a four-across row, three items span four units for a
   three-across row); 5 reuses the six-unit track already proven by the
   existing .xrex-grid component, generalised the same way. */
.ptrcx-grid-5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.ptrcx-grid-5 > *:nth-child(-n+3) { grid-column: span 2; }
.ptrcx-grid-5 > *:nth-child(n+4) { grid-column: span 3; }
.ptrcx-grid-7 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
.ptrcx-grid-7 > *:nth-child(-n+4) { grid-column: span 3; }
.ptrcx-grid-7 > *:nth-child(n+5) { grid-column: span 4; }

/* Collapse straight to a single column under 760px rather than passing
   through a fragile two-column state that could itself orphan (a 5-item
   or 3-item grid at 2 columns leaves a lone last row) - the same
   single-column-below-1000 philosophy .xrex-grid already uses, just at a
   narrower threshold since these grids read fine down to tablet width. */
@media (max-width: 760px) {
  .ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
  .ptrcx-grid-7, .ptrcx-grid-8 {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  .ptrcx-grid-2 > *, .ptrcx-grid-3 > *, .ptrcx-grid-4 > *, .ptrcx-grid-5 > *,
  .ptrcx-grid-6 > *, .ptrcx-grid-7 > *, .ptrcx-grid-8 > * {
    grid-column: span 1 !important;
  }
}

/* ---------- sequence / steps row ---------- */
.ptrcx-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: clamp(10px, 1.6vw, 18px);
}
.ptrcx-steps > * {
  flex: 1 1 clamp(120px, 16vw, 220px);
  min-width: 0;
}
.ptrcx-steps > .ptrcx-steps__arrow {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  opacity: 0.55;
}
@media (max-width: 700px) {
  .ptrcx-steps { flex-direction: column; }
  .ptrcx-steps > .ptrcx-steps__arrow { transform: rotate(90deg); padding-left: 6px; }
}

/* ---------- supporting cards (auto-fit, no fixed count) ---------- */
.ptrcx-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(16px, 2.2vw, 26px);
}

@media (prefers-reduced-motion: reduce) {
  .ptrcx-shell, .ptrcx-feature, .ptrcx-steps,
  .ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
  .ptrcx-grid-7, .ptrcx-grid-8, .ptrcx-cards {
    scroll-behavior: auto;
  }
}

/* ---------- video-tile collection, capped columns (added by the
   industries/case-study composition pass, 2026-09-04) ----------
   The industry and case-study families carry loose collections of practice
   loops (5 to 21 tiles per section) that used to render as
   repeat(auto-fit, minmax(300px,1fr)) inside a sticky-column-narrowed
   main column: at 1440-2560px that auto-fit math alone still yields 4-5
   columns, which is the "cramped 4-up tiles" the operator named. This
   caps the column count outright (3 max, never 4+) rather than letting
   available width decide it, so tile scale stays readable at every
   width; pair with data-composition="balanced" and pull one tile out as
   a .ptrcx-feature above the grid whenever the remaining count would
   otherwise leave a lone last-row item (count mod 3 == 1). */
.ptrcx-vgrid3 {
  display: grid;
  gap: clamp(16px, 2vw, 24px);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 900px) {
  .ptrcx-vgrid3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .ptrcx-vgrid3 { grid-template-columns: minmax(0, 1fr) !important; }
}

/* Desktop page contract, 2026-09-04.
   Home does not load this stylesheet. Keep the established mobile layout,
   except for restoring the broken video grid's existing mobile rules above.
   Legacy "center" class names are retained for authored/prerendered parity;
   on desktop they now mean readable copy anchored to its containing column.
   The shell owns outer gutters, copy owns reading width, collections fill
   the shell. Never independently center a label, heading or paragraph. */
@media (min-width: 761px) {
  :root {
    --ptr-page-gutter: clamp(24px, 4vw, 160px);
    --ptr-section-space: clamp(32px, 3vw, 48px);
    --ptr-card-gap: 24px;
  }

  .ptrcx-shell { padding-inline: var(--ptr-page-gutter); }
  .ptrcx-section {
    padding-block: var(--ptr-section-space) !important;
    margin-block: 0 !important;
    text-align: left !important;
    align-items: stretch !important;
  }
  .ptrcx-section:has(h1) { padding-top: 132px !important; }
  :is(.ptrcx-measure, .ptrcx-center, .ptrcx-intro) {
    margin-inline: 0 !important;
    text-align: left !important;
    align-self: start;
  }
  .ptrcx-section .ptrcx-intro { align-items: flex-start; }
  section:has(> .ptrcx-center):not(.ptrcx-section) {
    padding-inline: var(--ptr-page-gutter) !important;
  }
  section:not(.ptrcx-section) > div.ptrcx-center { max-width: none !important; }
  .ptrcx-section :is(h1, h2, h3) { text-align: left !important; }
  .ptrcx-section h1 { line-height: 1.1 !important; }
  .ptrcx-section :is(h2, h3) { line-height: 1.2 !important; }
  .ptrcx-section .ptrcx-actions { justify-content: flex-start; }
  .ptrcx-section figcaption {
    text-align: left !important;
    align-self: stretch;
    width: 100%;
    max-width: none !important;
    box-sizing: border-box;
  }
  .ptrcx-feature { align-items: start; }
  .ptrcx-feature > .ptrcx-intro { max-width: none; }
  .ptrcx-section .csCols > :first-child { container-type: inline-size; }

  /* A few authored sections put their introduction before the shell. */
  .ptrcx-section > :is(h1, h2, h3, p, .ptrcx-intro, .ptrcx-center) {
    margin-inline: var(--ptr-page-gutter) !important;
    width: calc(100% - 2 * var(--ptr-page-gutter));
  }

  /* Full-width video collections. Grid placement supersedes old flex-basis
     declarations; explicit child resets defeat the old odd-item width cap.
     Six tracks permit equal thirds and a final pair of equal halves. */
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) {
    display: grid !important;
    grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
    gap: var(--ptr-card-gap) !important;
    width: 100%;
    max-width: none !important;
    margin-inline: 0 !important;
  }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-child(n):nth-child(n):nth-child(n) {
    grid-column: span 2;
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    box-sizing: border-box;
  }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :only-child { grid-column: 1 / -1 !important; }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-last-child(2):nth-child(3n+1),
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-last-child(2):nth-child(3n+1) ~ *,
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-last-child(4):nth-child(3n+1),
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-last-child(4):nth-child(3n+1) ~ * {
    grid-column: span 3 !important;
  }
  .ptrcx-grid-7, .ptrcx-grid-8 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ptrcx-grid-7 > :nth-child(n), .ptrcx-grid-8 > :nth-child(n) { grid-column: span 2; }
  .ptrcx-grid-7 > :nth-child(n+4), .ptrcx-grid-8 > :nth-child(n+7) { grid-column: span 3; }

  /* The footer group and the top nav are styled ONLY by their own
     components. The closing-band, What clients say, Talk to Us, page-end
     and top-nav overrides that used to sit here are removed: the operator
     ruled them out, and the reference for those bands is RELEASE 17
     (0452a35), which carries no rule in this file that targets them. No
     rule in this stylesheet may name .wcs*, .ldb*, .asd*, .ttu*,
     .ptrFooter* or #ptrTopNavBar. */
}

/* Detail-page evidence rails must not squeeze the main video collection
   into thumbnail-sized columns on laptops. */
@media (min-width: 761px) and (max-width: 1200px) {
  .ptrcx-section .csCols { grid-template-columns: minmax(0, 1fr) !important; }
  .ptrcx-section .csRail { position: static; }
}
@media (min-width: 1201px) {
  @container (max-width: 880px) {
    html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
    html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-child(n):nth-child(n):nth-child(n):nth-child(n) { grid-column: span 1 !important; }
    html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :last-child:nth-child(odd):nth-child(n):nth-child(n) { grid-column: 1 / -1 !important; }
  }
}

@media (min-width: 761px) and (max-width: 1000px) {
  .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
  .ptrcx-grid-8 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8) > :nth-child(n) { grid-column: span 1; }
  :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8) > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :nth-child(n):nth-child(n):nth-child(n):nth-child(n) { grid-column: span 1 !important; }
  html body .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3) > :last-child:nth-child(odd):nth-child(n):nth-child(n) { grid-column: 1 / -1 !important; }
}

/*
 * DESKTOP RULES PREVIEW, 2026-09-05.
 *
 * Linked ONLY by the six pages in the approval preview (/xr, /about/story,
 * /work/industries, /work/industries/healthcare-medical,
 * /learn/xr/what-is-xr, /news). Every rule is scoped to `.ptrdr
 * .ptrcx-section` or to a `.ptrdr-*` class this file introduces, so nothing
 * here can reach the top nav, Home, or the footer group (What clients say,
 * the logo marquee, the Labs and AI Studio demo bands, Talk to Us, the page
 * end): none of those carries a .ptrcx-section.
 *
 * What it does, in the operator's order:
 *   1  FULL WIDTH TEXT. Removes the four cap layers on these pages: the
 *      per-page `.<page>-copy` measure, `.ptrcx-center` at 72ch,
 *      `.ptrcx-intro` at 72ch with auto margins, and inline max-widths on
 *      headings and leads. The BLOCK spans the content edges; the TYPE stays
 *      at the site scale, so a two-line heading fills the row instead of
 *      wrapping early inside an island with an empty right side.
 *   2  Routing pill rows render as a centred honeycomb (.ptrdr-pills). One
 *      of only two centred exceptions; Talk to Us is the other and is owned
 *      elsewhere.
 *   5  Placeholder tiles (.ptrdr-ph) take a real tile's slot: the same 16:9
 *      ground, the same caption slot, muted, and a one line scene brief.
 *   8/9 Media and copy pairs (.ptrdr-srow) fill the row. Copy to the RIGHT of
 *      the tile is right aligned the way the footer's right-hand blocks are;
 *      copy to the LEFT is left aligned; the sides alternate down the page.
 *   12 Citation and award lists run as one column (.ptrdr-citelist,
 *      .ptrdr-awardlist), each entry carrying its own image slot.
 *
 *   Row cap: 3 tiles across from 1200px, 2 between 761 and 1199, 1 below.
 */

/* The four cap layers this file used to undo are gone at their source:
   the composition base above carries no character cap, and the pages
   name their blocks instead of styling them inline. Nothing to undo.
   2026-09-05 (lane one-sheet): every page except Home now links this
   file alone; capability-composition.css is no longer linked by any
   page. The .ptrdr scope is carried on every page root. */

/* ------------------------------------------------------------------ *
 * Row cap. 3 across on desktop, 2 on a laptop, 1 on mobile.
 * ------------------------------------------------------------------ */
@media (min-width: 761px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3, .ptrdr-tiles) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3, .ptrdr-tiles) > :nth-child(n):nth-child(n):nth-child(n):nth-child(n) {
    grid-column: span 1 !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8) > :nth-child(n) {
    grid-column: span 1 !important;
  }
}
@media (min-width: 1200px) {
  html body .ptrdr .ptrcx-section .ptrdr-tiles {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: var(--ptr-card-gap, 24px) !important;
    width: 100%;
    max-width: none !important;
    margin-inline: 0 !important;
  }
}
@media (max-width: 760.98px) {
  .ptrdr .ptrdr-tiles { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
}
.ptrdr .ptrdr-tiles { display: grid; gap: var(--ptr-card-gap, 24px); width: 100%; }

/* ------------------------------------------------------------------ *
 * 2. Routing pills, centred honeycomb. A centred exception on purpose.
 * ------------------------------------------------------------------ */
.ptrdr .ptrdr-pills {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ptrdr .ptrdr-pills > li { display: flex; }
.ptrdr .ptrdr-pills a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 26px;
  border-radius: 26px;
  border: 1px solid rgba(11, 13, 18, 0.14);
  background: #fff;
  color: #0B0D12;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}
.ptrdr .ptrdr-pills a:hover { background: #F1F1F4; }
.ptrdr .ptrdr-pillhead {
  width: 100%;
  text-align: center !important;
  margin: 0 0 14px;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #63656E;
}

/* ------------------------------------------------------------------ *
 * 5. Placeholder tile. Same slot, same caption slot, muted ground.
 * ------------------------------------------------------------------ */
.ptrdr .ptrdr-ph {
  margin: 0;
  border-radius: 20px;
  overflow: hidden;
  background: #fff;
  border: 1px solid rgba(11, 13, 18, 0.08);
  display: flex;
  flex-direction: column;
}
.ptrdr .ptrdr-ph__slot {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #F1F1F4;
}
.ptrdr .ptrdr-ph__slot img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}
.ptrdr .ptrdr-ph__dot {
  position: absolute;
  left: 14px;
  bottom: 13px;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: #A8AAB4;
  box-shadow: 0 0 0 4px rgba(110, 112, 122, 0.16);
}
.ptrdr .ptrdr-ph figcaption {
  margin: 0;
  padding: 14px 16px;
  font-size: 13px;
  line-height: 1.5;
  color: #6E707A;
}
.ptrdr .ptrdr-ph__lab {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8A5A2B;
  margin-bottom: 4px;
}

/* ------------------------------------------------------------------ *
 * 8 and 9. Media and copy pairs. The row always fills; copy on the
 * right reads right, copy on the left reads left, sides alternate.
 * ------------------------------------------------------------------ */
.ptrdr .ptrdr-sectors { width: 100%; display: grid; grid-auto-rows: 1fr; }
.ptrdr .ptrdr-srow {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 45fr) minmax(0, 55fr);
  gap: clamp(24px, 3vw, 56px);
  align-items: center;
  padding: clamp(24px, 2.8vw, 44px) 0;
  border-top: 1px solid rgba(11, 13, 18, 0.08);
}
.ptrdr .ptrdr-srow:first-child { border-top: 0; padding-top: 0; }
.ptrdr .ptrdr-srow--rev { grid-template-columns: minmax(0, 55fr) minmax(0, 45fr); }
.ptrdr .ptrdr-srow--rev .ptrdr-smedia { order: 2; }
.ptrdr .ptrdr-srow--rev .ptrdr-scopy { order: 1; }
.ptrdr .ptrdr-smedia {
  min-width: 0;
  margin: 0;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid rgba(11, 13, 18, 0.08);
  background: #fff;
}
.ptrdr .ptrdr-smedia video, .ptrdr .ptrdr-smedia img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
.ptrdr .ptrdr-smedia figcaption {
  margin: 0;
  padding: 12px 15px;
  font-size: 13px;
  line-height: 1.5;
  color: #4B4D57;
}
.ptrdr .ptrdr-scopy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(10px, 1.1vw, 16px);
}
.ptrdr .ptrdr-scopy > * { width: 100%; max-width: none !important; margin: 0; }
.ptrdr .ptrdr-scopy h3 {
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
  font-size: clamp(22px, 2.2vw, 32px);
  text-wrap: balance;
}
.ptrdr .ptrdr-scopy .ptrdr-sdesc {
  font-size: clamp(15px, 1.3vw, 19px);
  line-height: 1.5;
  color: #4B4D57;
  text-wrap: pretty;
}
@media (min-width: 900px) {
  .ptrdr .ptrdr-srow:not(.ptrdr-srow--rev) .ptrdr-scopy {
    text-align: right !important;
    align-items: flex-end;
  }
  .ptrdr .ptrdr-srow:not(.ptrdr-srow--rev) .ptrdr-scopy > * { text-align: right !important; }
  .ptrdr .ptrdr-srow--rev .ptrdr-scopy { text-align: left; align-items: flex-start; }
}
@media (max-width: 899.98px) {
  .ptrdr .ptrdr-sectors { grid-auto-rows: auto; }
  .ptrdr .ptrdr-srow, .ptrdr .ptrdr-srow--rev { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .ptrdr .ptrdr-srow--rev .ptrdr-smedia, .ptrdr .ptrdr-srow--rev .ptrdr-scopy { order: initial; }
}

/* ------------------------------------------------------------------ *
 * 12. Citation and award lists: one column, an image slot each.
 * ------------------------------------------------------------------ */
.ptrdr .ptrdr-citelist, .ptrdr .ptrdr-awardlist {
  width: 100%;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 18px);
}
.ptrdr .ptrdr-citerow {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, clamp(160px, 18%, 260px)) minmax(0, 1fr);
  gap: clamp(16px, 2vw, 32px);
  align-items: center;
  border: 1px solid rgba(11, 13, 18, 0.08);
  border-radius: 16px;
  background: #fff;
  padding: clamp(12px, 1.2vw, 18px);
}
.ptrdr .ptrdr-citepic {
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  background:
    repeating-linear-gradient(135deg, #E9EAEF 0 14px, transparent 14px 28px),
    #F1F1F4;
  aspect-ratio: 4 / 3;
}
.ptrdr .ptrdr-citepic img, .ptrdr .ptrdr-citepic video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ptrdr .ptrdr-citecopy { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.ptrdr .ptrdr-citecopy > * { margin: 0; max-width: none !important; }
.ptrdr .ptrdr-citecopy h3, .ptrdr .ptrdr-citecopy h4 {
  font-size: clamp(17px, 1.5vw, 24px);
  letter-spacing: -0.015em;
  line-height: 1.25;
}
.ptrdr .ptrdr-citemeta { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: #6E707A; }
.ptrdr .ptrdr-citesrc { font-size: 14px; line-height: 1.55; color: #4B4D57; }
@media (max-width: 767.98px) {
  .ptrdr .ptrdr-citerow { grid-template-columns: minmax(0, 1fr); }
}

/* Timeline and feature pairs that alternate sides. Media left, copy right:
   the copy reads right, the way the footer's right-hand blocks do. */
@media (min-width: 900px) {
  /* The picture column sizes to the picture (it keeps its own shape and is
     never cropped), and the copy takes the slack, so no row ends with a gap
     between the picture and the words. Sides are set by explicit columns
     rather than `order`, so the track sizes follow the side that is shown. */
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature {
    grid-template-columns: minmax(0, 1fr) fit-content(45%) !important;
  }
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature > :first-child { grid-column: 1; grid-row: 1; }
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature > :nth-child(2) { grid-column: 2; grid-row: 1; }
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature.ptrdr-rev {
    grid-template-columns: fit-content(45%) minmax(0, 1fr) !important;
  }
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature.ptrdr-rev > :first-child { grid-column: 2; grid-row: 1; }
  .ptrdr .ptrcx-section .tlEntry.ptrcx-feature.ptrdr-rev > :nth-child(2) { grid-column: 1; grid-row: 1; }
  .ptrdr .ptrcx-section .ptrcx-feature.ptrdr-rev > :first-child,
  .ptrdr .ptrcx-section .ptrcx-feature.ptrdr-rev > :first-child > * { text-align: right !important; }
  .ptrdr .ptrcx-section .ptrcx-feature.ptrdr-rev .tlYear { justify-content: flex-end; }
}

/* ------------------------------------------------------------------ *
 * Blocks must OCCUPY the row, not shrink-wrap inside it.
 * capability-composition.css sets align-items:flex-start on
 * .ptrcx-intro, and several authored cards are flex columns that
 * shrink-wrap their own children. In a full-width page every one of
 * those has to stretch, or a kicker reads as a 100px island in a
 * 920px row (measured: 28 such kickers on /xr alone).
 * ------------------------------------------------------------------ */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .ptrcx-intro,
  html body .ptrdr .ptrcx-section .ptrcx-feature__copy,
  html body .ptrdr .ptrcx-section .nwCard,
  html body .ptrdr .ptrcx-section .vcCard,
  html body .ptrdr .ptrcx-section .tlEntry,
  html body .ptrdr .ptrcx-section .tlEntry > div,
  html body .ptrdr .ptrcx-section .ptrdr-scopy,
  html body .ptrdr .ptrcx-section .ptrdr-citecopy,
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .ptrcx-cards,
    .ptr-vgrid, .ptrcx-vgrid3, .nwGrid, .nwPressGrid, .nwWatchGrid,
    .nwResearchGrid, .xrex-grid) > *,
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .ptrcx-cards,
    .nwGrid, .nwPressGrid, .xrex-grid) > * > div {
    align-items: stretch !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-intro, .ptrcx-center, .ptrcx-measure,
    .ptrcx-feature__copy, .ptrdr-scopy, .ptrdr-citecopy) > :is(h1, h2, h3, h4, p, ul, ol, div, blockquote) {
    width: 100%;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-2, .ptrcx-grid-3, .ptrcx-grid-4,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .ptrcx-cards,
    .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid) > * :is(h1, h2, h3, h4, p, ul, ol, blockquote) {
    width: 100%;
  }
}


/* ------------------------------------------------------------------ *
 * Rule 8: a row never leaves the right side empty.
 * Six tracks, two per card (three across), and the tail of a grid
 * re-spans rather than orphaning: one leftover card takes the whole
 * row, two leftover cards take a half each. Same idiom the shared
 * .ptr-vgrid already uses, applied to every card grid on these pages.
 * ------------------------------------------------------------------ */
@media (min-width: 1200px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) {
    display: grid !important;
    grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
    gap: var(--ptr-card-gap, 24px) !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > * { grid-column: span 2 !important; }
  /* A lone card takes the whole row. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :only-child { grid-column: 1 / -1 !important; }
  /* Tail re-span so a row is never 3 + 1 (operator, 2026-09-05: "four items
     were better as a 2x2 / dont get why its 3 and 1"). Counting from the END:
     a trailing pair takes a half each (5 -> 3+2, 8 -> 3+3+2), and a trailing
     FOUR becomes two halves and two halves (4 -> 2+2, 7 -> 3+2+2). */
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :nth-last-child(2):nth-child(3n+1),
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :nth-last-child(2):nth-child(3n+1) ~ *,
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :nth-last-child(4):nth-child(3n+1),
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :nth-last-child(4):nth-child(3n+1) ~ * { grid-column: span 3 !important; }
}
@media (min-width: 761px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: var(--ptr-card-gap, 24px) !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > * { grid-column: span 1 !important; }
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8, .ptrcx-cards, .nwGrid, .nwPressGrid, .nwWatchGrid, .xrex-grid,
    .ptrdr-tiles) > :last-child:nth-child(odd) { grid-column: 1 / -1 !important; }
}

/* Timeline media: the WHOLE picture, never a crop.
   Operator, 2026-09-05, on the Everyday Inclusion tile: "This picture is
   cut off". A 4:3 frame with object-fit:cover was cutting a 3:2 source,
   and it was my own frame, added to stop a 1291x1960 portrait towering
   over its copy. Both are fixed by bounding the picture instead of
   reshaping it: the image keeps its own aspect, is never wider than its
   column and never taller than the bound, and is centred in the cell.
   Nothing is cropped and nothing towers. */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .tlFig {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  html body .ptrdr .ptrcx-section .tlFig > img {
    width: auto !important;
    height: auto !important;
    max-width: 100%;
    max-height: 520px;
    aspect-ratio: auto !important;
    object-fit: contain !important;
  }
  html body .ptrdr .ptrcx-section .tlFig > figcaption { width: 100%; }
}


/* ------------------------------------------------------------------ *
 * Operator review of the /xr preview, 2026-09-05.
 * ------------------------------------------------------------------ */
@media (min-width: 761px) {
  /* 1. Media and copy pairs: the copy block's vertical centre sits on the
     tile's centre, and the copy fills its column edge to edge. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature, .tlEntry, .ptrdr-srow) {
    align-items: center !important;
  }
  html body .ptrdr .ptrcx-section .ptrcx-feature > * { width: 100%; max-width: none !important; }

  /* 5. One body style for running copy. A pair's paragraphs used to be set
     two sizes and two colours apart from the rest of the page. */
  html body .ptrdr .ptrcx-section .ptrcx-feature__copy > p {
    font-size: clamp(16px, 1.8vw, 20px) !important;
    line-height: 1.55 !important;
    color: #33353D !important;
    font-weight: 400 !important;
  }

  /* 6. The stat row spans the content edges. repeat(auto-fit, ...) opened
     more tracks than there were figures, so the last one sat short of the
     right edge while the first sat on the left one. */
  html body .ptrdr .ptrcx-section #materStats {
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
    width: 100%;
    margin-inline: 0 !important;
  }

  /* 3. Flow diagram. */
  html body .ptrdr .ptrcx-section .xrflow { width: 100%; max-width: none; }
}
@media (max-width: 760.98px) {
  html body .ptrdr .ptrcx-section #materStats { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .ptrdr .ptrcx-section .xrflow { min-width: 640px; }
  .ptrdr .ptrcx-section .xrflow-scroll { overflow-x: auto; }
}

/* 2. Nothing is pill-shaped unless it is a link or a control. The four
   "Perspective & empathy" style labels on /xr and the "Featured" badge on
   /news were spans dressed as buttons; both are now plain kicker text in
   the markup, so there is no pill rule left to write here. */

/* ------------------------------------------------------------------ *
 * No tile crops its own picture.
 * Operator, 2026-09-05: "This picture is cut off". capability-composition
 * stretches .ptrcx-feature media to height:100% of its grid cell, so a
 * 16:9 source landed in whatever box the copy column happened to make and
 * object-fit:cover ate the difference (measured 10% of the /xr hero).
 * The media keeps its own declared aspect and the cell stops forcing a
 * height, so the box the reader sees is the shape of the source.
 * ------------------------------------------------------------------ */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .ptrcx-feature__media {
    align-self: center;
    height: auto;
  }
  html body .ptrdr .ptrcx-section .ptrcx-feature__media > :is(img, video) {
    height: auto !important;
    width: 100%;
  }
}

/* ------------------------------------------------------------------ *
 * Two rules that have to hold at once: a row's tiles share a top edge
 * and a height, and no picture is cut. So a tile in a GRID keeps its
 * fixed box and shows the whole source inside it (object-fit: contain
 * on a neutral ground), while a single media block in a pair or a
 * timeline entry simply takes the shape of its own source.
 * ------------------------------------------------------------------ */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section :is(.ptr-vgrid, .ptrcx-vgrid3, .ptrcx-grid-3, .ptrcx-grid-4,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .ptrcx-cards, .nwGrid,
    .nwPressGrid, .nwWatchGrid, .xrex-grid, .ptrdr-tiles) :is(img, video) {
    object-fit: contain !important;
    background: #F1F1F4;
  }
  /* A picture standing on its own keeps its own shape. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature__media, .tlFig, .ptrdr-smedia) > :is(img, video) {
    object-fit: contain !important;
  }
}

/* Anything else that renders a picture inside a fixed box, including the
   shared WatchVideo poster, shows the whole picture rather than the middle
   of it. Sources that already match their box are unaffected. */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section img { object-fit: contain !important; background: #F1F1F4; }
  html body .ptrdr .ptrcx-section .ptrdr-ph__slot img { background: none; object-fit: cover !important; }
}

/* ==================================================================== *
 * SAMPLE BAND SYSTEM, ported 2026-09-05 from the operator-iterated
 * design sample (scratchpad/ptr-full-width-sample.html, approved look at
 * 1440). One prefix, `ptrsx-`, so nothing here can reach the top nav,
 * Home or the footer group. Spacing, gaps, tile aspect, caption style
 * and the type-scale caps are the sample's own values, not re-derived.
 *
 * Sample band numbers referenced in the page comments:
 *   01 page hero with video      02 page hero, breadcrumb kicker
 *   03 section intro + card grid 04 video tile grid
 *   05 pair, media right         06 pair, media left
 *   07 labelled process steps    08 stats and numbers row
 *   09 key takeaway callout      10 pull quote
 *   12 case study list cards     13 hub and category rows
 *   14 FAQ list                  15 timeline, year by year
 *   16 long-form article copy
 * ==================================================================== */
.ptrdr .ptrsx {
  --sx-line: rgba(11,13,18,0.10);
  --sx-body: #33353D;
  --sx-muted: #6E707A;
  --sx-card: #FFFFFF;
  --sx-panel: #EEF0F3;
  --sx-gap: clamp(16px, 2vw, 24px);
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* --- full-width type. The BLOCK spans the row; the TYPE keeps the site
   scale: h1 96 / h2 56 / pair heading 44 / break heading 32 / subline 24. */
.ptrdr .ptrsx-kicker { margin: 0 0 12px; width: 100%; max-width: none; font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--sx-muted); }
.ptrdr .ptrsx-kicker a { color: inherit; }
.ptrdr .ptrsx-h1 { margin: 0 0 16px; width: 100%; max-width: none; font-size: clamp(42px, 6.6vw, 96px); font-weight: 700; letter-spacing: -0.03em; line-height: 1.03; text-wrap: balance; color: #0B0D12; }
.ptrdr .ptrsx-h2 { margin: 0 0 14px; width: 100%; max-width: none; font-size: clamp(34px, 4.6vw, 56px); font-weight: 700; letter-spacing: -0.03em; line-height: 1.08; text-wrap: balance; color: #0B0D12; }
.ptrdr .ptrsx-lead { margin: 0 0 30px; width: 100%; max-width: none; font-size: clamp(16px, 1.8vw, 24px); line-height: 1.5; color: var(--sx-body); text-wrap: pretty; }
.ptrdr .ptrsx-break { width: 100%; margin: 0; }
.ptrdr .ptrsx-bh { margin: 0 0 8px; width: 100%; max-width: none; font-size: clamp(20px, 2.2vw, 32px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.18; text-wrap: balance; color: #0B0D12; }
.ptrdr .ptrsx-bs { margin: 0; width: 100%; max-width: none; font-size: clamp(15px, 1.6vw, 20px); line-height: 1.5; color: var(--sx-body); text-wrap: pretty; }

/* --- tiles: 16:9 poster, caption slot, one caption style. */
.ptrdr .ptrsx-tile { margin: 0; border-radius: 20px; overflow: hidden; background: var(--sx-card); border: 1px solid var(--sx-line); display: flex; flex-direction: column; }
/* height: auto on purpose: a photo tile that carries an HTML height
   attribute (width="1200" height="800") otherwise renders at that height
   inside a 16:9 grid slot (measured 848 px tall in a 3-across row on
   /about/partners, 2026-09-05); with height auto the aspect-ratio wins. */
.ptrdr .ptrsx-tile > img, .ptrdr .ptrsx-tile > video { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; display: block; background: var(--sx-panel); }
.ptrdr .ptrsx-tile.ptrsx-own > img, .ptrdr .ptrsx-tile.ptrsx-own > video { aspect-ratio: auto 16 / 9; height: auto; object-fit: contain; }
.ptrdr .ptrsx-tile figcaption { margin: 0; padding: 13px 15px; font-size: 13px; line-height: 1.5; color: var(--sx-body); }
.ptrdr .ptrsx-phlab { display: block; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #8A5A2B; margin-bottom: 4px; }

/* --- grids: 3 across on desktop, 2 on a laptop, 1 on mobile; a trailing
   pair takes a half each, so a row is never 3 + 1. */
.ptrdr .ptrsx-g { display: grid; gap: var(--sx-gap); width: 100%; margin: 0; }
.ptrdr .ptrsx-g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ptrdr .ptrsx-g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ptrdr .ptrsx-g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ptrdr .ptrsx-g32 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.ptrdr .ptrsx-g32 > * { grid-column: span 2; }
.ptrdr .ptrsx-g32 > *:nth-child(n+4) { grid-column: span 3; }
@media (max-width: 1199.98px) {
  .ptrdr .ptrsx-g { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .ptrdr .ptrsx-g > * { grid-column: span 1 !important; }
  .ptrdr .ptrsx-g > *:last-child:nth-child(odd) { grid-column: 1 / -1 !important; }
}
@media (max-width: 639.98px) {
  .ptrdr .ptrsx-g { grid-template-columns: minmax(0, 1fr) !important; }
  .ptrdr .ptrsx-g > * { grid-column: 1 / -1 !important; }
}

/* --- media + copy pair (sample bands 05/06). Text column 58 percent,
   media 42 percent, together edge to edge. The copy column centres its
   TEXT CONTENT on the tile, not merely its own box: the grid stretches
   the box, so a centred box with top-set text is what the operator saw
   at 1440 and 1100. A full-height flex column with justify-content
   center puts the text's own centre on the tile's centre. */
.ptrdr .ptrsx-pair { width: 100%; display: grid; grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); gap: clamp(24px, 3vw, 56px); align-items: center; margin: 0; }
.ptrdr .ptrsx-pair.ptrsx-rev { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); }
.ptrdr .ptrsx-pair.ptrsx-rev .ptrsx-pmedia { order: 2; }
.ptrdr .ptrsx-pair.ptrsx-rev .ptrsx-pcopy { order: 1; }
.ptrdr .ptrsx-pmedia { min-width: 0; align-self: center; }
.ptrdr .ptrsx-pcopy { min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 14px; }
.ptrdr .ptrsx-pcopy > * { margin: 0; width: 100%; max-width: none; }
.ptrdr .ptrsx-pcopy h2, .ptrdr .ptrsx-pcopy h3 { font-size: clamp(24px, 2.6vw, 44px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.12; text-wrap: balance; color: #0B0D12; }
.ptrdr .ptrsx-pcopy p { font-size: clamp(15px, 1.5vw, 20px); line-height: 1.55; color: var(--sx-body); }
.ptrdr .ptrsx-pcopy .ptrsx-meta { font-size: 13px; line-height: 1.5; color: var(--sx-muted); }
.ptrdr .ptrsx-pcopy .ptrsx-year { font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--sx-muted); }
@media (min-width: 900px) {
  .ptrdr .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy { text-align: right; align-items: flex-end; }
  .ptrdr .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy > * { text-align: right; }
  .ptrdr .ptrsx-pair.ptrsx-rev .ptrsx-pcopy { text-align: left; align-items: flex-start; }
}
@media (max-width: 899.98px) {
  .ptrdr .ptrsx-pair, .ptrdr .ptrsx-pair.ptrsx-rev { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .ptrdr .ptrsx-pair.ptrsx-rev .ptrsx-pmedia, .ptrdr .ptrsx-pair.ptrsx-rev .ptrsx-pcopy { order: initial; }
  .ptrdr .ptrsx-pcopy { height: auto; }
}

/* --- running text keeps a reading measure. A paragraph is never the
   width of the row: 60-75 characters, measured. It fills the row by
   being paired with media, not by being stretched. */
.ptrdr .ptrsx-prose { width: 100%; }
.ptrdr .ptrsx-prose > p, .ptrdr .ptrsx-prose > ul, .ptrdr .ptrsx-prose > ol {
  margin: 0 0 20px; width: 100%; max-width: none;
  font-size: clamp(16px, 1.2vw, 19px); line-height: 1.65; color: var(--sx-body);
}
.ptrdr .ptrsx-pcopy p.ptrsx-measure, .ptrdr .ptrsx-scopy p.ptrsx-measure { max-width: none; }
.ptrdr .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy p.ptrsx-measure { margin-left: auto; }
.ptrdr .ptrsx-srow:not(.ptrsx-rev) .ptrsx-scopy p.ptrsx-measure { margin-left: auto; }

/* --- hero-class photograph: the only full-width figure, height-capped. */
.ptrdr .ptrsx-hero { width: 100%; margin: 0; border-radius: 20px; overflow: hidden; background: var(--sx-card); border: 1px solid var(--sx-line); }
.ptrdr .ptrsx-hero > img, .ptrdr .ptrsx-hero > video { width: 100%; height: auto; max-height: 60vh; object-fit: contain; display: block; background: var(--sx-panel); }
.ptrdr .ptrsx-hero figcaption { margin: 0; padding: 13px 15px; font-size: 13px; line-height: 1.5; color: var(--sx-body); }

/* --- pull quote band (sample band 10): a full-width band, the quote at
   the reading measure, the attribution beneath. No card, no pill, no
   source chip, no lone logo tile beside it. */
.ptrdr .ptrsx-quote { width: 100%; margin: 0; padding: clamp(22px, 2.6vw, 36px) 0; border-top: 1px solid var(--sx-line); border-bottom: 1px solid var(--sx-line); }
.ptrdr .ptrsx-quote blockquote { margin: 0; width: 100%; max-width: none; font-size: clamp(19px, 2.4vw, 36px); line-height: 1.3; letter-spacing: -0.02em; font-weight: 400; color: #0B0D12; text-wrap: pretty; }
.ptrdr .ptrsx-quote .ptrsx-attr { margin: 16px 0 0; width: 100%; max-width: none; font-size: 14px; line-height: 1.55; color: var(--sx-muted); }
.ptrdr .ptrsx-quote .ptrsx-attr strong { color: #0B0D12; font-weight: 700; }

/* --- brand mark: small, inside a pair's media column under the photo,
   never a lone tile in a big white box. */
.ptrdr .ptrsx-mark { margin: 14px 0 0; display: block; }
.ptrdr .ptrsx-mark img { max-width: 260px; width: 100%; height: auto; display: block; }

/* --- hub rows (sample band 13). */
.ptrdr .ptrsx-sectors { width: 100%; display: grid; grid-auto-rows: 1fr; }
.ptrdr .ptrsx-srow { width: 100%; display: grid; grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); gap: clamp(24px, 3vw, 56px); align-items: center; padding: clamp(24px, 2.8vw, 44px) 0; border-top: 1px solid var(--sx-line); }
.ptrdr .ptrsx-srow:first-child { border-top: 0; padding-top: 0; }
.ptrdr .ptrsx-srow.ptrsx-rev { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); }
.ptrdr .ptrsx-srow.ptrsx-rev .ptrsx-smedia { order: 2; }
.ptrdr .ptrsx-srow.ptrsx-rev .ptrsx-scopy { order: 1; }
.ptrdr .ptrsx-smedia { min-width: 0; margin: 0; }
.ptrdr .ptrsx-scopy { min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: clamp(10px, 1.1vw, 16px); }
.ptrdr .ptrsx-scopy > * { margin: 0; width: 100%; max-width: none; }
.ptrdr .ptrsx-scopy h3 { font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; font-size: clamp(24px, 2.8vw, 44px); text-wrap: balance; color: #0B0D12; }
.ptrdr .ptrsx-scopy .ptrsx-sdesc { font-size: clamp(16px, 1.8vw, 24px); line-height: 1.45; color: var(--sx-body); text-wrap: pretty; }
@media (min-width: 900px) {
  .ptrdr .ptrsx-srow:not(.ptrsx-rev) .ptrsx-scopy { text-align: right; align-items: flex-end; }
  .ptrdr .ptrsx-srow.ptrsx-rev .ptrsx-scopy { text-align: left; align-items: flex-start; }
}
@media (max-width: 899.98px) {
  .ptrdr .ptrsx-sectors { grid-auto-rows: auto; }
  .ptrdr .ptrsx-srow, .ptrdr .ptrsx-srow.ptrsx-rev { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .ptrdr .ptrsx-srow.ptrsx-rev .ptrsx-smedia, .ptrdr .ptrsx-srow.ptrsx-rev .ptrsx-scopy { order: initial; }
  .ptrdr .ptrsx-scopy { height: auto; }
}

/* --- stats row (sample band 08): four equal tracks that start on the
   content-left guide and finish on the content-right guide. The cells
   read left, and the caption line spans the same two edges, so the left
   and right gaps are equal at every width. */
.ptrdr .ptrsx-stats { width: 100%; max-width: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sx-gap); justify-content: stretch; }
.ptrdr .ptrsx-stat { min-width: 0; margin: 0; border: 1px solid var(--sx-line); border-radius: 20px; padding: 24px 22px; background: var(--sx-card); text-align: left; }
.ptrdr .ptrsx-stat .ptrsx-num { font-size: clamp(30px, 3.4vw, 44px); font-weight: 700; letter-spacing: -0.03em; line-height: 1; color: #0B0D12; }
.ptrdr .ptrsx-stat p { margin: 8px 0 0; font-size: 14px; line-height: 1.5; color: var(--sx-body); }
.ptrdr .ptrsx-statscap { width: 100%; max-width: none; margin: 14px 0 0; padding: 0; font-size: 13px; line-height: 1.55; color: var(--sx-muted); text-align: left; }
@media (max-width: 899.98px) { .ptrdr .ptrsx-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --- sources, one column, an image slot each. */
.ptrdr .ptrsx-srclist { width: 100%; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: clamp(12px, 1.4vw, 18px); }
.ptrdr .ptrsx-srcrow { width: 100%; display: grid; grid-template-columns: minmax(0, clamp(160px, 18%, 260px)) minmax(0, 1fr); gap: clamp(16px, 2vw, 32px); align-items: center; border: 1px solid var(--sx-line); border-radius: 16px; background: var(--sx-card); padding: clamp(12px, 1.2vw, 18px); }
.ptrdr .ptrsx-srcpic { margin: 0; border-radius: 10px; overflow: hidden; background: var(--sx-panel); }
.ptrdr .ptrsx-srcpic img, .ptrdr .ptrsx-srcpic video { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.ptrdr .ptrsx-srccopy { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.ptrdr .ptrsx-srccopy > * { margin: 0; max-width: none; }
.ptrdr .ptrsx-srccopy h3 { font-size: clamp(17px, 1.5vw, 24px); letter-spacing: -0.015em; line-height: 1.25; color: #0B0D12; }
.ptrdr .ptrsx-srcmeta { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--sx-muted); }
.ptrdr .ptrsx-srccopy p { font-size: 14px; line-height: 1.55; color: var(--sx-body); }
@media (max-width: 767.98px) { .ptrdr .ptrsx-srcrow { grid-template-columns: minmax(0, 1fr); } }

/* --- routing pills: the centred honeycomb, one of the two centred
   exceptions. Only ever real links. */
.ptrdr .ptrsx-pills { width: 100%; display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch; gap: 14px; margin: 0; padding: 0; list-style: none; }
.ptrdr .ptrsx-pills > li { display: flex; }
.ptrdr .ptrsx-pills a { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 26px; border-radius: 26px; border: 1px solid var(--sx-line); background: var(--sx-card); color: #0B0D12; font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600; text-align: center; text-decoration: none; }
.ptrdr .ptrsx-pills a:hover { background: #F1F1F4; }

/* --- band rhythm (the sample's own spacing). */
.ptrdr .ptrsx > * + * { margin-top: clamp(34px, 4.4vh, 62px); }
.ptrdr .ptrsx > .ptrsx-tight + * { margin-top: clamp(14px, 1.6vh, 22px) !important; }
.ptrdr .ptrsx-caprow { width: 100%; margin: 0; }

/* ==================================================================== *
 * PAIR TEXT-CONTENT CENTRING, 2026-09-05.
 * Operator, on /xr: "these are not vertically aligned: Role-play and
 * rehearsal / Perspective experiences / Procedural simulation".
 * Measured at 1440 and 1100: the pair is a two-column grid with
 * align-items:center, so the copy column's BOX centre already sat on the
 * tile centre (0 px, which is what the earlier gate measured). The copy
 * column is stretched to the tile's height by the grid, and inside it the
 * heading and subline sat at the TOP, because the column was a flex
 * column with justify-content:normal. The eye sees the text, not the box.
 * The fix is to centre the CONTENT: a full-height flex column that
 * centres its own children. Applied to every media + copy pair on these
 * pages, authored or template-driven.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-grid-2, .ptrcx-feature, .ptrcx-cards, .tlEntry) > :is(.ptrcx-intro, .ptrcx-feature__copy, .ptrdr-scopy) {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  /* The chapter rows alternate sides with `direction: rtl` on the grid, so
     the copy column is on the RIGHT in a reversed row and reads right, the
     way the footer's right-hand blocks do. Both spellings of the inline
     style are matched: the prerendered fallback is written back by Chrome
     with a space, the runtime template without one. */
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction: rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy),
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction:rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) {
    text-align: right;
    align-items: flex-end;
  }
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction: rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > *,
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction:rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > * {
    text-align: right;
  }
  /* A pair's running copy keeps a reading measure and is pushed to the
     outer edge of its own column, so the row still fills. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature__copy, .ptrcx-grid-2 > :is(.ptrcx-intro, .ptrsx-pcopy)) > p {
    max-width: none;
  }
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction: rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > p,
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction:rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > p {
    margin-left: auto;
  }
}

/* ==================================================================== *
 * v4 corrections, measured 2026-09-05.
 * 1  The reading measure has to beat the full-width cap layer. That layer
 *    is written with !important (it exists to kill four different 760px
 *    and 72ch caps), so a plain max-width on a paragraph inside a pair
 *    lost to it and running copy went back to the width of its column.
 * 2  A grid of five or six tiles keeps three across down to 1000px, so a
 *    trailing odd tile is never promoted to the whole row.
 * ==================================================================== */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .ptrsx-prose > p,
  html body .ptrdr .ptrcx-section .ptrsx-prose > ul,
  html body .ptrdr .ptrcx-section .ptrsx-prose > ol { max-width: none !important; }
  html body .ptrdr .ptrcx-section p.ptrsx-measure { max-width: none !important; }
  html body .ptrdr .ptrcx-section p.ptrsx-meta { max-width: none !important; }
  html body .ptrdr .ptrcx-section .ptrsx-quote blockquote { max-width: none !important; }
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature__copy, .ptrcx-grid-2 > :is(.ptrcx-intro, .ptrsx-pcopy)) > p { max-width: none !important; }
  /* Copy on the right of its tile pushes its measured column to the outer
     edge, so the row still meets the content guide. */
  html body .ptrdr .ptrcx-section .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy > p.ptrsx-measure,
  html body .ptrdr .ptrcx-section .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy > p.ptrsx-meta { margin-left: auto; margin-right: 0; }
}

/* Three across down to 1000px for tile grids, so five tiles read 3 + 2
   and the fifth is never a full-width lone tile. Below 1000px the row
   drops to two and a trailing odd tile takes the row, which is the
   established laptop behaviour for cards. */
@media (min-width: 1000px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section :is(.ptrsx-g3, .ptrsx-g32, .ptr-vgrid, .ptrcx-vgrid3, .ptrcx-grid-3,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .xrex-grid, .ptrdr-tiles) {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }
  html body .ptrdr .ptrcx-section :is(.ptrsx-g3, .ptrsx-g32, .ptr-vgrid, .ptrcx-vgrid3, .ptrcx-grid-3,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .xrex-grid, .ptrdr-tiles) > * {
    grid-column: span 1 !important;
  }
}
@media (min-width: 900px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section .ptrsx-g3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
  html body .ptrdr .ptrcx-section .ptrsx-g3 > * { grid-column: span 1 !important; }
}

/* The stats caption row meets both guides: the note on the left edge, the
   source on the right edge, one line, one type style. */
.ptrdr .ptrsx-capline {
  width: 100%; max-width: none; margin: 14px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px;
  font-size: 13px; line-height: 1.55; color: var(--sx-muted, #6E707A);
}
.ptrdr .ptrsx-capline > span { margin: 0; }
.ptrdr .ptrsx-capline > .ptrsx-capsrc { text-align: right; }

/* A trailing odd tile keeps its own cell at 1000-1199 instead of being
   promoted to the whole row: a lone tile never spans the content width.
   Written at the same specificity as the laptop span rule it overrides. */
@media (min-width: 1000px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section :is(.ptrsx-g3, .ptrsx-g32, .ptr-vgrid, .ptrcx-vgrid3, .ptrcx-grid-3,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .xrex-grid, .ptrdr-tiles) > *:last-child:nth-child(odd),
  html body .ptrdr .ptrcx-section :is(.ptrsx-g3, .ptrsx-g32, .ptr-vgrid, .ptrcx-vgrid3, .ptrcx-grid-3,
    .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7, .ptrcx-grid-8, .xrex-grid, .ptrdr-tiles) > *:only-child {
    grid-column: span 1 !important;
  }
}
@media (min-width: 900px) and (max-width: 999.98px) {
  html body .ptrdr .ptrcx-section .ptrsx-g3 > *:last-child:nth-child(odd) { grid-column: span 1 !important; }
}

/* ==================================================================== *
 * NO TEXT BLOCK READS WIDER THAN ITS MEASURE, 2026-09-05.
 * The rule the operator gave: kickers, headings and the ROW span the
 * content width; running text keeps a reading measure and fills the row
 * by being PAIRED with media. Everything that carries prose therefore
 * gets a measure here - lead, subline, body, list item, quote,
 * attribution and caption - while h1/h2/h3 and kickers keep spanning the
 * content edges at the site scale. Where a block has no media to pair
 * with, it reads as a measured column under a full-width heading, which
 * is the stated fallback. `!important` because the full-width cap-removal
 * layer above is itself written with `!important`.
 * ==================================================================== */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section :is(p, li, blockquote, figcaption, dd, dt):not(.ptrsx-kicker):not(.ptrsx-capline):not(.ptrdr-citerow):not(.ptrsx-srcrow):not(.ptrsx-pills > li):not(.ptrdr-pills > li):not(.ptrsx-lead):not(.ptrsx-bs):not(.ptrsx-sdesc):not(.workReflect *) {
    max-width: none !important;
  }
  /* A citation row, a source row and a routing pill are ROWS and controls,
     not lines of running text: the reading measure would cut them in half
     and leave the right of the row empty, which is the padding the
     operator kept seeing. */
  html body .ptrdr .ptrcx-section :is(.ptrdr-citerow, .ptrsx-srcrow, .ptrsx-pills > li, .ptrdr-pills > li) { max-width: none !important; }
  /* A subline sits under a heading that spans the content width and
     spans it too (operator rule 2026-09-05: kickers, headings AND
     sublines span the content width; a 58ch subline under a 1309 px h1
     measured 535 px of empty right side at 1440). */
  html body .ptrdr .ptrcx-section :is(.ptrsx-lead, .ptrsx-bs, .ptrsx-sdesc) { width: 100%; max-width: none !important; }
  /* Same rule for a subline that sits under a heading inside an intro
     group that still carries the older classes (/xr, /ai, /fast-builds):
     measured 645 px under a 1309 px h2 on /xr at 1440. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-intro, .ptrsx-tight, .ptrsx-break) > :is(h1, h2, h3) ~ p { width: 100%; max-width: none !important; margin-left: 0 !important; margin-right: 0 !important; }
  /* Running text inside a media pair fills its copy column: the column
     is already the reading measure (about 68 characters at 1440), so a
     second cap inside it left the paragraph narrower than its heading. */
  html body .ptrdr .ptrcx-section :is(.ptrsx-pcopy, .ptrsx-scopy) > :is(p, ul, ol) { width: 100%; max-width: none !important; }
  html body .ptrdr .ptrcx-section .ptrsx-quote blockquote { max-width: none !important; }
  html body .ptrdr .ptrcx-section figcaption { max-width: none !important; }
  /* A measured block inside a right-reading copy column stays flush to
     the column's outer edge, so the row still meets the content guide. */
  html body .ptrdr .ptrcx-section :is(.ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy, .ptrsx-srow:not(.ptrsx-rev) .ptrsx-scopy) > :is(p, ul, ol, blockquote) {
    margin-left: auto !important;
    margin-right: 0 !important;
  }
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction: rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > p,
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="direction:rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > p {
    margin-left: auto !important;
  }
  /* A caption inside a tile is bounded by the tile, so it never needs the
     page measure; keeping it at the tile width avoids a short caption
     column inside a narrow tile. */
  html body .ptrdr .ptrcx-section :is(.ptrsx-tile, .ptrsx-hero, .ptrdr-ph, .ptr-vgrid > *, .ptrsx-g > *) figcaption {
    max-width: none !important;
  }
  /* Source chips on /news were spans dressed as pills and are not links:
     they read as plain source meta on one line. */
  html body .ptrdr .ptrcx-section .nwSrcChips { display: block; margin: 2px 0 0; padding: 0; list-style: none; font-size: 12.5px; line-height: 1.5; color: #63656E; }
  html body .ptrdr .ptrcx-section .nwSrcChips > li { display: inline; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; }
  html body .ptrdr .ptrcx-section .nwSrcChips > li + li::before { content: " \00b7 "; }
}

/* ==================================================================== *
 * A LONE TILE NEVER SPANS THE ROW.
 * Operator, 2026-09-05: a single loop rendered as a 781px (and at 1440,
 * 1325px) full-width figure between two paragraphs. A tile that stands on
 * its own in a prose column is turned into a real media + copy pair: the
 * picture takes about 42 percent, its caption takes the rest at a reading
 * measure, both vertically centred, and the sides alternate down the
 * page. Nothing is cropped and no row is left empty on the right.
 * Excluded: the hero-class photograph (`data-ptr-hero`), tiles inside a
 * grid or a pair, and the tiles this stylesheet already lays out.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-shell, .csProse, .ind-copy, .news-copy, .learn-copy, .about-copy, .xr-copy) > figure:not([data-ptr-hero]):not(.ptrsx-tile):not(.ptrsx-hero):not(.ptrdr-ph) {
    display: grid;
    grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
    gap: clamp(24px, 3vw, 56px);
    align-items: center;
    width: 100%;
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
    padding: 0;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-shell, .csProse, .ind-copy, .news-copy, .learn-copy, .about-copy, .xr-copy) > figure:not([data-ptr-hero]):not(.ptrsx-tile):not(.ptrsx-hero):not(.ptrdr-ph) > :is(img, video) {
    grid-column: 1;
    grid-row: 1;
    width: 100%;
    height: auto;
    max-height: 60vh;
    border-radius: 20px;
    border: 1px solid rgba(11, 13, 18, 0.08);
    background: #F1F1F4;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-shell, .csProse, .ind-copy, .news-copy, .learn-copy, .about-copy, .xr-copy) > figure:not([data-ptr-hero]):not(.ptrsx-tile):not(.ptrsx-hero):not(.ptrdr-ph) > figcaption {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    padding: 0;
    max-width: none !important;
    font-size: clamp(15px, 1.5vw, 20px);
    line-height: 1.55;
    color: #33353D;
  }
  /* Sides alternate: an even-numbered lone tile puts its picture on the
     right and reads its caption right, the way the footer's right-hand
     blocks do. */
  html body .ptrdr .ptrcx-section :is(.ptrcx-shell, .csProse, .ind-copy, .news-copy, .learn-copy, .about-copy, .xr-copy) > figure:not([data-ptr-hero]):not(.ptrsx-tile):not(.ptrsx-hero):not(.ptrdr-ph):nth-of-type(even) > :is(img, video) {
    grid-column: 2;
  }
  html body .ptrdr .ptrcx-section :is(.ptrcx-shell, .csProse, .ind-copy, .news-copy, .learn-copy, .about-copy, .xr-copy) > figure:not([data-ptr-hero]):not(.ptrsx-tile):not(.ptrsx-hero):not(.ptrdr-ph):nth-of-type(even) > figcaption {
    grid-column: 1;
    text-align: right;
    margin-left: auto !important;
  }
}

/* A figure marked `ptrsx-solo` stood alone in a prose column at the whole
   content width. It becomes a real pair: picture about 42 percent, its
   caption at a reading measure in the rest of the row, both vertically
   centred, sides alternating. Same treatment as the shell-child rule
   above, applied by class where the figure sits deeper than a direct
   child (inside a component host or an authored wrapper). */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section figure.ptrsx-solo {
    display: grid;
    grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
    gap: clamp(24px, 3vw, 56px);
    align-items: center;
    width: 100%;
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
    padding: 0;
  }
  html body .ptrdr .ptrcx-section figure.ptrsx-solo > :is(img, video) {
    grid-column: 1; grid-row: 1;
    width: 100%; height: auto; max-height: 60vh;
    border-radius: 20px; border: 1px solid rgba(11, 13, 18, 0.08); background: #F1F1F4;
  }
  html body .ptrdr .ptrcx-section figure.ptrsx-solo > figcaption {
    grid-column: 2; grid-row: 1;
    margin: 0; padding: 0; max-width: none !important;
    font-size: clamp(15px, 1.5vw, 20px); line-height: 1.55; color: #33353D;
  }
  html body .ptrdr .ptrcx-section figure.ptrsx-solo:nth-of-type(even) > :is(img, video) { grid-column: 2; }
  html body .ptrdr .ptrcx-section figure.ptrsx-solo:nth-of-type(even) > figcaption {
    grid-column: 1; text-align: right; margin-left: auto !important;
  }
}

/* The pull quote keeps its own measure. The blanket 74ch rule above
   carries two :not() classes, so it out-specifies a plain descendant
   selector; this one carries them too. */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .ptrsx-quote blockquote:not(.ptrsx-kicker):not(.ptrsx-capline) {
    max-width: none !important;
  }
}

/* A component host renders its own single figure (the shared WatchVideo
   poster on /work/industries/healthcare-medical). It gets the same
   treatment as a marked solo figure, since the class cannot be authored
   into markup this page does not own. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .sc-host > figure,
  html body .ptrdr .ptrcx-section .sc-host > div > figure {
    display: grid;
    grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
    gap: clamp(24px, 3vw, 56px);
    align-items: center;
    width: 100%;
  }
  html body .ptrdr .ptrcx-section .sc-host > figure > :is(img, video, div),
  html body .ptrdr .ptrcx-section .sc-host > div > figure > :is(img, video, div) { grid-column: 1; grid-row: 1; width: 100%; }
  html body .ptrdr .ptrcx-section .sc-host > figure > figcaption,
  html body .ptrdr .ptrcx-section .sc-host > div > figure > figcaption {
    grid-column: 2; grid-row: 1; margin: 0; padding: 0; max-width: none !important;
    font-size: clamp(15px, 1.5vw, 20px); line-height: 1.55; color: #33353D;
  }
}

/* Any copy column in a pair centres its content on the tile, including
   the ones authored as a bare <div> with no class of their own. :has()
   picks the column that holds no media, which is the copy side. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature, .ptrcx-grid-2, .ptrsx-pair, .ptrdr-srow, .tlEntry) > div:not(:has(img, video)) {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* ==================================================================== *
 * OPERATOR REVIEW OF THE /xr PREVIEW, second round, 2026-09-05.
 *
 * 1 and 6  "Not correctly aligned" / "again poor formatting". The copy
 *   column's heading spanned the whole column while its paragraphs were
 *   held to a character measure inside it, so the two blocks did not
 *   share an edge. The COLUMN is now the measure: the pair's copy track
 *   is sized in characters, every block inside it fills that track, and
 *   heading and paragraphs share both edges at every width. The media
 *   track takes the remaining row, so nothing is left empty on the right.
 * 2 "This has poor spacing above it". The stats row now sits on the
 *   same block gap this page uses between a subline and its row.
 * 3 "the stats need to be centered in their tiles". Each figure and its
 *   label are centred in a tile, and the tiles share a height.
 * 5 "a lot of empty space" around the testimonial: the band's padding is
 *   the section rhythm rather than a card's, and the speaker's picture
 *   sits small beside the attribution.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-pair { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); }
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev { grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); }
  /* The column carries the measure, so nothing inside it is capped
     again: every block shares the column's two edges. */
  html body .ptrdr .ptrcx-section :is(.ptrsx-pcopy, .ptrsx-scopy) > * { max-width: none !important; width: 100%; }
  html body .ptrdr .ptrcx-section :is(.ptrsx-pcopy, .ptrsx-scopy) > :is(p, ul, ol, blockquote) { margin-left: 0 !important; margin-right: 0 !important; }
}

/* 2. One block gap above the stats row, the same one a subline uses. */
.ptrdr .ptrsx > .ptrsx-caprow { margin-top: clamp(14px, 1.6vh, 22px) !important; }

/* 3. A stat is centred in its tile and the tiles share a height. */
.ptrdr .ptrsx-stats { align-items: stretch; }
.ptrdr .ptrsx-stat {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 6px; min-height: 100%;
}
.ptrdr .ptrsx-stat p { margin: 0; max-width: none !important; }

/* 5. The quote band keeps the section's own rhythm and carries a face. */
.ptrdr .ptrsx-quote { padding: clamp(18px, 2vw, 26px) 0; }
.ptrdr .ptrsx-quote .ptrsx-attr { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.ptrdr .ptrsx-face {
  flex: 0 0 auto; width: 56px; height: 56px; border-radius: 999px;
  object-fit: cover !important; background: #EEF0F3; display: block;
}

/* ==================================================================== *
 * OPERATOR BATCH FOUR, Our Story, 2026-09-05.
 *
 * "The pictures in our story not aligned with the text". A pair centred
 * the whole media BLOCK (picture plus its caption) on the copy, so the
 * PICTURE always sat high by half a caption. The pair now lays the
 * picture and the copy on one grid row and drops the caption into a
 * second row under the picture, so the copy's centre lands on the
 * picture's centre and the caption cannot move it.
 *
 * "do not like that content boxes have so much empty space". A picture in
 * a pair is a picture, not a card: no frame, no white ground, no inner
 * padding, and the caption reads directly under it.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-pair {
    grid-template-rows: auto auto;
    align-items: center;
  }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia,
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia > figure { display: contents; }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia > figure > :is(img, video) {
    grid-column: 1; grid-row: 1;
    align-self: center;
    width: 100%; height: auto; max-height: 62vh;
    border-radius: 20px; display: block; background: #F1F1F4;
  }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia > figure > figcaption {
    grid-column: 1; grid-row: 2;
    margin: 10px 0 0; padding: 0;
    font-size: 13px; line-height: 1.5; color: #6E707A;
  }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pcopy { grid-column: 2; grid-row: 1; align-self: center; }
  /* Reversed rows put the picture on the right and the copy on the left. */
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev > .ptrsx-pmedia > figure > :is(img, video),
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev > .ptrsx-pmedia > figure > figcaption { grid-column: 2; }
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev > .ptrsx-pcopy { grid-column: 1; }
  /* A pair that carries two media blocks (a video slot above a
     photograph) keeps them stacked in the picture column. */
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia:has(> figure + figure) { display: block; align-self: center; }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia:has(> figure + figure) > figure { display: flex; }

  /* No card chrome and no inner padding on a picture inside a pair. */
  html body .ptrdr .ptrcx-section .ptrsx-pair .ptrsx-tile {
    border: 0; background: none; border-radius: 0; padding: 0; overflow: visible;
  }
}

/* ==================================================================== *
 * INDUSTRIES HUB ROWS, operator 2026-09-05.
 * "The alignment of these are so wrong": a sector row's copy column read
 * right but its three blocks did not share a right edge, and the block
 * was centred on the whole media figure rather than on the picture. The
 * row now uses the same shape as a pair: picture and copy on one grid
 * row, caption beneath the picture, copy centred on the picture, and
 * title, description and the Explore control all flush to the same edge.
 * The Explore link is a real link, so it may be a pill.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-srow { grid-template-rows: auto auto; align-items: center; }
  html body .ptrdr .ptrcx-section .ptrsx-srow > .ptrsx-smedia { display: contents; }
  html body .ptrdr .ptrcx-section .ptrsx-srow > .ptrsx-smedia > :is(img, video) {
    grid-column: 1; grid-row: 1; align-self: center;
    width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover;
    border-radius: 20px; display: block; background: #F1F1F4;
  }
  html body .ptrdr .ptrcx-section .ptrsx-srow > .ptrsx-smedia > figcaption {
    grid-column: 1; grid-row: 2; margin: 10px 0 0; padding: 0;
    font-size: 13px; line-height: 1.5; color: #6E707A;
  }
  html body .ptrdr .ptrcx-section .ptrsx-srow > .ptrsx-scopy { grid-column: 2; grid-row: 1; align-self: center; }
  html body .ptrdr .ptrcx-section .ptrsx-srow.ptrsx-rev > .ptrsx-smedia > :is(img, video),
  html body .ptrdr .ptrcx-section .ptrsx-srow.ptrsx-rev > .ptrsx-smedia > figcaption { grid-column: 2; }
  html body .ptrdr .ptrcx-section .ptrsx-srow.ptrsx-rev > .ptrsx-scopy { grid-column: 1; }
  html body .ptrdr .ptrcx-section .ptrsx-srow { grid-template-columns: minmax(0, 58fr) minmax(0, 42fr); }
  html body .ptrdr .ptrcx-section .ptrsx-srow.ptrsx-rev { grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); }
  html body .ptrdr .ptrcx-section .ptrsx-srow:not(.ptrsx-rev) .ptrsx-spill { justify-content: flex-end; }
  html body .ptrdr .ptrcx-section .ptrsx-srow.ptrsx-rev .ptrsx-spill { justify-content: flex-start; }
}
.ptrdr .ptrsx-spill { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; }
.ptrdr .ptrsx-pillbtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 24px; border-radius: 24px;
  border: 1px solid rgba(11, 13, 18, 0.14); background: #fff; color: #0B0D12;
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
  font-weight: 600; text-decoration: none;
}
.ptrdr .ptrsx-pillbtn:hover { background: #F1F1F4; }

/* A band introduced outside a .ptrsx flow still gets the section rhythm. */
.ptrdr .ptrcx-section .ptrsx-band { width: 100%; margin: clamp(34px, 4.4vh, 62px) 0 0; }
.ptrdr .ptrcx-section .ptrsx-tight.ptrsx-band + * { margin-top: clamp(14px, 1.6vh, 22px); }
.ptrdr .ptrcx-section .ptrsx-pcopy > h2 { font-size: clamp(24px, 2.6vw, 44px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.12; margin: 0; color: #0B0D12; }

/* Stats beside their loop (operator: "the stats need media"): the loop
   takes about 45 percent, the four figures read two by two in the rest,
   each centred in a box of equal height. */
.ptrdr .ptrsx-statpair { width: 100%; display: grid; grid-template-columns: minmax(0, 45fr) minmax(0, 55fr); gap: clamp(24px, 3vw, 56px); align-items: center; }
.ptrdr .ptrsx-statwrap { min-width: 0; }
.ptrdr .ptrsx-statmedia { align-self: center; }
.ptrdr .ptrsx-stats--2x2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 899.98px) {
  .ptrdr .ptrsx-statpair { grid-template-columns: minmax(0, 1fr); }
}

/* The rest of a shortened quote reads under the sentence that carries it. */
.ptrdr .ptrsx-quoterest { margin: 14px 0 0; max-width: none !important; font-size: 14px; line-height: 1.6; color: #4B4D57; }

/* The routing pill row is one of the two centred exceptions. */
.ptrdr .ptrsx-pillhead { width: 100%; text-align: center !important; margin: 0 0 14px; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: #63656E; }

/* A citation row's picture slot holds a real picture. */
.ptrdr .ptrdr-citepic img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }

/* No band carries empty height beyond the page's own block gap: the quote
   band and the sector row were padded like cards. */
.ptrdr .ptrsx-quote { padding: clamp(8px, 0.9vw, 12px) 0; }
.ptrdr .ptrsx-srow { padding: clamp(14px, 1.6vw, 24px) 0; }

/* A legacy pair whose picture carries a caption centred its copy on the
   picture PLUS the caption, so the words sat half a caption low. Same fix
   as the ported pair: picture and copy on one grid row, caption on a
   second row under the picture. Only pairs whose media is a figure with a
   caption are touched; a card with a body of its own is a card, and its
   whole box stays the reference. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrcx-feature:has(> figure:has(> figcaption)) { grid-template-rows: auto auto; align-items: center; }
  html body .ptrdr .ptrcx-section .ptrcx-feature > figure:has(> figcaption) { display: contents; }
  html body .ptrdr .ptrcx-section .ptrcx-feature > figure:has(> figcaption):first-child > :is(img, video) { grid-column: 1; grid-row: 1; align-self: center; }
  html body .ptrdr .ptrcx-section .ptrcx-feature > figure:has(> figcaption):first-child > figcaption { grid-column: 1; grid-row: 2; margin: 10px 0 0; padding: 0; }
  html body .ptrdr .ptrcx-section .ptrcx-feature > figure:has(> figcaption):last-child > :is(img, video) { grid-column: 2; grid-row: 1; align-self: center; }
  html body .ptrdr .ptrcx-section .ptrcx-feature > figure:has(> figcaption):last-child > figcaption { grid-column: 2; grid-row: 2; margin: 10px 0 0; padding: 0; }
  html body .ptrdr .ptrcx-section .ptrcx-feature:has(> figure:has(> figcaption)) > :is(.ptrcx-intro, .ptrcx-feature__copy, div:not(:has(img, video))) { grid-row: 1; align-self: center; }
}

/* A copy column's first and last blocks carry no outer margin, so a
   panel's own 6px margin cannot push the block off the picture's centre
   by half of it. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature, .ptrcx-grid-2, .ptrsx-pair, .ptrsx-srow) > :is(.ptrcx-intro, .ptrcx-feature__copy, .ptrsx-pcopy, .ptrsx-scopy, div) > :first-child { margin-top: 0 !important; }
  html body .ptrdr .ptrcx-section :is(.ptrcx-feature, .ptrcx-grid-2, .ptrsx-pair, .ptrsx-srow) > :is(.ptrcx-intro, .ptrcx-feature__copy, .ptrsx-pcopy, .ptrsx-scopy, div) > :last-child { margin-bottom: 0 !important; }
}

/* Rule 15: an A to B sequence is drawn, not typed with an arrow glyph. */
.ptrdr .ptrsx-dgm { width: 100%; margin: 0; }
.ptrdr .ptrsx-dgmsvg { width: 100%; height: auto; display: block; max-width: 720px; }
.ptrdr .ptrsx-dgmsvg.ptrsx-dgmwide { max-width: none; }

/* The AI building blocks read three across, so six cards are two rows and
   not three. Their grid is an authored inline style with no class, so it is
   selected by the cards it holds. */
@media (min-width: 1100px) {
  html body .ptrdr .ptrcx-section div:has(> [data-prerender-expect="ai-capability"]) {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: clamp(24px, 2.4vw, 34px) !important;
  }
}

/* ==================================================================== *
 * SHARED FIXES REQUESTED BY LANE B, 2026-09-05. Owned here because the
 * stylesheet is shared; each one is a shape the lanes met, not a
 * page-local patch.
 * ==================================================================== */
@media (min-width: 900px) {
  /* 1. A pair whose picture column holds a COMPONENT (the shared
     WatchVideo facade) must not use the display:contents split: the
     component renders its own figure, so contents put the poster in
     column one and left an empty second column. The column keeps its own
     box and centres on the row instead. */
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia:has(.sc-host) { display: block; align-self: center; }
  /* The component writes `margin: 10px 0` inline, which beats a class
     rule and left the row twenty pixels of air it did not need. */
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia:has(.sc-host) .sc-host > figure { display: block !important; margin: 0 !important; }
  html body .ptrdr .ptrcx-section .ptrsx-pair > .ptrsx-pmedia:has(.sc-host) .sc-host > figure > figcaption { max-width: none !important; }

  /* 3. The stats pair carries the same two-row treatment as any pair, so
     the caption under the picture cannot move the figures beside it. */
  html body .ptrdr .ptrcx-section .ptrsx-statpair { grid-template-rows: auto auto; align-items: center; }
  html body .ptrdr .ptrcx-section .ptrsx-statpair > .ptrsx-statmedia { display: contents; }
  html body .ptrdr .ptrcx-section .ptrsx-statpair > .ptrsx-statmedia > :is(img, video) {
    grid-column: 1; grid-row: 1; align-self: center;
    width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover;
    border-radius: 20px; display: block; background: #F1F1F4;
  }
  html body .ptrdr .ptrcx-section .ptrsx-statpair > .ptrsx-statmedia > figcaption {
    grid-column: 1; grid-row: 2; margin: 10px 0 0; padding: 0;
    font-size: 13px; line-height: 1.5; color: #6E707A;
  }
  html body .ptrdr .ptrcx-section .ptrsx-statpair > .ptrsx-statwrap { grid-column: 2; grid-row: 1; align-self: center; }

  /* 5. A hub row's caption floated under a centred picture when the copy
     column was the taller of the two. The caption belongs to the picture,
     so it sits on the picture's own row and takes its height from it. */
  html body .ptrdr .ptrcx-section .ptrsx-srow { align-content: center; }
  html body .ptrdr .ptrcx-section .ptrsx-srow > .ptrsx-smedia > figcaption { align-self: start; }
}

/* 2. An author line in a source row reads at its own measure: a citation
   is scanned, not read in paragraphs. */
.ptrdr .ptrsx-srcrow .ptrsx-srccopy > p { max-width: none !important; }

/* 4. A source row is a ROW, not a line of running text, so the blanket
   reading measure on list items does not apply to it. */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section li.ptrsx-srcrow,
  html body .ptrdr .ptrcx-section li.ptrdr-citerow { max-width: none !important; }
}

/* A pair's second row holds the caption, which carries its own 10px of
   space. The gap that separates the two COLUMNS was also being applied
   between the rows, so a pair whose picture column keeps its own box left
   an empty second row worth of air under it (measured 43px at 1440). The
   column gap stays; the row gap goes. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrsx-pair, .ptrsx-srow, .ptrsx-statpair) { row-gap: 0; }
}

/* ==================================================================== *
 * A COPY BLOCK ON THE RIGHT READS RIGHT AS ONE BLOCK, HEADING INCLUDED.
 * capability-composition.css forces every h1/h2/h3 in a section to the
 * left with !important, so a right-hand copy column showed a left heading
 * over right-aligned text and a right-aligned pill (measured on every
 * sector row and pair on /work/industries, 2026-09-05). The split is
 * media 58 / text 42: operator 2026-09-05 10:30, "text takes up more than
 * half ... videos are too small".
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section :is(.ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy, .ptrsx-srow:not(.ptrsx-rev) .ptrsx-scopy) > :is(h2, h3, p, ul, ol) { text-align: right !important; }
  html body .ptrdr .ptrcx-section :is(.ptrsx-pair.ptrsx-rev .ptrsx-pcopy, .ptrsx-srow.ptrsx-rev .ptrsx-scopy) > :is(h2, h3, p, ul, ol) { text-align: left !important; }
}

/* /xr chapter rows alternate with an inline direction: rtl on the grid. A
   copy column that lands on the right reads right as one block, heading
   included (operator, 2026-09-05: "right aligned for consistency"), and
   the split is text 58 / media 42 like every other pair. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[data-prerender-expect="xr-chapter"] { grid-template-columns: minmax(0, 42fr) minmax(0, 58fr) !important; }
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) > * { text-align: right !important; }
  html body .ptrdr .ptrcx-section .ptrcx-grid-2[style*="rtl"] > :is(.ptrcx-intro, .ptrsx-pcopy) { align-items: flex-end; }
}
/* A pull quote takes its measure from a COLUMN, not from a character cap:
   the quote reads in the left track and its attribution in the right, so
   a 36px quote cannot run the whole 1325px row. Same idiom as a pair. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-quote {
    display: grid;
    grid-template-columns: minmax(0, 60fr) minmax(0, 40fr);
    column-gap: clamp(24px, 3vw, 56px);
    align-items: center;
  }
  html body .ptrdr .ptrcx-section .ptrsx-quote > blockquote { grid-column: 1; margin: 0; }
  html body .ptrdr .ptrcx-section .ptrsx-quote > .ptrsx-attr { grid-column: 2; margin: 0; }
  html body .ptrdr .ptrcx-section .ptrsx-quote > .ptrsx-quoterest { grid-column: 1; margin: 14px 0 0; }
}

/* A band authored as centred (the /ai Digital Twins band: logo, kicker,
   heading, subline, four equal channel boxes, the Didymo control) stays
   centred all the way down; the shell inside it no longer resets to left
   and the global left-heading rule does not apply here. Operator 09-05:
   "needs the Didymo AI logo and needs to be centered". */
html body .ptrdr .ptrcx-section.ptrsx-centerband,
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-shell,
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-feature__copy { text-align: center !important; align-items: center; }
html body .ptrdr .ptrcx-section.ptrsx-centerband :is(h1, h2, h3, p, div) { text-align: center !important; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-feature__copy > p { margin-left: auto !important; margin-right: auto !important; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-grid-4 > * { text-align: center; align-items: center; }

html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-feature { display: block !important; grid-template-columns: none !important; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-feature__copy { width: 100%; max-width: none !important; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; width: 100%; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-grid-4 > * { grid-column: span 1 !important; }

/* The plane of builds is a three-across row: five tiles read three and
   two, not two, two and one, so a row-set never runs past two rows. */
@media (min-width: 1200px) {
  html body .ptrdr .ptrcx-section .ptrcx-shell.ptrcx-grid-3 {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }
  html body .ptrdr .ptrcx-section .ptrcx-shell.ptrcx-grid-3 > * { grid-column: span 1 !important; }
}

/* The try-it row is six cards: three across is two rows, which is the
   pacing rule. Its own inline gap had left it at two across. */
@media (min-width: 1200px) {
  html body .ptrdr .ptrcx-section .ptrcx-shell > .ptrcx-grid-6 {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }
  html body .ptrdr .ptrcx-section .ptrcx-shell > .ptrcx-grid-6 > * { grid-column: span 1 !important; }
}

/* ==================================================================== *
 * BAND VOCABULARY, 2026-09-05. The three pillar pages carried their band
 * layout as inline style attributes on ptrcx-intro / ptrcx-center /
 * ptrcx-measure elements, which is why every rule above had to out-shout
 * an inline declaration. The markup now names what each block IS and the
 * layout lives here only.
 *
 *   .ptrsx-tight    a band header: kicker, heading, subline as one block
 *   .ptrsx-p        running copy in a band, at the one body style
 *   .ptrsx-list     a list in a band, at the same body style
 * ==================================================================== */
.ptrdr .ptrsx-tight { width: 100%; display: flex; flex-direction: column; gap: clamp(10px, 1.1vw, 14px); }
.ptrdr .ptrsx-tight > * { margin: 0; width: 100%; }
.ptrdr .ptrsx-p { margin: 0; width: 100%; font-size: clamp(16px, 1.2vw, 19px); line-height: 1.65; color: var(--sx-body, #33353D); text-wrap: pretty; }
.ptrdr .ptrsx-list { margin: 0; width: 100%; padding-left: 22px; font-size: clamp(16px, 1.2vw, 19px); line-height: 1.65; color: var(--sx-body, #33353D); }
.ptrdr .ptrsx-list.ptrsx-plain { list-style: none; padding-left: 0; display: flex; flex-direction: column; gap: 6px; }
.ptrdr .ptrsx-rule { border-top: 1px solid rgba(11, 13, 18, 0.12); padding-top: clamp(22px, 3vh, 34px); }

/* ==================================================================== *
 * FULL-BLEED CATEGORY PANELS (operator 2026-09-05, /fast-builds): the
 * image is the full width of the page and the category word sits on top.
 * Text-free renders only; never a screenshot of a product. Copy alternates
 * sides; a right-hand copy block reads right as one block.
 * ==================================================================== */
.ptrdr .ptrsx-bleedset { display: flex; flex-direction: column; gap: 0; }
.ptrdr .ptrsx-bleedset > .ptrcx-shell + .ptrsx-bleed { margin-top: clamp(28px, 4vh, 44px); }
.ptrdr .ptrsx-bleed { position: relative; display: block; width: 100vw; margin-left: calc(50% - 50vw); min-height: clamp(440px, 64vh, 760px); overflow: hidden; text-decoration: none; color: #fff; background: #0B0D12; }
.ptrdr .ptrsx-bleed > video, .ptrdr .ptrsx-bleed > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ptrdr .ptrsx-bleed::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(6,8,16,0.82) 0%, rgba(6,8,16,0.55) 42%, rgba(6,8,16,0.08) 100%); }
.ptrdr .ptrsx-bleed.ptrsx-rev::after { background: linear-gradient(270deg, rgba(6,8,16,0.82) 0%, rgba(6,8,16,0.55) 42%, rgba(6,8,16,0.08) 100%); }
.ptrdr .ptrsx-bleedcopy { position: relative; z-index: 1; box-sizing: border-box; width: 100%; max-width: 1425px; margin: 0 auto; min-height: clamp(440px, 64vh, 760px); padding: clamp(40px, 6vh, 72px) clamp(20px, 4vw, 56px); display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 14px; text-align: left; }
.ptrdr .ptrsx-bleed.ptrsx-rev .ptrsx-bleedcopy { align-items: flex-end; text-align: right; }
.ptrdr .ptrsx-bleedcopy h3 { margin: 0; font-size: clamp(48px, 8vw, 128px); font-weight: 700; letter-spacing: -0.04em; line-height: 0.95; color: #fff; text-align: inherit; }
.ptrdr .ptrsx-bleedcopy .ptrsx-bleedpromise { margin: 6px 0 0; font-size: clamp(22px, 2.6vw, 36px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; color: #fff; }
.ptrdr .ptrsx-bleedcopy p { margin: 0; font-size: clamp(16px, 1.7vw, 21px); line-height: 1.5; color: rgba(255,255,255,0.88); max-width: 58%; text-align: inherit; }
.ptrdr .ptrsx-bleedcopy .ptrsx-pillbtn { margin-top: 10px; background: #fff; color: #0B0D12; border-color: #fff; }
/* Hover on a category panel: the word takes the brand gradient, nothing washes out (operator 2026-09-05). */
.ptrdr .ptrsx-bleed:hover .ptrsx-bleedcopy h3, .ptrdr .ptrsx-bleed:focus-visible .ptrsx-bleedcopy h3 { background: linear-gradient(90deg, #A567F1, #41BBF5, #80EDEF); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; animation: ptrsxGradientSlide 4s ease-in-out infinite; }
@keyframes ptrsxGradientSlide { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) { .ptrdr .ptrsx-bleed:hover .ptrsx-bleedcopy h3 { animation: none; } }
@media (max-width: 899.98px) {
  .ptrdr .ptrsx-bleedcopy p { max-width: none; }
  .ptrdr .ptrsx-bleed::after, .ptrdr .ptrsx-bleed.ptrsx-rev::after { background: linear-gradient(180deg, rgba(6,8,16,0.15) 0%, rgba(6,8,16,0.85) 100%); }
  /* lane-cifix, 2026-09-06: CI check-capability-composition TEXT-LEFT on
     /fast-builds at 768x1024 and 820x1180 (run 34013354302), MOBILE/AI/
     360/CUSTOM panels (the four .ptrsx-rev ones): this rule used to force
     align-items:flex-start (box hugs the LEFT) on every .ptrsx-bleedcopy,
     rev included, at any width <=899.98px - but a later, more specific
     rule (min-width:761px, "html body .ptrdr .ptrcx-section .ptrsx-bleed.
     ptrsx-rev .ptrsx-bleedcopy h3 { text-align:right !important; }") keeps
     the REV heading's text-align:right starting at 761px. Between 761 and
     899.98px both were active at once: right-aligned text inside a box
     still pinned to the left edge, so the text read as pinned to neither
     side (ratio=0.92). Scoped this line to non-rev only; rev's own
     align-items:flex-end (box hugs the right, set unconditionally at the
     top of this file) now carries through the 761-899.98px gap
     unchanged, matching the 761px+ text-align rule instead of fighting
     it. Verified: MOBILE/AI/360/CUSTOM's h3 box and text now both sit at
     the right edge at 768/820, 0px gutter delta. Below 761px the
     min-width:761px text-align:right rule (and the equally-scoped
     desktop-contract h1/h2/h3 left rule it exists to beat) both stop
     applying, so true phone widths get their own rule just below,
     keeping the original single-column, read-left stacking rev always
     had there - this fix only closes the 761-899.98px gap, it does not
     widen "reads right" onto phone widths that never asked for it. */
  .ptrdr .ptrsx-bleed:not(.ptrsx-rev) .ptrsx-bleedcopy { justify-content: flex-end; align-items: flex-start; text-align: left; }
}
@media (max-width: 760.98px) {
  .ptrdr .ptrsx-bleed.ptrsx-rev .ptrsx-bleedcopy { justify-content: flex-end; align-items: flex-start; text-align: left; }
}
/* Two stats side by side, equal bordered boxes, centred. */
.ptrdr .ptrsx-stats.ptrsx-stats--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ptrdr .ptrsx-stats.ptrsx-stats--2 .ptrsx-stat, .ptrdr .ptrsx-stats.ptrsx-stats--2 .ptrsx-stat p { text-align: center; }

/* HERO MEDIA FILLS ITS BOX (template, 2026-09-05). A hero photo or loop
   used to sit letterboxed inside its frame (object-fit contain under a
   60vh cap left grey bars either side of a 3:2 photo on /about/story and
   of every 16:9 loop at 1440x900). The operator also rules out cropped
   media, so the hero keeps its full frame at the row width with no height
   cap: no bars, no crop. */
html body .ptrdr .ptrcx-section .ptrsx-hero > img, html body .ptrdr .ptrcx-section .ptrsx-hero > video { width: 100%; height: auto; max-height: none; object-fit: contain !important; }

/* QUOTE BAND WITH A PERSON (operator 2026-09-05): "so much right padding ...
   make her photo larger". The photo takes the left column at 42 percent at
   its own aspect (no crop); the quote and attribution fill the right column. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who { display: grid; grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); gap: clamp(24px, 3vw, 56px); align-items: center; }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > blockquote { grid-column: 2; grid-row: 1; max-width: none !important; width: 100%; }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr { grid-column: 1; grid-row: 1; margin: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 14px; max-width: none !important; width: 100%; }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who .ptrsx-face { width: 100%; max-width: none; height: auto; border-radius: 20px; object-fit: contain !important; display: block; }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > span { font-size: 16px; line-height: 1.5; }
}
/* The same band when the 42 percent column carries a FILM (a WatchVideo
   import) instead of a photograph: the import fills the column edge to edge
   and the attribution reads beneath it, at every width. Without this the
   flex column sizes the import to its content and the film collapses. */
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr:has(.sc-host) { display: flex; flex-direction: column; align-items: stretch; gap: 14px; }
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > .sc-host { display: block; width: 100%; height: auto; }
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > .sc-host > figure { display: block !important; width: 100%; margin: 0 !important; }
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > .sc-host > figure > div { width: 100%; }
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > .sc-host > figure > figcaption { margin: 8px 0 0; padding: 0; font-size: 13px; line-height: 1.5; color: #6E707A; max-width: none !important; }

/* ==================================================================== *
 * LEGACY PAIRS ON EVERY PAGE, lane one-sheet 2026-09-05.
 * Sixty-six pages now load this file with their legacy markup. Two shapes
 * were measured on the served channel that the rules above did not reach:
 *  1  A .ptrcx-feature (or a two-column .ptrcx-grid-2) whose MEDIA comes
 *     first in the markup (a figure, a __media block, or a bare div that
 *     wraps the picture) puts its copy on the right. Measured on
 *     /learn/ai/ai-training-roleplay at 1440: heading and two paragraphs
 *     read left in a right-hand column, edges 134 px apart. The block reads
 *     right as one block, heading included (operator rule 4).
 *  2  A two-column .ptrcx-grid-2 that pairs one figure with one copy block
 *     split 50/50. Every pair is media 58 / text 42 (operator rule 3), so
 *     the split follows the side the media is on.
 * A band authored as centred (.ptrsx-centerband) is left alone.
 * ==================================================================== */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section:not(.ptrsx-centerband) :is(.ptrcx-feature, .ptrcx-grid-2):not(.ptrcx-feature--reverse):not(.ptrdr-rev)
    > :is(figure, .ptrcx-feature__media, div:has(> img, > video)):first-child + :is(.ptrcx-intro, .ptrcx-feature__copy, div:not(:has(img, video))) {
    text-align: right !important;
    align-items: flex-end;
  }
  html body .ptrdr .ptrcx-section:not(.ptrsx-centerband) :is(.ptrcx-feature, .ptrcx-grid-2):not(.ptrcx-feature--reverse):not(.ptrdr-rev)
    > :is(figure, .ptrcx-feature__media, div:has(> img, > video)):first-child + :is(.ptrcx-intro, .ptrcx-feature__copy, div:not(:has(img, video))) > :is(h1, h2, h3, h4, p, ul, ol, blockquote) {
    text-align: right !important;
  }
  html body .ptrdr .ptrcx-section:not(.ptrsx-centerband) :is(.ptrcx-feature, .ptrcx-grid-2):not(.ptrcx-feature--reverse):not(.ptrdr-rev)
    > :is(figure, .ptrcx-feature__media, div:has(> img, > video)):first-child + :is(.ptrcx-intro, .ptrcx-feature__copy, div:not(:has(img, video))) > :is(ul, ol) {
    padding-left: 0; padding-right: 22px;
  }
  /* media first: media 58, text 42; copy first: text 42, media 58 */
  html body .ptrdr .ptrcx-section:not(.ptrsx-centerband) .ptrcx-grid-2:not([data-prerender-expect="xr-chapter"]):has(> :is(figure, div:has(> img, > video)):first-child + :is(.ptrcx-intro, div:not(:has(img, video))):last-child) {
    grid-template-columns: minmax(0, 58fr) minmax(0, 42fr);
  }
  html body .ptrdr .ptrcx-section:not(.ptrsx-centerband) .ptrcx-grid-2:not([data-prerender-expect="xr-chapter"]):has(> :is(.ptrcx-intro, div:not(:has(img, video))):first-child + :is(figure, div:has(> img, > video)):last-child) {
    grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
  }
}

/* A tile that is a link keeps the tile look; a pill inside a right-hand copy
   block sits at the right edge with its text (operator 2026-09-05). */
.ptrdr a.ptrsx-tile.ptrsx-tilelink { display: block; text-decoration: none; color: inherit; }
.ptrdr a.ptrsx-tile.ptrsx-tilelink:hover figcaption strong, .ptrdr a.ptrsx-tile.ptrsx-tilelink:focus-visible figcaption strong { background: linear-gradient(90deg, #A567F1, #41BBF5, #80EDEF); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy .ptrsx-spill { justify-content: flex-end; }
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev .ptrsx-pcopy .ptrsx-spill { justify-content: flex-start; }
}

/* ==================================================================== *
 * /ai BANDS, 2026-09-05 PM. Operator: no product captures anywhere, the
 * Didymo card "very hard to read", the three-box strip "very bland", the
 * Digital Twins band on a dark ground with the Didymo wordmark, and every
 * channel with its own loop. Everything below is the template's own idioms
 * (pair, tile grid, centred band) plus a dark variant that keeps copy at
 * full white and never under 16px.
 * ==================================================================== */
/* A pair on a dark ground: full-white copy, 16px or more, and a dark tile
   chrome so the loop does not float as a white card. */
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-pcopy :is(h2, h3, p, li) { color: #fff; }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-pcopy .ptrsx-kicker { color: rgba(255, 255, 255, 0.72); }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-pcopy p { font-size: clamp(16px, 1.5vw, 20px); }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-pcopy .ptrsx-list { font-size: clamp(16px, 1.2vw, 19px); color: #fff; }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-tile { background: #111318; border-color: rgba(255, 255, 255, 0.12); }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-ondark .ptrsx-tile figcaption { color: rgba(255, 255, 255, 0.86); }
/* The Didymo card is the pair itself on a dark card: heading 34px, body
   and list items 16px at full white (operator: "very hard to read"). */
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-darkcard { background: #0B0D12; border-radius: 24px; overflow: hidden; box-shadow: 0 24px 60px rgba(11, 13, 18, 0.18); padding: clamp(20px, 2.4vw, 32px); }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-darkcard .ptrsx-pcopy h3 { font-size: 34px; line-height: 1.15; }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-darkcard .ptrsx-pcopy p:not(.ptrsx-kicker) { font-size: clamp(16px, 1.3vw, 18px); }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-darkcard .ptrsx-pcopy .ptrsx-list { font-size: 16px; }
.ptrdr .ptrcx-section .ptrsx-pair.ptrsx-darkcard .ptrsx-pcopy .ptrsx-pillbtn { background: #fff; border-color: #fff; color: #0B0D12; }
/* The pill row in a pair follows the block's reading side, like a sector
   row's. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-pair:not(.ptrsx-rev) .ptrsx-spill { justify-content: flex-end; }
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev .ptrsx-spill { justify-content: flex-start; }
}
/* The centred Digital Twins band on a dark ground: the Didymo wordmark
   above the kicker, white type all the way down. */
html body .ptrdr .ptrcx-section.ptrsx-centerband.ptrsx-dark { background: #060609; color: #fff; }
html body .ptrdr .ptrcx-section.ptrsx-centerband.ptrsx-dark :is(h2, h3, p, div) { color: #fff; }
html body .ptrdr .ptrcx-section.ptrsx-centerband.ptrsx-dark .ptrsx-kicker { color: rgba(255, 255, 255, 0.65); }
html body .ptrdr .ptrcx-section.ptrsx-centerband.ptrsx-dark .ptrsx-lead { color: #fff; margin-bottom: 0; }
.ptrdr .ptrsx-wordmark { width: clamp(220px, 25vw, 360px); height: auto; display: block; margin: 0 auto; }
/* The Didymo wordmark at the top of the Didymo card copy (operator 2026-09-05: at least 260px wide); it sits on the copy block's reading side. */
.ptrdr .ptrcx-section .ptrsx-pair .ptrsx-pcopy .ptrsx-cardmark { width: clamp(240px, 19vw, 280px); height: auto; display: block; margin: 0 0 6px; background: none; object-fit: contain; }
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-pair:not(.ptrsx-rev) .ptrsx-pcopy .ptrsx-cardmark { margin-left: auto; margin-right: 0; }
  html body .ptrdr .ptrcx-section .ptrsx-pair.ptrsx-rev .ptrsx-pcopy .ptrsx-cardmark { margin-left: 0; margin-right: auto; }
}
/* Channel tiles: a loop above its copy, four equal tiles four across
   (operator: "EACH get their own loop above their copy"). */
.ptrdr .ptrsx-chan { margin: 0; min-width: 0; display: flex; flex-direction: column; gap: 12px; align-items: center; text-align: center; }
.ptrdr .ptrsx-chan > video, .ptrdr .ptrsx-chan > img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; border-radius: 16px; background: #111318; }
/* A placeholder channel tile keeps the slot; its "Loop coming" label reads on the dark ground. */
html body .ptrdr .ptrcx-section.ptrsx-centerband.ptrsx-dark .ptrsx-chan .ptrsx-phlab { color: rgba(255, 255, 255, 0.72); width: 100%; }
.ptrdr .ptrsx-chan h3 { margin: 4px 0 0; width: 100%; font-size: clamp(18px, 1.5vw, 22px); font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; }
.ptrdr .ptrsx-chan p { margin: 0; width: 100%; font-size: 16px; line-height: 1.55; }
@media (min-width: 1200px) {
  html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrsx-g.ptrsx-chans { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; width: 100%; }
  html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrsx-g.ptrsx-chans > * { grid-column: span 1 !important; }
}
/* The centred band's content lives in a shell (the shell owns the gutters),
   the flow centres its items, the wordmark keeps its transparent ground and
   the round control sits in the flow with the action row close beneath it. */
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrcx-shell.ptrsx { align-items: center; }
html body .ptrdr .ptrcx-section .ptrsx-wordmark { background: none !important; object-fit: contain; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrsx-tight + .ptrsx-chans { margin-top: clamp(24px, 3vh, 40px) !important; }
html body .ptrdr .ptrcx-section.ptrsx-centerband .ptrsx > .twinActionsRow { margin-top: 18px; }

/* ==================================================================== *
 * THE FIVE STEPS AS A PINNED CINEMATIC (operator 2026-09-05, "think of the
 * home cinematic"): a wrapper five screens tall, a stage that fills the
 * viewport and sticks, one loop per step crossfading with scroll, the step
 * word carried between shapes by a particle canvas, the copy rising in,
 * and a rail that follows. Reduced motion: plain word, no per-frame loop.
 * ==================================================================== */
.ptrdr .ptrsx-cine { position: relative; width: 100vw; margin-left: calc(50% - 50vw); margin-top: clamp(28px, 4vh, 44px); height: calc(var(--ptrsx-steps, 5) * 100vh); background: #0B0D12; }
.ptrdr .ptrsx-cine[data-steps="5"] { --ptrsx-steps: 5; }
.ptrdr .ptrsx-cinestage { position: sticky; top: 0; height: 100vh; min-height: 560px; overflow: hidden; color: #fff; }
.ptrdr .ptrsx-cinevid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover !important; display: block; opacity: 0; transform: scale(1.06); transition: opacity 0.9s ease, transform 1.6s ease; }
.ptrdr .ptrsx-cinevid.is-active { opacity: 1; transform: scale(1); }
.ptrdr .ptrsx-cineshade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6,8,16,0.35) 0%, rgba(6,8,16,0.15) 40%, rgba(6,8,16,0.85) 100%); pointer-events: none; }
.ptrdr .ptrsx-cinecanvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ptrdr .ptrsx-cine.is-static .ptrsx-cinecanvas { display: none; }
.ptrdr .ptrsx-steprail { position: absolute; top: 0; left: 0; right: 0; z-index: 3; margin: 0; padding: 18px clamp(20px, 4vw, 56px); list-style: none; display: flex; gap: clamp(14px, 2.4vw, 36px); justify-content: center; pointer-events: none; }
.ptrdr .ptrsx-steprail li { font-size: 13px; letter-spacing: 0.22em; font-weight: 700; color: rgba(255,255,255,0.5); transition: color 0.4s ease; }
.ptrdr .ptrsx-steprail li.is-active { background: linear-gradient(90deg, #A567F1, #41BBF5, #80EDEF); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.ptrdr .ptrsx-cinecopy { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; box-sizing: border-box; width: 100%; max-width: 1425px; margin: 0 auto; padding: 0 clamp(20px, 4vw, 56px) clamp(48px, 8vh, 96px); display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; opacity: 0; transform: translateY(26px); transition: opacity 0.6s ease, transform 0.6s ease; pointer-events: none; }
.ptrdr .ptrsx-cinecopy.is-active { opacity: 1; transform: translateY(0); transition-delay: 0.15s; }
.ptrdr .ptrsx-cinecopy .ptrsx-stepnum { margin: 0; font-size: clamp(13px, 1.1vw, 15px); letter-spacing: 0.3em; color: rgba(255,255,255,0.7); }
.ptrdr .ptrsx-cinecopy .ptrsx-cineword { position: absolute; left: -9999px; top: -9999px; margin: 0; }
.ptrdr .ptrsx-cine.is-static .ptrsx-cinecopy .ptrsx-cineword { position: static; font-size: clamp(56px, 9vw, 144px); font-weight: 700; letter-spacing: -0.04em; line-height: 0.92; color: #fff; }
.ptrdr .ptrsx-cinecopy .ptrsx-stepwhen { margin: 0; font-size: clamp(22px, 2.6vw, 36px); font-weight: 700; letter-spacing: -0.02em; color: #fff; }
.ptrdr .ptrsx-cinecopy p { margin: 0; font-size: clamp(16px, 1.7vw, 21px); line-height: 1.5; color: rgba(255,255,255,0.92); max-width: 62ch; }
@media (max-width: 899.98px) { .ptrdr .ptrsx-cinestage { min-height: 520px; } .ptrdr .ptrsx-cinecopy p { max-width: none; } }
@media (prefers-reduced-motion: reduce) { .ptrdr .ptrsx-cinevid, .ptrdr .ptrsx-cinecopy, .ptrdr .ptrsx-steprail li { transition: none; } .ptrdr .ptrsx-cinevid { transform: none; } }

/* FAST BUILDS HERO AND ROBOT STAGE (operator 2026-09-05): the hero loop runs
   the full page width and blends into the page; the "what we build" copy
   sits over the robot band; a pointer-driven grid shader lives behind the
   robot; the band blends into the first category panel. */
.ptrdr .ptrsx-hero.ptrsx-hero--bleed { width: 100vw; margin-left: calc(50% - 50vw); border: 0; border-radius: 0; background: transparent; position: relative; }
.ptrdr .ptrsx-hero.ptrsx-hero--bleed > video, .ptrdr .ptrsx-hero.ptrsx-hero--bleed > img { -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 72%, transparent 100%); mask-image: linear-gradient(180deg, #000 0%, #000 72%, transparent 100%); }
.ptrdr .ptrsx-hero.ptrsx-hero--bleed figcaption { position: absolute; left: 0; right: 0; bottom: 18px; margin: 0 auto; max-width: 1425px; padding: 0 clamp(20px, 4vw, 56px); color: var(--sx-body); }
.ptrdr .ptrsx-robotband { padding: 0 !important; }
.ptrdr .ptrsx-robotstage { width: 100vw !important; max-width: none !important; margin-left: calc(50% - 50vw) !important; border-radius: 0 !important; box-shadow: none !important; }
.ptrdr .ptrsx-robotstage::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 28%; background: linear-gradient(180deg, rgba(11,13,18,0) 0%, #0B0D12 100%); pointer-events: none; z-index: 3; }
.ptrdr .ptrsx-gridshader { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }
.ptrdr .ptrsx-robotstage > canvas#robotCanvas, .ptrdr .ptrsx-robotstage > #robotPoster { z-index: 1; }
.ptrdr .ptrsx-robotcopy { position: absolute; z-index: 4; left: 0; right: 0; top: 0; box-sizing: border-box; width: 100%; max-width: 1425px; margin: 0 auto; padding: clamp(40px, 7vh, 88px) clamp(20px, 4vw, 56px) 0; pointer-events: none; }
.ptrdr .ptrsx-robotcopy .ptrsx-tight { pointer-events: auto; }
.ptrdr .ptrsx-robotcopy .ptrsx-lead { max-width: 58%; }
.ptrdr .ptrsx-bleedset > .ptrsx-bleed:first-child { margin-top: 0; }
@media (max-width: 899.98px) { .ptrdr .ptrsx-robotcopy .ptrsx-lead { max-width: none; } .ptrdr .ptrsx-robotstage { min-height: clamp(520px, 80vh, 760px) !important; } }

/* Hero and robot stage, second pass (measured 2026-09-05: 200 px of dead space
   above the hero copy, 400 px of empty page between the loop and the robot
   band, the copy sitting on the robot, the grid hidden behind the poster). */
.ptrdr .ptrsx-fbhero .ptrsx { gap: clamp(18px, 2.6vh, 28px) !important; }
.ptrdr .ptrsx-hero.ptrsx-hero--bleed { margin-top: clamp(8px, 2vh, 20px); margin-bottom: 0; }
.ptrdr .ptrsx-hero.ptrsx-hero--bleed > video, .ptrdr .ptrsx-hero.ptrsx-hero--bleed > img { -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 84%, transparent 100%); mask-image: linear-gradient(180deg, #000 0%, #000 84%, transparent 100%); }
.ptrdr .ptrsx-hero.ptrsx-hero--bleed figcaption { bottom: 10px; }
.ptrdr .ptrsx-robotband { margin-top: calc(-1 * clamp(40px, 6vh, 80px)); }
.ptrdr .ptrsx-robotstage { background: linear-gradient(180deg, #FAFAFC 0%, #E8EEFF 26%, #F1E8FF 62%, #0B0D12 100%) !important; }
.ptrdr .ptrsx-robotcopy { top: auto; bottom: 0; padding: 0 clamp(20px, 4vw, 56px) clamp(64px, 12vh, 140px); }
.ptrdr .ptrsx-robotcopy .ptrsx-tight { max-width: 54%; }
.ptrdr .ptrsx-robotcopy .ptrsx-lead { max-width: none; }
.ptrdr .ptrsx-robotcopy .ptrsx-h2, .ptrdr .ptrsx-robotcopy .ptrsx-lead, .ptrdr .ptrsx-robotcopy .ptrsx-kicker { color: #0B0D12; }
.ptrdr .ptrsx-robotstage > canvas#robotCanvas, .ptrdr .ptrsx-robotstage > #robotPoster { transform: translateX(22%); }
.ptrdr .ptrsx-gridshader { z-index: 1; mix-blend-mode: normal; opacity: 1; }
.ptrdr .ptrsx-robotstage > canvas#robotCanvas, .ptrdr .ptrsx-robotstage > #robotPoster { z-index: 2; }
.ptrdr .ptrsx-robotstage::after { height: 22%; }
@media (max-width: 899.98px) { .ptrdr .ptrsx-robotcopy .ptrsx-tight { max-width: none; } .ptrdr .ptrsx-robotstage > canvas#robotCanvas, .ptrdr .ptrsx-robotstage > #robotPoster { transform: none; } }

/* ==================================================================== *
 * CITATION ROWS AS PICTURE CARDS (operator 2026-09-05 on /learn/xr/what-is-xr:
 * "a lot of right padding ... use the images in this section as background
 * image"). Each source is a full-row card: its loop or picture fills the
 * card as the background, a scrim keeps the text readable, the copy sits
 * over it at the left. Applies to every .ptrsx-srcrow on the site.
 * ==================================================================== */
html body .ptrdr .ptrcx-section .ptrsx-srclist { display: flex; flex-direction: column; gap: clamp(14px, 2vw, 24px); }
html body .ptrdr .ptrcx-section .ptrsx-srcrow { position: relative; display: block !important; grid-template-columns: none !important; min-height: clamp(220px, 32vh, 340px); border-radius: 20px; overflow: hidden; background: #0B0D12; color: #fff; padding: 0 !important; margin: 0 !important; max-width: none !important; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srcpic { position: absolute; inset: 0; margin: 0; width: 100%; height: 100%; border: 0; border-radius: 0; background: #0B0D12; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srcpic > :is(img, video) { position: absolute !important; inset: 0 !important; width: 100% !important; height: 100% !important; min-height: 100% !important; object-fit: cover !important; display: block; aspect-ratio: auto !important; max-height: none !important; border-radius: 0 !important; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(6,8,16,0.88) 0%, rgba(6,8,16,0.62) 48%, rgba(6,8,16,0.10) 100%); pointer-events: none; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy { position: relative; z-index: 1; box-sizing: border-box; width: 100%; max-width: 64% !important; min-height: inherit; padding: clamp(24px, 3vw, 40px); display: flex; flex-direction: column; justify-content: center; gap: 8px; text-align: left; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy > * { max-width: none !important; margin: 0; color: #fff; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy > h3 { font-size: clamp(22px, 2.4vw, 32px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy > p { font-size: 16px; line-height: 1.5; color: rgba(255,255,255,0.92); }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy > .ptrsx-srcmeta { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(255,255,255,0.75); }
html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
html body .ptrdr .ptrcx-section .ptrsx-srcrow:nth-child(even)::after { background: linear-gradient(270deg, rgba(6,8,16,0.88) 0%, rgba(6,8,16,0.62) 48%, rgba(6,8,16,0.10) 100%); }
html body .ptrdr .ptrcx-section .ptrsx-srcrow:nth-child(even) > .ptrsx-srccopy { margin-left: auto !important; text-align: right; align-items: flex-end; }
@media (max-width: 899.98px) { html body .ptrdr .ptrcx-section .ptrsx-srcrow > .ptrsx-srccopy, html body .ptrdr .ptrcx-section .ptrsx-srcrow:nth-child(even) > .ptrsx-srccopy { max-width: none !important; margin-left: 0 !important; text-align: left; align-items: flex-start; } html body .ptrdr .ptrcx-section .ptrsx-srcrow::after, html body .ptrdr .ptrcx-section .ptrsx-srcrow:nth-child(even)::after { background: linear-gradient(180deg, rgba(6,8,16,0.35) 0%, rgba(6,8,16,0.88) 100%); } }

/* Photo tiles that must not show empty space (operator 2026-09-05, Our Story
   "the rooms those years happened in"): every picture in a .ptrsx-g--fill grid
   fills a 16:10 tile, cropped rather than letterboxed. */
html body .ptrdr .ptrcx-section .ptrsx-g--fill > .ptrsx-tile > img, html body .ptrdr .ptrcx-section .ptrsx-g--fill > .ptrsx-tile > video { width: 100% !important; height: auto !important; aspect-ratio: 16 / 10 !important; object-fit: cover !important; max-height: none !important; }

/* lane-about (2026-09-05): the About hub's 10+ YEARS band on a near-black
   ground. The big number and the tight heading/lead read white; the pair
   inside it is a standard .ptrsx-ondark pair. Scoped to .ptrsx-aboutdark so
   nothing here can reach the footer group. */
html body .ptrdr .ptrcx-section.ptrsx-aboutdark { background: #060609; color: #fff; }
html body .ptrdr .ptrcx-section.ptrsx-aboutdark .ptrsx-tight :is(.ptrsx-h2, .ptrsx-lead, .ptrsx-kicker) { color: #fff; }
html body .ptrdr .ptrcx-section.ptrsx-aboutdark .ptrsx-bignum { margin: 0 0 18px; width: 100%; max-width: none; font-size: clamp(46px, 15vw, 240px); font-weight: 700; letter-spacing: -0.05em; line-height: 0.9; color: #fff; }

/* Award picture cards (operator 2026-09-05 on /news: "show the background
 * images better"). A .ptrsx-srclist--award list keeps every row's copy on
 * the LEFT at 45 percent and fades the scrim out by 45 percent, so the right
 * 55 percent of the picture reads clear. No side alternation in this list. */
html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow::after,
html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow:nth-child(even)::after { background: linear-gradient(90deg, rgba(6,8,16,0.86) 0%, rgba(6,8,16,0.70) 28%, rgba(6,8,16,0.00) 45%); }
html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow > .ptrsx-srccopy,
html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow:nth-child(even) > .ptrsx-srccopy { max-width: 45% !important; margin-left: 0 !important; text-align: left; align-items: flex-start; }
@media (max-width: 899.98px) {
  html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow > .ptrsx-srccopy,
  html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow:nth-child(even) > .ptrsx-srccopy { max-width: none !important; }
  html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow::after,
  html body .ptrdr .ptrcx-section .ptrsx-srclist--award > .ptrsx-srcrow:nth-child(even)::after { background: linear-gradient(180deg, rgba(6,8,16,0.35) 0%, rgba(6,8,16,0.88) 100%); }
}

/* WatchVideo picture cards inside a tile grid (operator 2026-09-05 on
 * /news: recordings as 3-across picture cards). The lone-embed rule above
 * turns every .sc-host > figure into a 42/58 pair; inside a .ptrsx-g grid
 * the card is the tile, so the figure is a plain block and its 16:9 frame
 * takes the full tile width. */
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-g > .sc-host > figure { display: block; margin: 0; width: 100%; }
  html body .ptrdr .ptrcx-section .ptrsx-g > .sc-host > figure > div { width: 100%; }
}

/* ==================================================================== *
 * lane-pillars 2026-09-05: media that is not 16:9 keeps its own aspect
 * (rule 19). A 2:1 tile carries an unwrapped 360 strip; a portrait tile
 * carries a character render. Figcaption buttons (View in 360, Play the
 * strip) sit on one line with the caption text. Nothing here targets the
 * footer group.
 * ==================================================================== */
html body .ptrdr .ptrcx-section .ptrsx-tile.ptrsx-tile--2x1 > :is(img, video) { aspect-ratio: 2 / 1 !important; }
html body .ptrdr .ptrcx-section .ptrsx-tile.ptrsx-tile--portrait > img { aspect-ratio: 7 / 9 !important; object-fit: contain !important; background: #ECECEE !important; }
html body .ptrdr .ptrcx-section .ptrsx-tile > figcaption > :is(.ptr-view-360, .ptrsx-playstrip) { flex: none; margin-left: auto; padding: 6px 12px; border: 1px solid #0B0D12; border-radius: 999px; background: #fff; color: #0B0D12; font: inherit; font-size: 12px; line-height: 1.2; cursor: pointer; }
html body .ptrdr .ptrcx-section .ptrsx-tile > figcaption > .ptrsx-playstrip { margin-left: auto; }
html body .ptrdr .ptrcx-section .ptrsx-tile > figcaption > .ptrsx-playstrip + .ptr-view-360 { margin-left: 8px; }
html body .ptrdr .ptrcx-section .ptrsx-tile > figcaption:has(> button) { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
html body .ptrdr .ptrcx-section .ptrsx-tile > figcaption > .ptrsx-playstrip[aria-pressed="true"] { background: #0B0D12; color: #fff; }

/* lane-library 2026-09-05: the founder-quote attribution span (.ptrsx-attr >
   span, the Name/title/source text beside the headshot in .ptrsx-quote--who)
   sits in a flex column with align-items:flex-start (rule above, ~line 1685),
   so at wide viewports the span shrinks to its own text width instead of
   filling the 42% attribution column - measured on /xr/ptr-vr-library and
   four Library titles as "stops Npx short of its column" (check-text-
   alignment.mjs --mode full-width, TWO-COL-FILL-CELL) at 1920/2560px. Width
   only; no alignment or type change. */
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr > span { width: 100%; }

/* lane-mobile */

/* ==================================================================== *
 * lane-mobile (2026-09-05): LAYOUT AT 390. Job 1 of LANE-MOBILE brief.
 * Scope: every routed page except Home and the footer group (rules 9,
 * 52, 53 untouched; nothing here names .wcs*, .ldb*, .asd*, .ttu*,
 * .ptrFooter* or #ptrTopNavBar). Fixes are template-level, single sheet,
 * max-width: 767.98px only, so nothing here changes the 900px-plus
 * desktop rules already proven by the content lanes.
 * ==================================================================== */

/* 1a. Founder quote band: photo above quote at mobile. Measured defect:
   .ptrsx-quote--who is <blockquote> then <p class="ptrsx-attr"> (the
   photo) in the DOM, because the 761px-plus grid reorders them onto
   columns with the photo on the left. Below 761px no reorder rule
   existed, so the band rendered quote text first and the photo second,
   the opposite of the LANE-MOBILE brief's stacking order. Flex plus
   order fixes it without touching the 761px-plus grid rule. */
@media (max-width: 767.98px) {
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who {
    display: flex;
    flex-direction: column;
  }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > blockquote {
    order: 2;
    margin: 0;
  }
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who > .ptrsx-attr {
    order: 1;
    margin: 0 0 16px;
    max-width: 220px;
  }
}

/* 1b. .ptrsx-bleed category panels: the h3 word clamp floors at 48px
   regardless of viewport, since 8vw drops under 48px well before 600px.
   Every word live today (WEB, MOBILE, GAMES, AI, XR, 360, EVENTS,
   CUSTOM) fits a 390px stage with room either side, but the floor is
   lowered under 480px so a longer future category word cannot overrun
   the viewport; the promise line gets the same treatment. */
@media (max-width: 479.98px) {
  html body .ptrdr .ptrcx-section .ptrsx-bleedcopy h3 {
    font-size: clamp(38px, 13vw, 56px) !important;
    text-wrap: balance;
  }
  html body .ptrdr .ptrcx-section .ptrsx-bleedcopy .ptrsx-bleedpromise {
    font-size: clamp(18px, 5.5vw, 24px) !important;
  }
}

/* 1c. .ptrsx-cine (the pinned five-step cinematic): the stage already
   drops to a 520px floor at 899.98px and under, but a 390-wide phone in
   a short browser chrome window can still come in under that with the
   step rail and the step-when line competing for room. Floor lowered
   further, the step rail wraps instead of overflowing, and step-when
   type scales down so a two-line step label does not collide with the
   rail. Touch scrolling itself is unchanged: the existing rAF plus
   scroll-listener script on .ptrsx-cine already runs on any input, not
   only wheel. */
@media (max-width: 479.98px) {
  html body .ptrdr .ptrsx-cinestage { min-height: 460px; }
  html body .ptrdr .ptrsx-steprail { flex-wrap: wrap; row-gap: 6px; padding: 14px clamp(16px, 5vw, 24px); }
  html body .ptrdr .ptrsx-cinecopy .ptrsx-stepwhen { font-size: clamp(20px, 6vw, 28px); }
  html body .ptrdr .ptrsx-cinecopy { padding-left: clamp(16px, 5vw, 24px); padding-right: clamp(16px, 5vw, 24px); }
}

/* 1d. The "g3-grid mobile-stacking" content-rhythm finding, flagged by
   lane-cshubs (commit 1790dc9) as sitewide and template-level, not
   per-page. Measured root cause: tools/check-content-rhythm.mjs groups
   media into one VIDEO-ROW by shared rendered top inside one grid or
   flex-row container (its isRowContainer/containerFor functions). At
   900px and up these tile families lay out 3 across, so a 6-tile grid is
   2 VIDEO-ROWs. At mobile every one of them already collapses to a
   single column (this file's own "Row cap ... 1 below" comment), which
   is correct for a 1-up reading layout, but the same N tiles become N
   stacked VIDEO-ROWs, so any grid of 3 or more tiles fails the "no more
   than 2 rows without a heading and subline" rule on mobile even where
   its desktop layout passes.

   Decision, recorded here rather than asked of the operator: the real
   per-page fix is a true heading and subline INSIDE a long grid, which
   is content authorship, not layout, exactly what lane-cshubs already
   did on its own 8 pages, and exactly what the brief bans this lane from
   fabricating (no meta text, no invented headings). A CSS ::before
   heading would not count either: the gate reads real DOM text
   (element.innerText), so decorative generated content would not
   register as a break and would be dishonest content besides.

   The template-level fix this lane can make, and does: these tile
   families (loop-thumbnail collections, not primary hero or pair media)
   run as a single horizontally scrollable row at mobile widths instead
   of a vertical stack. A flex row lays every tile at the same rendered
   top, so the gate's own grouping counts the whole collection as ONE
   VIDEO-ROW at 390, matching what a reader actually meets: one visual
   band they can swipe, not a monotonous vertical wall of loops. This
   does not add page-level horizontal scroll (the rail scrolls inside its
   own box; document.documentElement.scrollWidth is unaffected, measured
   in the lane report), places every tile exactly once at a larger
   visible size than the old 1-up tile, and keeps every approved loop on
   the page. Scope is the tile families already grouped together
   elsewhere in this file (the row-cap section, the object-fit and
   figcaption rules), not .ptrcx-grid-2 (2 tiles is already 2 rows
   stacked or fewer) and not .ptrcx-cards (auto-fit feature cards, text
   led, not a loop collection).

   Residual, left open on purpose: a handful of very large single-page
   grids (a dozen tiles or more) still read as a long rail to swipe
   rather than 2 rows then a break; closing that fully needs a per-page
   heading split, which is a copy decision for the page-owning content
   lane, per lane-cshubs' own note, not a template layout fix. */
@media (max-width: 767.98px) {
  html body .ptrdr.ptrdr .ptrcx-section.ptrcx-section :is(.ptrsx-g, .ptr-vgrid, .ptrcx-vgrid3,
    .ptrdr-tiles, .xrex-grid, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
    .ptrcx-grid-7, .ptrcx-grid-8) {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    grid-template-columns: none !important;
    align-items: stretch;
    gap: 14px !important;
    overflow-x: auto;
    overflow-y: visible;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scroll-padding-left: 4px;
    padding-bottom: 6px;
    scrollbar-width: thin;
  }
  html body .ptrdr.ptrdr .ptrcx-section.ptrcx-section :is(.ptrsx-g, .ptr-vgrid, .ptrcx-vgrid3,
    .ptrdr-tiles, .xrex-grid, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
    .ptrcx-grid-7, .ptrcx-grid-8) > * {
    grid-column: auto !important;
    flex: 0 0 auto !important;
    width: min(320px, 82vw) !important;
    max-width: min(320px, 82vw) !important;
    scroll-snap-align: start;
  }
  html body .ptrdr.ptrdr .ptrcx-section.ptrcx-section :is(.ptrsx-g, .ptr-vgrid, .ptrcx-vgrid3,
    .ptrdr-tiles, .xrex-grid, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6,
    .ptrcx-grid-7, .ptrcx-grid-8) > :only-child {
    width: 100% !important;
    max-width: 100% !important;
  }
}
@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
  html body .ptrdr .ptrcx-section :is(.ptrsx-g, .ptr-vgrid, .ptrcx-vgrid3, .ptrdr-tiles,
    .xrex-grid, .ptrcx-grid-3, .ptrcx-grid-4, .ptrcx-grid-5, .ptrcx-grid-6, .ptrcx-grid-7,
    .ptrcx-grid-8) {
    scroll-behavior: auto;
  }
}

/* 1e. Safety net: nothing on the page may exceed the viewport width at
   390 (measured per route with a dedicated scrollWidth walk, see the
   lane report). max-width:100% on any raw media that slipped through a
   component without its own rule, and overflow-wrap on any run of
   unbroken text (a bare URL in a citation source line was the one shape
   not already covered by the pair and measure rules above). */
@media (max-width: 767.98px) {
  html body .ptrdr .ptrcx-section img, html body .ptrdr .ptrcx-section video,
  html body .ptrdr .ptrcx-section canvas, html body .ptrdr .ptrcx-section iframe {
    max-width: 100%;
  }
  html body .ptrdr .ptrcx-section :is(p, li, blockquote, figcaption, a) {
    overflow-wrap: break-word;
    word-break: break-word;
  }
}

/* lane-defects, 2026-09-06: /fast-builds text-align finding from the gates
   lane's sweep at tip 7b25ff4 (measured, not fixed there - that lane never
   edits pages). Appended here per rule A1 (one template stylesheet); this
   rule does not touch another lane's block above.

   .ptrsx-bleed.ptrsx-rev .ptrsx-bleedcopy h3 computed text-align:left
   (MOBILE, AI, 360, CUSTOM) even though the panel is right-anchored
   (align-items:flex-end on .ptrsx-rev .ptrsx-bleedcopy at line ~1653):
   `.ptrsx-bleedcopy h3 { text-align: inherit; }` (line ~1654) loses to
   the desktop-contract rule `.ptrcx-section :is(h1,h2,h3) { text-align:
   left !important; }` (line 186) because both are !important and 186
   comes later in an equal-specificity tie - only a MORE SPECIFIC rule
   beats it. Verified via CDP: getComputedStyle(h3).textAlign was "left"
   on all eight panels before this fix (rule 4: right block reads right);
   confirmed "right" on the four .ptrsx-rev panels after it, on the
   published channel, at 1440.

   The brief's second finding ("`.ptrsx-robotcopy` renders about 100 px
   wider than its stage, clipped by overflow:hidden") was investigated and
   NOT reproduced: measured .ptrsx-robotcopy vs #robotWrap (its only
   overflow:hidden ancestor) by CDP at 390/600/800/1024/1440/1920/2560/3840
   on both this branch's local render and the published channel - the copy
   box never exceeds its stage (e.g. at 1440: robotcopy right=1432.5 inside
   robotstage right=1440; scrollWidth == clientWidth); a clipped 1440
   screenshot shows no cut-off text. The only real, currently-measurable
   defect on that box is a content-rhythm ROW-WIDTH finding (its .ptrsx-tight
   column fills ~42-50% of the row width at various widths, by the existing
   max-width:54% rule at line ~1864) - a different shape of problem (an
   under-filled row) than "wider than its stage", already visible in
   check-capability-composition.mjs output and left for the lane that owns
   row-fill composition, not renamed or reframed here. */
@media (min-width: 761px) {
  html body .ptrdr .ptrcx-section .ptrsx-bleed.ptrsx-rev .ptrsx-bleedcopy h3 { text-align: right !important; }
  html body .ptrdr .ptrcx-section .ptrsx-bleed:not(.ptrsx-rev) .ptrsx-bleedcopy h3 { text-align: left !important; }
}

/* lane-cifix, 2026-09-06: CI check-section-centering BLOCK-OVERFLOW on
   /fast-builds at 1440 (run 34010637248): "Eight kinds of build..." <DIV>
   width=1425.0 parent=1324.8. Root cause: .ptrsx-robotcopy is position:
   absolute inside #robotWrap (.ptrcx-shell.ptrsx-robotstage), a full-
   bleed 100vw band. Its containing block for absolute positioning is
   robotWrap's PADDING box (100vw, since left:0/right:0 ignore robotWrap's
   own padding-inline), so robotcopy's width:100% resolved against the
   viewport and only the flat max-width:1425px capped it - wider than the
   shell's own content measure (viewport minus padding-inline:clamp(20px,
   4vw,240px), 1324.8px at 1440) whenever the viewport is close to 1425px
   (1425-1549px window; 1440 sits inside it). At 1920/2560/3840 the shell
   measure already exceeds 1425 so it never reproduced there, and a
   flatter cap would only have narrowed the window, not closed it.
   Fix: give the copy the shell's own left/right inset instead of a flat
   px cap, so its box is DERIVED from the same formula as the content
   column at every width, not a constant that can cross it. Copy text is
   unchanged. Measured on the local composition check (1440/1920/2560/
   3840): robotcopy's right edge equals #robotWrap's content-box right
   edge (0px delta) at every width; PASS replaces the prior BLOCK-OVERFLOW. */
.ptrdr .ptrsx-robotcopy {
  left: clamp(20px, 4vw, 240px);
  right: clamp(20px, 4vw, 240px);
  width: auto;
  max-width: none;
  margin: 0;
}

/* Operator 2026-09-06 on /xr: "must not make client testimonial photos huge if
   they are low resolution". The 42 percent column used to force width:100% on
   the photograph, so a 200px headshot was blown up to ~532px and read as
   pixelated. The photo now renders at its own size, capped by the column: a
   large portrait still fills the column, a small headshot stays sharp and sits
   at the top of the column with the attribution under it. */
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--who .ptrsx-face { width: auto !important; max-width: 100% !important; height: auto; }

/* A CLIENT testimonial is a headshot beside the quote, not a portrait that
   fills the column (operator 2026-09-06 on /xr: the face read as huge). The
   FOUNDER bands keep the large photo the operator asked for; only bands marked
   .ptrsx-quote--client are capped, and the quote takes the width the photo
   gives back. */
html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--client .ptrsx-face { width: auto !important; max-width: min(100%, clamp(150px, 16vw, 220px)) !important; height: auto; border-radius: 18px; }
@media (min-width: 900px) {
  html body .ptrdr .ptrcx-section .ptrsx-quote.ptrsx-quote--client { grid-template-columns: minmax(0, 24fr) minmax(0, 76fr); align-items: center; }
}

/* Full-bleed page hero (operator 2026-09-06 on /xr): the hero footage IS the
   background, the kicker, h1 and lead sit on top of it, and the bottom of the
   image blends into the page's own white so the next band starts clean. The
   media uses the full-size file, never the -720 variant (rule 36). */
.ptrdr .ptrsx-herofull { position: relative; width: 100vw; margin-left: calc(50% - 50vw); min-height: clamp(560px, 82vh, 900px); display: flex; align-items: flex-end; overflow: hidden; background: #06070C; }
.ptrdr .ptrsx-herofull__media { position: absolute; inset: 0; }
.ptrdr .ptrsx-herofull__media > video, .ptrdr .ptrsx-herofull__media > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ptrdr .ptrsx-herofull__fade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6,7,12,0.58) 0%, rgba(6,7,12,0.40) 26%, rgba(6,7,12,0.14) 48%, rgba(250,250,252,0) 64%, rgba(250,250,252,0.86) 89%, #FAFAFC 100%); }
.ptrdr .ptrsx-herofull__copy { position: relative; z-index: 1; width: 100%; padding: clamp(120px, 16vh, 200px) clamp(20px, 4vw, 56px) clamp(56px, 9vh, 110px); display: flex; flex-direction: column; gap: clamp(18px, 2.6vh, 30px); }
.ptrdr .ptrsx-herofull__copy .ptrsx-kicker { color: rgba(255,255,255,0.86); }
.ptrdr .ptrsx-herofull__copy .ptrsx-h1, .ptrdr .ptrsx-herofull__copy .ptrsx-lead { color: #FFFFFF; text-shadow: 0 2px 18px rgba(6,7,12,0.55), 0 1px 3px rgba(6,7,12,0.45); }
@media (max-width: 767.98px) {
  .ptrdr .ptrsx-herofull { min-height: clamp(460px, 72vh, 620px); }
  .ptrdr .ptrsx-herofull__copy { padding-top: clamp(96px, 14vh, 150px); }
}

/* lane-cifix, 2026-09-06: CI check-capability-composition ORPHAN-ROW on
   /fast-builds's "Shaped by hand before it is built" (n=3) at
   768/820/960 and "Phones and tablets, tried where they will be used"
   (n=4) at 1024 (run 34013354302). Both are plain .ptr-vgrid grids;
   FastBuilds is explicitly excluded from apply-video-grid-format.mjs (its
   own bespoke cinematic/robot bands), so unlike every other page's
   .ptr-vgrid, these two never get a data-composition="balanced" stamp or
   the tool's own per-count balanced row split - they fall through to the
   generic, page-agnostic column rules instead, which produce a real
   visual defect here: a lone final tile sitting alone in its own
   column-width cell with dead space beside it (2+1 at 761-999.98px from
   the "Row cap" rule near line 311, 3+1 at 1000-1199.98px from the
   laptop-tile rule near line 1052, whose own trailing-tile companion
   rule near line 1077 deliberately keeps a lone TILE-GRID, .ptrsx-g3 and
   friends, in its own cell - a different, balanced-split-aware class of
   grid this page's plain .ptr-vgrid is not, so the same "don't promote"
   choice does not carry the same justification here).
   Promoting the trailing lone .ptr-vgrid item to the full row (the
   behaviour .ptrcx-grid-3/4/5 already get at 761-999.98px from the same
   "Row cap" block) removes the dead space; matched to each overridden
   rule's own specificity so cascade order cannot flip it back, scoped to
   .ptr-vgrid only so .ptrsx-g3's own deliberate choice is untouched.
   Verified: both grids' final row is full-width at every affected
   breakpoint, 0 findings. */
@media (min-width: 761px) and (max-width: 1199.98px) {
  html body .ptrdr .ptrcx-section .ptr-vgrid > :last-child:nth-child(odd):nth-child(n):nth-child(n):nth-child(n) {
    grid-column: 1 / -1 !important;
  }
}
@media (min-width: 1000px) and (max-width: 1199.98px) {
  /* This window is 3 columns (not 2), so a lone trailing item is whatever
     is left over after groups of 3, not "an odd position" (that heuristic
     only holds for a 2-column grid, which is what :last-child:nth-child
     (odd) actually tests) - :nth-child(3n+1) is the correct "first of a
     new row of 3" test, and :last-child confirms nothing follows it. */
  html body .ptrdr .ptrcx-section .ptr-vgrid > *:last-child:nth-child(3n+1):nth-child(n):nth-child(n) {
    grid-column: 1 / -1 !important;
  }
}

/* A product wordmark that needs a dark ground, sitting inside a light copy
   column (operator 2026-09-06: the Didymo logo with its text belongs with the
   digital-twins section on /ai). */
.ptrdr .ptrsx-brandchip { display: inline-flex; align-items: center; justify-content: center; padding: 12px 18px; border-radius: 14px; background: #06070C; }
.ptrdr .ptrsx-brandchip > img { display: block; width: auto; height: clamp(26px, 3.4vw, 38px); }

/* Fast Builds: the hero, the robot stage and the eight category panels read as
   ONE surface (operator 2026-09-06: "the hero, the robot what we build and web
   need to all blend"). The hero's base fades into the robot stage's own top
   colour instead of the page white, the stage runs full width with no gap, and
   the first panel begins where the stage ends. */
.ptrdr .ptrsx-herofull--fb .ptrsx-herofull__fade { background: linear-gradient(180deg, rgba(6,7,12,0.58) 0%, rgba(6,7,12,0.40) 26%, rgba(6,7,12,0.14) 48%, rgba(250,250,252,0) 66%, rgba(250,250,252,0.88) 90%, #FAFAFC 100%); }
.ptrdr .ptrsx-herofull--fb + .ptrsx-fbjoin { margin-top: 0; }
.ptrdr .ptrsx-fbjoin { margin-top: 0 !important; }
.ptrdr .ptrsx-fbjoin > .ptrsx-robotstage { width: 100vw; margin-left: calc(50% - 50vw); max-width: none; border-radius: 0; }
.ptrdr .ptrsx-robotband + .ptrsx-bleedset, .ptrdr .ptrsx-fbjoin.ptrsx-bleedset { margin-top: 0 !important; }
.ptrdr .ptrsx-fbjoin.ptrsx-bleedset > .ptrsx-bleed:first-child { margin-top: 0; }
.ptrdr .ptrsx-herofull--fb .ptrsx-stats { margin-top: clamp(18px, 2.6vh, 30px); }
.ptrdr .ptrsx-herofull--fb .ptrsx-stat { background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.36); box-shadow: 0 16px 40px rgba(6,7,12,0.22), inset 0 1px 0 rgba(255,255,255,0.28); backdrop-filter: blur(14px) saturate(150%); -webkit-backdrop-filter: blur(14px) saturate(150%); }
.ptrdr .ptrsx-herofull--fb .ptrsx-stat .ptrsx-num { color: #FFFFFF; text-shadow: 0 2px 10px rgba(6,7,12,0.55), 0 1px 2px rgba(6,7,12,0.45); }
.ptrdr .ptrsx-herofull--fb .ptrsx-stat p { color: rgba(255,255,255,0.94); text-shadow: 0 1px 2px rgba(6,7,12,0.5); }

/* Measured on the channel at 1440 (2026-09-06): hero bottom 1047 = stage top
   1047 and stage bottom 1785 = panel set top 1785, but 43px of page ground sat
   between the stage's dark base and the first dark panel, so the surfaces read
   as three blocks rather than one. */
.ptrdr .ptrsx-fbjoin.ptrsx-bleedset > .ptrsx-bleed { margin-top: 0 !important; }
.ptrdr .ptrsx-fbjoin.ptrsx-bleedset > .ptrcx-shell + .ptrsx-bleed { margin-top: 0 !important; }
.ptrdr .ptrsx-fbjoin.ptrsx-bleedset { padding-top: 0 !important; }

/* The seam the operator saw: the robot stage ends on #0B0D12 while the first
   category panel starts on its own bright footage, so the two dark surfaces met
   at a hard edge. The first panel of a joined set now emerges out of that same
   base colour, and the stage's own base fade is deepened to meet it. */
.ptrdr .ptrsx-fbjoin > .ptrsx-robotstage::after { height: 34%; background: linear-gradient(180deg, rgba(11,13,18,0) 0%, rgba(11,13,18,0.55) 46%, #0B0D12 100%); }
.ptrdr .ptrsx-fbjoin.ptrsx-bleedset > .ptrsx-bleed:first-of-type::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 26%; background: linear-gradient(180deg, #0B0D12 0%, rgba(11,13,18,0.72) 38%, rgba(11,13,18,0) 100%); z-index: 2; pointer-events: none; }

/* The two ways to reach PTR, at the top of /talk-to-us (operator 2026-09-06:
   "we need to funnel people to the Contact Form ... or ask questions with the
   didymo widget", and "the Talk to us page needs the contact form in it from
   the beginning"). */
.ptrdr .ptrsx-ctarow { margin-top: clamp(18px, 2.6vh, 28px); gap: 12px; }
.ptrdr .ptrsx-pillbtn--solid { background: #0B0D12; color: #FFFFFF; border-color: #0B0D12; }
.ptrdr .ptrsx-pillbtn--solid:hover { background: #1B1E28; border-color: #1B1E28; }

/* The credit line under a full-bleed hero, where the footage is of a person
   (operator 2026-09-06, /about/values). */
.ptrdr .ptrsx-herofull__copy .ptrsx-herocred { margin: 0; font-size: 14px; line-height: 1.5; color: rgba(255,255,255,0.84); text-shadow: 0 1px 3px rgba(6,7,12,0.5); }
.ptrdr .ptrsx-herofull__copy .ptrsx-kicker a { color: inherit; }

/* The "next chapter" band (operator 2026-09-06: it read as squished against
   its neighbours, the copy wanted centring, and it needed something to make
   it lift off the page). The band now has its own air, the copy is centred,
   and an ambient Australian-landscape wash sits behind it on a canvas that
   leans towards the pointer (public/ptrsx-ctaglow.js). The wash is masked to
   nothing at the top and bottom edges, so the band has no seam against
   whatever section sits above or below it. */
.ptrdr .ptrsx-ctaband { position: relative; isolation: isolate; text-align: center; padding: clamp(76px, 11vh, 130px) clamp(20px, 4vw, 56px); margin: clamp(32px, 5vh, 56px) 0; border-radius: 0; }
.ptrdr .ptrsx-ctaband .ptrsx-lead, .ptrdr .ptrsx-ctaband h2, .ptrdr .ptrsx-ctaband h3, .ptrdr .ptrsx-ctaband p { text-align: center !important; margin-left: auto; margin-right: auto; max-width: 46ch; }
.ptrdr .ptrsx-ctaband .ptrsx-ctarow { justify-content: center; margin-top: clamp(20px, 3vh, 30px); }
@media (max-width: 767.98px) {
  .ptrdr .ptrsx-ctaband { padding: clamp(44px, 7vh, 72px) 20px; border-radius: 20px; }
  .ptrdr .ptrsx-ctaband .ptrsx-ctarow { flex-direction: column; align-items: stretch; }
}

/* The call-to-action band carries footage (operator 2026-09-06): the eight
   approved world clips as one 29s loop, full page width, black at the top and
   bottom edges so it fades into the page above and below. The question line
   runs the brand gradient, and both controls are glass over the footage. */
.ptrdr .ptrsx-ctaband { position: relative; isolation: isolate; text-align: center; width: 100vw; max-width: none; margin-left: calc(50% - 50vw); margin-top: clamp(32px, 5vh, 56px); margin-bottom: clamp(32px, 5vh, 56px); padding: clamp(140px, 22vh, 260px) clamp(20px, 4vw, 56px); border-radius: 0; overflow: hidden; background: #FAFAFC; }
.ptrdr .ptrsx-ctavid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: 0; }
.ptrdr .ptrsx-ctascrim { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(180deg, #FAFAFC 0%, rgba(250,250,252,0.82) 9%, rgba(6,7,12,0.30) 26%, rgba(6,7,12,0.46) 50%, rgba(6,7,12,0.30) 74%, rgba(250,250,252,0.82) 91%, #FAFAFC 100%); }
.ptrdr .ptrsx-ctaband > :not(.ptrsx-ctavid):not(.ptrsx-ctascrim) { position: relative; z-index: 2; }
.ptrdr .ptrsx-ctaband .ptrsx-lead, .ptrdr .ptrsx-ctaband h2, .ptrdr .ptrsx-ctaband h3 { font-size: clamp(28px, 3.4vw, 44px); line-height: 1.16; font-weight: 700; letter-spacing: -0.02em; max-width: 22ch; color: #FFFFFF; text-shadow: 0 2px 22px rgba(6,7,12,0.62), 0 1px 3px rgba(6,7,12,0.5); }
@keyframes ptrsxCtaHue { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@media (prefers-reduced-motion: reduce) { .ptrdr .ptrsx-ctaband .ptrsx-lead { animation: none; } }
.ptrdr .ptrsx-ctaband p:not(.ptrsx-lead) { color: rgba(255,255,255,0.86); }
.ptrdr .ptrsx-ctaband .ptrsx-pillbtn { background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.42); color: #FFFFFF;
  backdrop-filter: blur(14px) saturate(150%); -webkit-backdrop-filter: blur(14px) saturate(150%); box-shadow: 0 14px 34px rgba(6,7,12,0.32), inset 0 1px 0 rgba(255,255,255,0.24); }
.ptrdr .ptrsx-ctaband .ptrsx-pillbtn:hover { background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.62); }
.ptrdr .ptrsx-ctaband .ptrsx-pillbtn--solid { background: rgba(255,255,255,0.92); border-color: rgba(255,255,255,0.92); color: #0B0D12; }
.ptrdr .ptrsx-ctaband .ptrsx-pillbtn--solid:hover { background: #FFFFFF; border-color: #FFFFFF; color: #0B0D12; }
@media (max-width: 767.98px) {
  .ptrdr .ptrsx-ctaband { padding: clamp(56px, 9vh, 92px) 20px; }
  .ptrdr .ptrsx-ctaband .ptrsx-ctarow { flex-direction: column; align-items: stretch; }
}

/* WHAT WE BUILD sits vertically centred on the robot stage (operator
   2026-09-06), instead of hanging from the top or sitting on the floor of it.
   The left/right insets from the overflow fix above are kept, so the copy
   still derives its box from the shell's own formula. */
.ptrdr .ptrsx-robotband .ptrsx-robotcopy { top: 0; bottom: 0; display: flex; flex-direction: column; justify-content: center; padding-top: clamp(24px, 4vh, 56px); padding-bottom: clamp(24px, 4vh, 56px); }
@media (max-width: 899.98px) { .ptrdr .ptrsx-robotband .ptrsx-robotcopy { justify-content: flex-end; padding-bottom: clamp(40px, 8vh, 96px); } }

/* The two timing figures run the brand gradient (operator 2026-09-06), the
   same treatment as the call-to-action question line. */
.ptrdr .ptrsx-herofull--fb .ptrsx-stat p { background: linear-gradient(92deg, #80EDEF 0%, #41BBF5 24%, #A567F1 58%, #F00EF9 100%); background-size: 260% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: none; animation: ptrsxCtaHue 9s ease-in-out infinite; font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .ptrdr .ptrsx-herofull--fb .ptrsx-stat p { animation: none; } }

/* Anything clickable shows a pointer (operator 2026-09-06: the twin control
   did not change the cursor). Buttons default to `default` in every browser;
   this makes every control on the site read as clickable. */
.ptrdr button, .ptrdr [role="button"], .ptrdr a[href], .ptrdr summary, .ptrdr label[for],
.ptrdr .ptrsx-pillbtn, .ptrdr .ptrsx-tilelink, .ptrdr [data-ptr-action] { cursor: pointer; }
.ptrdr button:disabled, .ptrdr [aria-disabled="true"] { cursor: not-allowed; }
