/* /app/ — the product page (WB-6, round 6, lane L-app). Additive: every token, control
   and surface comes from soft.css, pages.css and pages-art.css; this file lays the route
   out on the page column and draws only what no other route has (the hero scene, the
   capture wells, the callouts, the season list, the role panels, the Trinity bridge, the
   steps and the close). Type stays on the round-4 scale (13/15/17/20 at 1.4 or 1.6; the
   display triples), radii on the round-4 scale (16/28/40/pill). Subtrees that draw app UI
   (the devices, the Trinity excerpt) carry data-lint-exempt. */

/* One rhythm (soft.css spacing scale, lane SP 2026-10-20): sections are spaced by margin, so
   a chapter's frame holds only its content; the index under the hero is a block of the hero. */
.app-section {
  margin-top: var(--space-section);
}
.app-page .chapter-lede {
  color: var(--ink-secondary);
}

/* ─── Hero ─────────────────────────────────────────────────────────────────────── */
.app-hero {
  --h1-cap: calc(var(--d-h1) * 0.18);
  align-items: start;
  padding-top: var(--space-top);
}
.app-hero__copy {
  grid-column: 1 / 7;
  min-width: 0;
}
.app-hero__copy .pages-title {
  margin: 0 0 var(--space-head);
}
.app-hero__lede {
  max-width: 34ch;
  margin: 0 0 var(--space-lede);
}
.app-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.app-hero__actions .button {
  height: var(--btn-lg);
  padding-inline: 28px;
}
.app-hero__availability {
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.4em;
  max-width: 44ch;
  margin: var(--space-block) 0 0;
  color: var(--ink-secondary);
  text-wrap: balance;
}
.app-hero__availability > span:last-child {
  flex-basis: 100%;
}
/* The scene: the season-bleachers still in a recessed window, level with the h1's cap,
   with two board captures rising from its lower edge. The window's own lip (soft.css
   ::after, z-index 1) paints under the devices (z-index 2), so the phones read as sitting in
   front of the picture rather than pressed under glass. */
.app-hero__scene {
  grid-column: 7 / 13;
  aspect-ratio: 736 / 600;
  width: 100%;
  margin-top: var(--h1-cap);
}
.app-hero__scene img.field-window__media {
  object-position: 50% 62%;
}
.app-hero__shade {
  background:
    linear-gradient(0deg, rgb(9 12 11 / 48%), rgb(9 12 11 / 0) 56%),
    linear-gradient(180deg, rgb(9 12 11 / 26%), rgb(9 12 11 / 0) 32%);
}
.app-hero__devices {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
/* One device frame for the whole route: a pearl bezel whose corners follow the screen's
   (the capture is 390x844 with 14% corners), a dark drop so it floats over the picture. In
   the hero each device is placed from the window's top (never its bottom), so its top edge
   always clears the corner tag whatever the window's height, and the window cuts its foot. */
.app-device {
  --bezel: 8px;
  --corner: calc(var(--device-w) * 0.14);
  position: absolute;
  box-sizing: border-box;
  width: var(--device-w);
  border: var(--bezel) solid var(--surface);
  border-radius: calc(var(--corner) + var(--bezel));
  background: var(--surface);
  box-shadow:
    0 30px 60px -20px rgb(6 8 7 / 60%),
    0 2px 6px rgb(6 8 7 / 16%),
    inset 0 1px 0 var(--soft-light);
  overflow: hidden;
}
.app-device > img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--corner);
}
.app-device--front {
  --device-w: 300px;
  top: 112px;
  right: 40px;
}
.app-device--back {
  --device-w: 248px;
  top: 152px;
  left: 64px;
}

/* ─── Section index ─────────────────────────────────────────────────────────────── */
.app-index {
  display: flex;
  margin-top: var(--space-block);
}
.app-index__seg {
  max-width: 100%;
  /* Fix round 3: snap positions sit clear of the 40px start fade (plus the focus ring's
     4px), so a swiped or focused link never rests under it (app-page.js). */
  scroll-padding-inline: 44px;
}
.app-index__seg > a {
  flex: none;
  white-space: nowrap;
  scroll-snap-align: start;
}

/* ─── Chapters ──────────────────────────────────────────────────────────────────── */
.chapter {
  align-items: start;
}
.chapter__copy {
  grid-column: 1 / 7;
  min-width: 0;
}
.chapter__stage {
  grid-column: 7 / 13;
  min-width: 0;
}
.chapter--flip .chapter__copy {
  grid-column: 7 / 13;
}
.chapter--flip .chapter__stage {
  grid-column: 1 / 7;
  grid-row: 1;
}
.chapter__copy h2 {
  margin: 0;
}
.chapter__copy .chapter-lede {
  max-width: 44ch;
  margin: var(--space-head) 0 0;
  font-size: var(--fs-20);
  line-height: var(--lh-prose);
}
.chapter__facts {
  display: grid;
  gap: 12px;
  max-width: 56ch;
  margin: var(--space-lede) 0 0;
  padding: 0;
  list-style: none;
}
.chapter__facts > li {
  position: relative;
  padding-left: 22px;
  color: var(--ink);
  font-size: var(--fs-17);
  line-height: var(--lh-prose);
  text-wrap: pretty;
}
.chapter__facts > li::before {
  content: '';
  position: absolute;
  top: 0.62em;
  left: 2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ink-secondary);
}

.chapter__note {
  max-width: 60ch;
  margin: var(--space-block) 0 0;
  color: var(--ink-secondary);
  text-wrap: pretty;
}

/* The capture: one device in a recessed well (its corner tag was retired 2026-10-19). The device
   sits 56px under the well's top edge (64px to the screen, with the bezel) and the well
   fades out over its last --fade, so a capture taller than the well ends softly rather than
   on a cut.
   Fix round 1: the well is sized from the capture itself. --from and --to are board rows
   of the 390x844 screen (the first shown, and the last that must stay crisp: every
   callout's element plus its ring sits above it), so at any device width the well is
   64px + the shown rows at the device's scale + the fade, and no callout ever lands in
   the fade. A capture that starts lower (--from > 0) shows rows --from to 844 only:
   .capture__screen is cut to those rows and the img covers it from its foot, so the
   image's box is exactly what is drawn, and app-page.js maps the ring from --from. */
.capture {
  position: relative;
  margin: 0;
}
.capture__well {
  --device-w: clamp(280px, 24vw, 340px);
  --from: 0;
  --to: 578;
  --fade: 88px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  height: calc(
    var(--pad-well) + 8px + var(--lift, 0px) + (var(--device-w) - 16px) *
      (var(--to) - var(--from)) / 390 + var(--fade)
  );
  padding-top: calc(var(--pad-well) + var(--lift, 0px));
  border: 1px solid light-dark(rgb(255 255 255 / 55%), var(--rim-dark));
  border-radius: var(--r-window);
  background: var(--surface);
  box-shadow: var(--e-inset-lg);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - var(--fade)), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - var(--fade)), transparent);
}
/* The last crisp row per capture (board px): the schedule card's foot, the roster's head
   coach row, the payments list's fifth request; messages keeps its round-6 depth. */
[data-capture='schedule'] .capture__well {
  --to: 656;
}
[data-capture='roster'] .capture__well {
  --to: 716;
}
[data-capture='payments'] .capture__well {
  --to: 590;
}
.capture__device {
  position: relative;
  flex: none;
  box-shadow: var(--e-raised-lg);
}
.capture__screen {
  position: relative;
  aspect-ratio: 390 / calc(844 - var(--from));
}
.capture__screen > img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--corner);
  object-fit: cover;
  object-position: 50% 100%;
}

/* The ring: an app-blue outline around the element a callout names, placed in percentages of the
   screen (app-page.js sets --x/--y/--w/--h from the point's 390x844 box) and grown by --air
   on every side, so the stroke (3px, 2px on phones) clears the element by --air less the
   stroke: 4px of air at desktop widths, 3px on phones. */
.capture__ring {
  --air: 7px;
  position: absolute;
  z-index: 2;
  top: calc(var(--y, 0) * 100% - var(--air));
  left: calc(var(--x, 0) * 100% - var(--air));
  box-sizing: border-box;
  width: calc(var(--w, 0) * 100% + 2 * var(--air));
  height: calc(var(--h, 0) * 100% + 2 * var(--air));
  border: 3px solid var(--app-accent);
  border-radius: var(--r-16);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--app-accent) 14%, transparent),
    0 8px 20px -6px rgb(6 8 7 / 35%);
  pointer-events: none;
  transition:
    top 240ms var(--ease-out),
    left 240ms var(--ease-out),
    width 240ms var(--ease-out),
    height 240ms var(--ease-out);
}
/* The payments rows stack a date, a 3px bar and a ledger line 8px apart: a 6px ring keeps
   each ring's stroke clear of the neighbouring line (3px of air; 2.5px inside a phone's
   2px stroke). */
[data-capture='payments'] .capture__ring {
  --air: 6px;
}
@media (max-width: 760px) {
  :root [data-capture='payments'] .capture__ring {
    --air: 4.5px;
  }
}
.capture__ring[hidden] {
  display: none;
}

/* Callouts: the chapter's one interaction. Without JavaScript the points are a list; with
   it each point is a button (aria-pressed) that moves the ring. The pressed option rises
   like a selected seg option; the rest sit flat on the page. */
.callouts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: var(--space-lede) 0 0;
  padding: 0;
  list-style: none;
}
.callouts > li {
  display: grid;
  min-width: 0;
}
.callouts:not([data-callouts-live]) > li {
  gap: 2px;
  padding: 12px 16px;
}
.callouts__button {
  display: grid;
  gap: 2px;
  width: 100%;
  min-height: 44px;
  padding: 12px 16px;
  border: 1px solid transparent;
  border-radius: var(--r-16);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition:
    box-shadow var(--dur-ui) var(--ease-out),
    background-color var(--dur-ui) var(--ease-out);
}
.callouts__button[aria-pressed='true'] {
  border-color: color-mix(in srgb, var(--app-accent) 22%, var(--surface-lift));
  background: color-mix(in srgb, var(--app-accent-wash) 50%, var(--surface-lift));
  box-shadow: var(--e-raised-sm);
}
@media (hover: hover) {
  .callouts__button:not([aria-pressed='true']):hover {
    background: var(--surface-lift);
  }
}
.callouts__title {
  color: var(--ink);
  font-size: var(--fs-15);
  font-weight: 600;
  line-height: var(--lh-ui);
}

/* ─── Roles ─────────────────────────────────────────────────────────────────────── */
.roles__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gap);
}
.role-card {
  padding: var(--pad-card);
  border: 1px solid light-dark(rgb(255 255 255 / 70%), var(--rim-dark));
  border-radius: var(--r-28);
  background: var(--surface);
  box-shadow: var(--e-raised-lg);
}
.role-card h3 {
  margin: 0;
  color: var(--ink);
}
.role-card__line {
  margin: 6px 0 0;
  color: var(--ink-secondary);
  font-size: var(--fs-13);
  font-weight: 600;
  line-height: var(--lh-ui);
}
.role-card__list {
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}
.role-card__list > li {
  padding: 12px 0;
  border-top: 1px solid var(--border);
  color: var(--ink);
  font-size: var(--fs-15);
  line-height: var(--lh-prose);
  text-wrap: pretty;
}

/* ─── Trinity in context ────────────────────────────────────────────────────────── */
/* One band on the page grid (fix round 2). Below 1024px the side wrapper dissolves, so the
   copy, the excerpt and the link stack in that order; from 1024px the copy and its link
   hold columns 1-5, sticky beside the excerpt on columns 7-12, so neither half is empty. */
.bridge {
  row-gap: var(--space-lede);
  align-items: start;
}
.bridge > * {
  grid-column: 1 / -1;
  min-width: 0;
}
.bridge__side {
  display: contents;
}
.bridge__copy,
.bridge__more {
  grid-column: 1 / -1;
  min-width: 0;
}
.bridge__copy {
  order: 1;
}
.bridge__stage {
  order: 2;
}
.bridge__more {
  order: 3;
}
.bridge__copy h2 {
  margin: 0;
}
.bridge__copy .chapter-lede {
  max-width: 44ch;
  margin: var(--space-head) 0 0;
  font-size: var(--fs-20);
  line-height: var(--lh-prose);
}
.bridge__more {
  display: grid;
  justify-items: start;
  gap: 12px;
}
.bridge__more p {
  max-width: 44ch;
  margin: 0;
  color: var(--ink-secondary);
  font-size: var(--fs-17);
  line-height: var(--lh-prose);
  text-wrap: pretty;
}
.bridge__stage {
  width: 100%;
  max-width: 680px;
  padding: clamp(24px, 3.2vw, 40px);
  border-radius: var(--r-40);
  background: var(--surface);
  box-shadow: var(--e-inset-lg);
}

@media (min-width: 1024px) {
  .bridge {
    grid-template-rows: auto;
  }
  .bridge__side {
    display: grid;
    grid-column: 1 / 6;
    gap: var(--space-lede);
    position: sticky;
    top: 120px;
  }
  .bridge__stage {
    grid-column: 7 / -1;
    max-width: none;
  }
}

/* ─── Getting started ───────────────────────────────────────────────────────────── */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-inline: 0;
  margin-bottom: 0;
  padding: 0;
  list-style: none;
}
.steps__item {
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
.steps__num {
  display: block;
  color: var(--ink-secondary);
  font: 700 var(--d-price) / var(--d-price-lh) var(--font-display);
  font-variant-numeric: lining-nums tabular-nums;
}
.steps__item h3 {
  margin: 14px 0 0;
  color: var(--ink);
}
.steps__item p {
  margin: 10px 0 0;
  color: var(--ink-secondary);
  font-size: var(--fs-15);
  line-height: var(--lh-prose);
  text-wrap: pretty;
}
.start__now {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 28px;
  padding: 24px var(--pad-card);
  border: 1px solid light-dark(rgb(255 255 255 / 70%), var(--rim-dark));
  border-radius: var(--r-28);
  background: var(--surface);
  box-shadow: var(--e-raised-lg);
}
.start__now-line {
  flex: 1 1 320px;
  margin: 0;
  color: var(--ink-secondary);
  font-size: var(--fs-17);
  line-height: var(--lh-prose);
  text-wrap: pretty;
}
.start__now-line strong {
  color: var(--ink);
  font-weight: 600;
}
.start__now .mailto-note {
  flex-basis: 100%;
  margin: 0;
}

/* ─── Questions ─────────────────────────────────────────────────────────────────── */
.app-faq {
  align-items: start;
}
.app-faq__aside {
  grid-column: 1 / 6;
  min-width: 0;
}
.app-faq__aside h2 {
  margin: 0;
}
.app-faq__lede {
  max-width: 30ch;
  margin: var(--space-head) 0 0;
  color: var(--ink-secondary);
  font-size: var(--fs-17);
  line-height: var(--lh-prose);
}
.app-faq .faq-list {
  grid-column: 7 / -1;
  min-width: 0;
}

/* ─── Close ─────────────────────────────────────────────────────────────────────── */
/* The closing panel is .site-close, one component with /trinity/'s; its rules live in
   pages-art.css (fix round 3), which both routes load. */

/* ─── Widths ────────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  .app-faq__aside {
    position: sticky;
    top: 120px;
  }
}
@media (max-width: 1023px) {
  .app-hero__copy,
  .app-hero__scene {
    grid-column: 1 / -1;
  }
  .app-hero__scene {
    aspect-ratio: 16 / 10;
    margin-top: var(--space-block);
  }
  .app-hero__lede {
    max-width: 40ch;
  }
  .chapter__copy,
  .chapter__stage,
  .chapter--flip .chapter__copy,
  .chapter--flip .chapter__stage {
    grid-column: 1 / -1;
  }
  .chapter--flip .chapter__stage {
    grid-row: auto;
  }
  .chapter__stage {
    margin-top: var(--space-block);
  }
  .roles__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .app-faq__aside,
  .app-faq .faq-list {
    grid-column: 1 / -1;
  }
  .app-faq .faq-list {
    margin-top: var(--space-lede);
  }
}
@media (min-width: 1024px) and (max-width: 1279px) {
  /* Six columns are 456-583px here: the window squares up and the devices scale down so
     the corner tag keeps clear of both. */
  .app-hero__scene {
    aspect-ratio: 1 / 1;
  }
  .app-device--front {
    --device-w: 240px;
    top: 96px;
    right: 24px;
  }
  .app-device--back {
    --device-w: 200px;
    top: 136px;
    left: 32px;
  }
}
@media (max-width: 760px) {
  .app-hero__actions {
    width: 100%;
  }
  .app-hero__actions .button {
    flex: 1 1 140px;
  }
  .app-hero__scene {
    aspect-ratio: 4 / 5;
  }
  .app-device--front {
    --device-w: 236px;
    top: 80px;
    right: 16px;
  }
  .app-device--back {
    --device-w: 200px;
    top: 120px;
    left: 8px;
  }
  .capture__well {
    --device-w: 260px;
  }
  .capture__ring {
    --air: 5px;
    border-width: 2px;
  }
  .callouts {
    grid-template-columns: minmax(0, 1fr);
  }
  .roles__grid,
  .steps {
    grid-template-columns: minmax(0, 1fr);
  }

  .bridge__copy .chapter-lede {
    font-size: var(--fs-17);
  }

  .start__now .button {
    width: 100%;
  }
}
@media (max-width: 360px) {
  .app-device--front {
    --device-w: 200px;
    top: 72px;
    right: 8px;
  }
  .app-device--back {
    --device-w: 170px;
    top: 104px;
  }
  .capture__well {
    --device-w: 236px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .capture__ring,
  .callouts__button {
    transition: none;
  }
}
@media (forced-colors: active) {
  .capture__ring {
    border-color: Highlight;
  }
  .callouts__button[aria-pressed='true'] {
    outline: 2px solid Highlight;
  }
}

/* Astra visual finish: app-blue joins each explanatory control to its capture ring.
   The raised shape and aria-pressed state remain the selection cues besides color. */
.app-index__seg > a[aria-current]:not([aria-current='false']),
.callouts__button[aria-pressed='true'] .callouts__title {
  color: var(--app-accent-ink);
}
.callouts__button:focus-visible,
.app-index__seg > a:focus-visible {
  outline: 2px solid var(--app-accent-ink);
  outline-offset: 3px;
}

/* Astra execution — sports-product composition in the approved pearl world.
   Lines are field geometry, dates are the timeline: neither invents product data. */
.app-page ::selection {
  background: var(--app-accent);
  color: #fff;
}
.app-hero {
  align-items: center;
}
.app-hero__copy .pages-title {
  max-width: 9ch;
}
.app-hero__emphasis {
  color: var(--app-accent-ink);
}
.app-hero__scene {
  aspect-ratio: 1 / 1.08;
  isolation: isolate;
  background: linear-gradient(145deg, var(--surface-lift), var(--surface));
  box-shadow: inset 0 1px 0 light-dark(rgb(255 255 255 / 70%), rgb(255 255 255 / 6%));
}
.app-hero__scene img.field-window__media {
  top: 38%;
  height: 62%;
  object-position: 50% 65%;
  -webkit-mask-image: linear-gradient(transparent, #000 30%);
  mask-image: linear-gradient(transparent, #000 30%);
}
@media (min-width: 1024px) {
  .app-hero__scene {
    margin-top: 0;
  }
}
.app-hero__shade {
  background: linear-gradient(0deg, rgb(9 12 11 / 18%), transparent 45%);
}
.app-hero__court {
  display: none;
}
.app-hero__scene::after {
  border-radius: inherit;
  box-shadow: inset 1px 1px 3px light-dark(rgb(255 255 255 / 85%), rgb(255 255 255 / 6%));
}
.app-hero .app-device {
  box-shadow:
    12px 28px 40px -18px rgb(9 12 11 / 48%),
    1px 1px 0 var(--soft-light);
}
.app-device--front {
  --device-w: clamp(248px, 23vw, 310px);
  top: 88px;
  right: 24px;
  z-index: 2;
}
.app-device--back {
  --device-w: clamp(210px, 18vw, 248px);
  top: 150px;
  left: 64px;
  transform: rotate(-6deg);
  transform-origin: 50% 90%;
}
/* Keep keyboard rings inside the rail's scrolling clip. */
.app-index__seg {
  padding: 8px;
  border: 1px solid light-dark(rgb(255 255 255 / 65%), var(--rim-dark));
}
.app-index__seg > a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition:
    color 180ms var(--ease-out),
    background-color 180ms var(--ease-out),
    box-shadow 180ms var(--ease-out);
}
.app-index__seg > a::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.45;
}
.app-index__seg > a[aria-current='location'] {
  color: var(--app-accent-ink);
  background: var(--surface-lift);
  box-shadow: var(--e-raised-sm);
}
.app-index__seg > a[href='#trinity'][aria-current='location'] {
  color: var(--trinity-accent-ink);
}
.app-index__seg > a:focus-visible {
  outline-offset: -2px;
}

.chapter {
  --chapter-color: var(--app-accent);
  align-items: center;
}
.chapter__copy h2 {
  max-width: 15ch;
}
.chapter__facts {
  gap: 0;
}
.chapter__facts > li {
  padding: 12px 0 12px 22px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
  font-size: var(--fs-15);
}
.chapter__facts > li::before {
  top: calc(12px + 0.62em);
  width: 5px;
  height: 5px;
  background: var(--chapter-color);
}
#payments {
  --chapter-color: light-dark(#2e7d4f, #56b977);
}
#tasks {
  --chapter-color: var(--sport-orange, #ff7c2a);
}

.capture__well {
  position: relative;
  background: linear-gradient(145deg, var(--surface-lift), var(--surface));
  box-shadow: inset 0 1px 0 light-dark(rgb(255 255 255 / 70%), rgb(255 255 255 / 6%));
}
.capture__device {
  box-shadow:
    12px 22px 36px -16px light-dark(rgb(41 46 44 / 32%), rgb(6 8 12 / 70%)),
    -5px -5px 12px var(--soft-light);
}
.callouts {
  gap: 4px;
  padding: 6px;
  border: 1px solid light-dark(rgb(255 255 255 / 65%), var(--rim-dark));
  border-radius: var(--r-28);
  background: var(--surface);
  box-shadow: var(--e-inset-sm);
}
.callouts__button {
  padding: 14px 12px;
  align-content: start;
  transition:
    box-shadow 240ms var(--ease-out),
    background-color 240ms var(--ease-out),
    transform 240ms var(--ease-out);
}
.callouts__button[aria-pressed='true'] {
  background: var(--surface-lift);
}
.callouts__button:active {
  transform: translateY(1px);
}

/* A single continuous role panel preserves the permission comparison's reading order. */
.roles__grid {
  gap: 0;
  padding: 8px;
  border: 1px solid light-dark(rgb(255 255 255 / 70%), var(--rim-dark));
  border-radius: var(--r-40);
  box-shadow: var(--e-raised-lg);
}
.role-card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
.role-card + .role-card {
  border-left: 1px solid var(--border);
}
.role-card__line {
  color: var(--app-accent-ink);
}
.bridge__stage {
  border: 1px solid light-dark(rgb(255 255 255 / 70%), var(--rim-dark));
  background: var(--trinity-accent-wash);
}

.steps {
  gap: 0;
}
.steps__item {
  position: relative;
  padding: 24px 28px 0 0;
}
.steps__num {
  width: fit-content;
  color: var(--app-accent-ink);
}
.steps__item h3 {
  max-width: 15ch;
}
.steps__item:last-child {
  padding-right: 0;
}
@media (min-width: 761px) and (max-width: 1023px) {
  .app-hero__copy .pages-title {
    max-width: 12ch;
  }
  .app-hero__scene {
    aspect-ratio: 1.3;
  }
  .app-device--front {
    --device-w: 310px;
    right: 12%;
  }
  .app-device--back {
    --device-w: 260px;
    left: 12%;
  }

  .roles__grid {
    grid-template-columns: 1fr;
  }
  .role-card + .role-card {
    border-left: 0;
    border-top: 1px solid var(--border);
  }
}
@media (max-width: 760px) {
  .app-hero__copy .pages-title {
    max-width: 11ch;
  }
  .app-hero__scene {
    aspect-ratio: 4 / 5;
  }
  .app-device--front {
    --device-w: 236px;
    top: 88px;
    right: 14px;
  }
  .app-device--back {
    --device-w: 200px;
    top: 126px;
    left: 42px;
  }
  .chapter__copy h2 {
    max-width: 16ch;
  }
  .callouts {
    grid-template-columns: 1fr;
    gap: 2px;
  }
  .callouts__button {
    grid-template-columns: minmax(100px, 0.85fr) minmax(0, 1.15fr);
    gap: 12px;
    align-items: start;
    padding: 14px;
  }

  .roles__grid {
    border-radius: var(--r-28);
  }
  .role-card + .role-card {
    border-left: 0;
    border-top: 1px solid var(--border);
  }
  .steps__item {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    column-gap: 20px;
    padding: 24px 0 0;
  }
  .steps__num {
    grid-row: 1 / 3;
  }
  .steps__item h3 {
    margin-top: 0;
    max-width: none;
  }
  .steps__item p {
    grid-column: 2;
  }
}
@media (max-width: 360px) {
  .app-device--front {
    --device-w: 210px;
    right: 10px;
  }
  .app-device--back {
    --device-w: 180px;
    left: 38px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-index__seg > a,
  .callouts__button {
    transition: none;
  }
}
@media (forced-colors: active) {
  .app-hero__emphasis,
  .steps__num,
  .role-card__line {
    color: CanvasText;
  }
  .app-index__seg > a[aria-current='location'] {
    outline: 1px solid Highlight;
  }
}

/* A selected explanation uses the same app-blue as its location on the real screen. */
.callouts__button[aria-pressed='true'] {
  background: color-mix(in srgb, var(--app-accent) 5%, var(--surface-lift));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--app-accent) 22%, transparent),
    var(--e-raised-sm);
}
.app-hero__lede {
  text-wrap: pretty;
}

/* Opus finish, 2026-09-24: the product is the evidence, so it reads at a useful size. The
   chapter screens drew 324px wide in a 620px stage (24vw, capped at 340px); they now take
   up to 400px of it. The well's height follows --device-w, and the callout rings are placed
   in screen percentages, so nothing else needs to move. Phones get a larger screen too. */
.app-page .capture__well {
  --device-w: clamp(300px, 27.5vw, 404px);
}
@media (max-width: 1023px) and (min-width: 761px) {
  .app-page .capture__well {
    --device-w: clamp(280px, 38vw, 340px);
  }
}
@media (max-width: 760px) {
  .app-page .capture__well {
    --device-w: min(300px, calc(100vw - 80px));
  }
}

/* Lane P: viewport-fit chapters. Full captures retain their native 390:844 ratio. The frame
   holds only the chapter's content (lane SP): the old 2 x --app-gap of padding is gone, so
   the fit terms below no longer subtract it. */
.app-page .chapter {
  align-items: start;
}
.app-page .chapter__copy h2 {
  max-width: none;
}
.app-page .chapter__copy .chapter-lede {
  max-width: none;
  font-size: var(--fs-17);
  line-height: var(--lh-ui);
}
.app-page .chapter__facts {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 20px;
  max-width: none;
}
.app-page .chapter__facts > li {
  padding-block: 10px;
  line-height: var(--lh-ui);
}

.app-page .capture__well {
  height: auto;
  padding: var(--pad-well) 12px 12px;
  overflow: visible;
}
.app-page .capture__device {
  --bezel: 4px;
}
/* Lane E, fix-brief item 4: the chapter captures crop to a window again. Rows --from to --to
   stay crisp; the device clips at --to + --fade and the well fades its last --fade, so a
   capture reads as a phone at a legible scale, never a whole-screen thumbnail.
   .capture__screen still spans rows --from to 844 and only the device clips it, so
   app-page.js keeps shown = 844 - from. --fade is a fixed px value: --device-w reads it. */
.app-page .capture__device {
  height: calc(
    2 * var(--bezel) + (var(--device-w) - 2 * var(--bezel)) * (var(--to) - var(--from)) / 390 +
      var(--fade)
  );
}
.app-page .capture__screen {
  aspect-ratio: 390 / calc(844 - var(--from));
}
.app-page .capture__screen > img {
  height: 100%;
  object-fit: cover;
  object-position: 50% 100%;
}
.app-page .capture__well {
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - var(--fade)), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - var(--fade)), transparent);
}
@media (min-width: 761px) {
  .app-page .capture__well {
    --from: 0;
    --to: 578;
    --fade: 40px;
    --device-w: min(
      clamp(300px, 27.5vw, 404px),
      calc((100svh - 78px - 120px - var(--fade)) * 390 / (var(--to) - var(--from)) + 8px)
    );
  }
  .app-page [data-capture='schedule'] .capture__well {
    --to: 656;
  }
  .app-page [data-capture='roster'] .capture__well {
    --to: 716;
  }
  .app-page [data-capture='payments'] .capture__well {
    --to: 590;
  }
  .app-page [data-capture='tasks'] .capture__well {
    --from: 330;
    --to: 745;
  }
}
@media (max-width: 760px) {
  .app-page .capture__well {
    --fade: 24px;
    --device-w: min(232px, calc(100vw - 120px));
  }
  .app-page [data-capture='schedule'] .capture__well {
    --from: 400;
    --to: 656;
  }
  .app-page [data-capture='messages'] .capture__well {
    --from: 0;
    --to: 340;
  }
  .app-page [data-capture='roster'] .capture__well {
    --from: 286;
    --to: 698;
  }
  .app-page [data-capture='payments'] .capture__well {
    --from: 0;
    --to: 280;
  }
  .app-page [data-capture='tasks'] .capture__well {
    --from: 470;
    --to: 745;
  }
}

.app-page .fit-rail-hint {
  display: none;
}

.app-page .role-card__list {
  line-height: var(--lh-ui);
}
.app-page .start__now {
  padding-block: 16px;
}
.app-page .bridge__side {
  position: static;
}
.app-page .bridge__stage {
  padding: 20px;
}

@media (min-width: 761px) and (max-height: 820px) {
  .app-page .chapter__copy .t-h2,
  .app-page .bridge__copy .t-h2 {
    font-size: var(--d-price);
    line-height: var(--d-price-lh);
  }
  .app-page .chapter__facts > li {
    padding-block: 8px;
  }
}
@media (max-width: 760px) {
  .app-page .app-hero__lede {
    font-size: var(--fs-17);
    line-height: var(--lh-ui);
  }
  .app-page .app-hero__scene {
    height: clamp(140px, calc(100svh - 445px), 300px);
    aspect-ratio: auto;
  }
  .app-page .app-hero .app-device--front {
    --device-w: 150px;
    top: 52px;
    right: 35px;
  }
  .app-page .app-hero .app-device--back {
    --device-w: 130px;
    top: 66px;
    left: 45px;
  }
  .app-page .chapter {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  .app-page .chapter__copy,
  .app-page .chapter__stage {
    display: contents;
  }
  .app-page .chapter__copy h2 {
    order: 0;
    font-size: var(--d-card);
    line-height: var(--d-card-lh);
    max-width: 23ch;
  }
  .app-page .chapter__copy .chapter-lede {
    order: 1;
    font-size: var(--fs-15);
  }
  .app-page .capture {
    order: 2;
    width: 100%;
    margin-top: var(--space-lede);
  }
  .app-page .capture__well {
    padding: 38px 12px 8px;
  }

  .app-page .chapter__copy > .fit-rail-hint {
    order: 4;
  }
  .app-page .chapter__facts {
    order: 5;
    width: 100%;
    margin-top: var(--space-block);
  }

  .app-page .chapter__note {
    order: 8;
  }
  /* The swipe hint labels the rail under it (a caption gap); the step before it spaces it. */
  .app-page .fit-rail-hint {
    display: block;
    margin-inline: 0;
    margin-bottom: 0;
    color: var(--ink-secondary);
    font-size: var(--fs-13);
    line-height: var(--lh-ui);
  }
  .app-page :is(.chapter__facts, .roles__grid, .steps) {
    display: grid;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 88%;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scroll-padding-inline: 4px;
    padding: 4px;
  }
  .app-page :is(.chapter__facts, .roles__grid, .steps) > * {
    scroll-snap-align: start;
  }
  .app-page :is(.chapter__facts, .roles__grid, .steps):focus-visible {
    outline: 2px solid var(--app-accent-ink);
    outline-offset: 2px;
  }

  .app-page .chapter-head {
    gap: 0;
  }
  .app-page .chapter-head .chapter-lede {
    font-size: var(--fs-15);
    line-height: var(--lh-ui);
  }
  .app-page .role-card {
    border: 0;
  }
  .app-page .role-card__list {
    margin-top: 12px;
  }
  .app-page .steps__item {
    display: block;
    padding: 12px;
  }
  .app-page .steps__num {
    font-size: var(--d-card);
    margin-bottom: 10px;
  }
  .app-page .start__now {
    gap: 12px;
  }
  .app-page .start__now-line {
    font-size: var(--fs-15);
    line-height: var(--lh-ui);
  }
  .app-page .bridge__copy .t-h2 {
    font-size: var(--d-card);
    line-height: var(--d-card-lh);
  }
  .app-page .bridge__stage {
    padding: 12px;
    border-radius: var(--r-28);
  }

  .app-page .fit-rail-hint + * {
    margin-top: var(--space-caption);
  }

  .app-page .bridge__more {
    gap: 4px;
  }
  .app-page .bridge__more p {
    font-size: var(--fs-15);
    line-height: var(--lh-ui);
  }
}

@media (min-width: 761px) and (max-height: 820px) {
  .app-page .bridge__stage {
    padding: 12px;
  }
}
@media (max-width: 760px) {
  .app-page .steps__num {
    line-height: var(--d-card-lh);
  }
  .app-page .app-hero__scene {
    height: clamp(120px, calc(100svh - 502px), 300px);
  }
}

@media (max-width: 760px) {
  .app-page .capture__well {
    padding-top: calc(38px + var(--lift, 0px));
  }
}
@media (max-width: 760px) {
  /* The label takes its own row so enlarged text can never sit on the preview. */
  .app-page .capture__well {
    flex-direction: column;
    align-items: center;
    padding: 4px 12px;
  }
}
/* Lane E, fix-brief item 10 (needed once item 4 restored the windows: #roster read 1.28 at
   390x664): the plan line joins the first screen, the chapter drops 8px of padding and the
   rail cards are outlined on all four sides. */
@media (max-width: 760px) {
  .app-page .chapter__note {
    order: 1;
  }
  .app-page .chapter__facts > li {
    padding: 12px 12px 12px 24px;
    border: 1px solid var(--border);
    border-radius: var(--r-16);
    background: transparent;
  }
  .app-page .chapter__facts > li::before {
    left: 10px;
  }
}

/* ─── Site refresh, 2026-10-19 (lane D1) ───────────────────────────────────────────
   The chapter captures are real app captures (public/previews/app-real/: an iPhone 17 Pro,
   402x874 pt, delivered as 390-wide webps, so a screen is 390x848 in these units). --screen-h
   is that height, and .capture__screen spans rows --from to --screen-h; app-page.js reads the
   same height from the img's width/height, so the ring stays on its element. --from/--to are
   each capture's rows: the first shown and the last that must stay crisp (every callout's
   ring above it). */
.app-page .capture__screen {
  --screen-h: 848;
  aspect-ratio: 390 / calc(var(--screen-h) - var(--from));
}
@media (min-width: 761px) {
  .app-page [data-capture='schedule'] .capture__well {
    --from: 0;
    --to: 400;
  }
  .app-page [data-capture='messages'] .capture__well {
    --from: 0;
    --to: 356;
  }
  .app-page [data-capture='roster'] .capture__well {
    --from: 0;
    --to: 394;
  }
  .app-page [data-capture='payments'] .capture__well {
    --from: 0;
    --to: 540;
  }
  .app-page [data-capture='tasks'] .capture__well {
    --from: 0;
    --to: 416;
  }
  .app-page [data-capture='notifications'] .capture__well {
    --from: 420;
    --to: 752;
  }
}
@media (max-width: 760px) {
  .app-page [data-capture='schedule'] .capture__well {
    --from: 110;
    --to: 396;
  }
  .app-page [data-capture='messages'] .capture__well {
    --from: 100;
    --to: 352;
  }
  .app-page [data-capture='roster'] .capture__well {
    --from: 200;
    --to: 392;
  }
  .app-page [data-capture='payments'] .capture__well {
    --from: 126;
    --to: 533;
  }
  .app-page [data-capture='tasks'] .capture__well {
    --from: 100;
    --to: 412;
  }
  .app-page [data-capture='notifications'] .capture__well {
    --from: 540;
    --to: 748;
  }
}

/* More of the app: one card per page, each a link with the page's status. */
.more__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-inline: 0;
  margin-bottom: 0;
  padding: 0;
  list-style: none;
}
.more__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 20px 20px;
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--e-raised-sm);
  transition: box-shadow var(--dur-ui) var(--ease-out);
}
.more__name {
  margin: 0;
  font: 600 var(--fs-17) / var(--lh-ui) var(--font-body);
}
.more__name a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
}
.more__name a::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.more__item > p {
  margin: 0;
  color: var(--ink-secondary);
  font-size: var(--fs-15);
  line-height: var(--lh-prose);
}

@media (hover: hover) {
  .more__item:hover {
    box-shadow: var(--e-raised-lg);
  }
}
.more__item:has(a:focus-visible) {
  outline: 3px solid var(--app-accent);
  outline-offset: 4px;
}
@supports selector(:has(a)) {
  .more__name a:focus-visible {
    outline: none;
  }
}

/* Plans compared: a quiet table in a recessed well; status pills where a part is still
   being built; "Not included" in secondary ink. Below 1024px the well scrolls sideways
   inside itself, never the page. */
.compare__scroll {
  padding: clamp(12px, 2vw, 24px);
  overflow-x: auto;
  border-radius: var(--r-28);
  background: var(--surface-lift);
  box-shadow: var(--e-inset-sm);
}
.compare__table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  color: var(--ink);
  font-size: var(--fs-15);
  line-height: var(--lh-ui);
}
.compare__table :is(th, td) {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}
.compare__table tbody tr:last-child > * {
  border-bottom: 0;
}
.compare__table thead th {
  font: 700 var(--d-card) / var(--d-card-lh) var(--font-display);
  letter-spacing: var(--d-card-ls);
}
.compare__table tbody th {
  width: 28%;
  color: var(--ink-secondary);
  font-weight: 600;
}

.compare__note {
  max-width: 72ch;
  margin: var(--space-caption) 0 0;
  color: var(--ink-secondary);
}
@media (max-width: 1023px) {
  .more__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 760px) {
  .more__grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .more__item {
    gap: 2px;
    padding: 8px 16px 14px;
  }
  .more__item > p {
    font-size: var(--fs-13);
    line-height: var(--lh-ui);
  }

  .compare__table {
    min-width: 560px;
    font-size: var(--fs-13);
  }
  /* The feature column stays put while the plans scroll under it. */
  .compare__table :is(tbody th, thead th:first-child) {
    position: sticky;
    left: 0;
    z-index: 1;
    width: 120px;
    background: var(--surface-lift);
  }
  .compare__table :is(th, td) {
    padding: 10px 12px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .more__item {
    transition: none;
  }
}

/* ─── Copy diet, 2026-10-20 (lane C2; the Apple iPhone Duo benchmark) ────────────────────
   Each chapter is a headline, one line and at most three callout labels beside its capture,
   so the copy sits level with the middle of the screen and the screen grows (up to 460px
   wide, still bounded by the viewport-fit term above). The callouts are labels only: one
   line each, in the inset segment on desktop and a stacked list under the screen on phones.
   Notifications has no callouts. */
@media (min-width: 761px) {
  .app-page .chapter {
    align-items: center;
  }
  .app-page .chapter__copy .chapter-lede {
    max-width: 40ch;
  }
  .app-page .capture__well {
    --device-w: min(
      clamp(320px, 32vw, 460px),
      calc((100svh - 78px - 120px - var(--fade)) * 390 / (var(--to) - var(--from)) + 8px)
    );
  }
  .app-page .chapter .callouts {
    max-width: 560px;
  }
}
.app-page .callouts__title {
  text-wrap: balance;
}
@media (max-width: 760px) {
  .app-page .capture__well {
    --device-w: min(300px, calc(100vw - 72px));
  }
  .app-page .chapter .callouts {
    order: 3;
    width: 100%;
    margin-top: var(--space-block);
  }
  .app-page .callouts__button {
    grid-template-columns: minmax(0, 1fr);
    padding: 12px 14px;
  }
}

/* Photos, files and teams: three short cards, a title and one line each, stacked on phones
   (too short to need the swipe rail the role grids use). */
@media (max-width: 760px) {
  .app-page .more-basics .roles__grid {
    grid-auto-flow: row;
    grid-template-columns: minmax(0, 1fr);
    overflow: visible;
    padding: 0;
  }
}
.app-page .more-basics .role-card > p {
  margin: 8px 0 0;
  color: var(--ink-secondary);
  font-size: var(--fs-15);
  line-height: var(--lh-ui);
  text-wrap: pretty;
}

/* Trinity at tablet widths (761-1023px): the headline and line across the top, then the phone
   on columns 1-6 with its steps and link beside it on 7-12, so the band is one screen at
   768x1024 (stacked, it read 1.22 screens). From 1024px the copy column returns. */
@media (min-width: 761px) and (max-width: 1023px) {
  .app-page .bridge {
    align-items: center;
  }
  .app-page .bridge[data-trinity-stage] .bridge__copy {
    grid-column: 1 / -1;
    grid-row: 1;
  }
  .app-page .bridge[data-trinity-stage] .bridge__stage {
    grid-column: 1 / 7;
    grid-row: 2 / 4;
  }
  .app-page .bridge[data-trinity-stage] .bridge__guide {
    grid-column: 7 / 13;
    grid-row: 2;
    align-self: end;
  }
  .app-page .bridge[data-trinity-stage] .bridge__more {
    grid-column: 7 / 13;
    grid-row: 3;
    align-self: start;
  }
}

/* Plans compared: the feature column, then three equal plan columns of ticks and dashes. */
.app-page .compare__table {
  table-layout: fixed;
}
.app-page .compare__table :is(thead th, tbody th):first-child {
  width: 31%;
}
.app-page .compare__table td .cell-mark {
  display: block;
}
/* Each tick's words (.sr-only, absolutely positioned) stay inside the scrolling well. */
.app-page .compare__scroll {
  position: relative;
}
.app-page .compare__price td {
  color: var(--ink);
  font-weight: 600;
}
@media (min-width: 761px) {
  .app-page .compare__table :is(tbody th, tbody td) {
    padding-block: 9px;
  }
}
@media (max-width: 760px) {
  .app-page .compare__table :is(thead th, tbody th):first-child {
    width: 120px;
  }
}
