/* ============================================================
   Capability pages (/capabilities and /capabilities/<slug>)
   crew phossil-capability-showcase, 2026-07-26

   Ports the landing bento language onto the marketing-template
   token base. Spokes must NOT link landing-ab.css: the bento
   rules live only there (68KB, landing-scoped) while compare
   pages and guides load marketing-template.css + guide-template.css.
   REQUIRES marketing-template.css to be linked first (tokens).

   Tokens only, zero raw hex. Components ship as their spokes ship:
   the before/after pair, the verso pair, and the EXIF-conflict rows
   belong to Group C and land with restorations and dating.
   ============================================================ */

/* --- Page shell ------------------------------------------- */

.cap-main {
  margin-top: 80px; /* clears the fixed marketing header */
}
.cap-section {
  padding: var(--space-2xl) var(--space-md);
}
.cap-inner {
  max-width: var(--container-xl);
  margin: 0 auto;
}
.cap-section--warm {
  background: var(--color-warmth);
}

.cap-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: var(--space-sm);
}
.cap-hero h1 {
  font-family: var(--font-serif);
  font-size: clamp(2rem, 5vw, 3.1rem);
  line-height: 1.15;
  color: var(--color-text-primary);
  margin: 0 0 var(--space-md);
}
.cap-hero h1 em {
  font-style: italic;
  color: var(--gold-deep);
}
.cap-lede {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  line-height: 1.7;
  color: var(--color-text-primary);
  max-width: 34rem; /* rem, not ch: a ch-based measure is computed from the FALLBACK font and rewraps when the webfont swaps, which reflows the section and shows up as CLS (PERF-P2). */
  margin: 0 0 var(--space-lg);
}
.cap-section h2 {
  font-family: var(--font-serif);
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-md);
}
.cap-body {
  font-size: 1.02rem;
  line-height: 1.75;
  color: var(--color-text-secondary-strong);
  max-width: 34rem; /* rem, not ch: a ch-based measure is computed from the FALLBACK font and rewraps when the webfont swaps, which reflows the section and shows up as CLS (PERF-P2). */
  margin: 0 0 var(--space-md);
}
.cap-body a,
.cap-links a {
  color: var(--gold-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- The bento grid --------------------------------------- */

.cap-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--space-md);
  margin-top: var(--space-lg);
  /* Cells size to their own content. Stretching a short cell to match a tall
     one leaves it mostly empty, which reads as a cell with nothing in it. */
  align-items: start;
}
.cap-cell {
  grid-column: span 12;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
.cap-cell--half { grid-column: span 6; }
.cap-cell--wide { grid-column: span 7; }
.cap-cell--narrow { grid-column: span 5; }

/* --- The artifact pair (the atomic unit) ------------------- */

.proof-pair figure {
  margin: 0;
}
.proof-pair img,
.proof-pair video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--color-canvas);
}
/* A portrait artifact at full cell width runs past 1400px tall and eats the
   whole viewport, so both are capped at 560px (CR-5). The portrait stills
   already in tree are 1080x1600 and 1096x1600, and Group C's before/after and
   verso pairs use this same wrapper.

   ONE AXIS MUST BE DEFINITE or the box is not reserved and the section jumps
   when the media resolves (PERF-P2, measured CLS 0.137). The two element types
   need different definite axes:

   - VIDEO gets a definite HEIGHT. A preload="none" video has NO intrinsic size
     until its poster decodes, so height:auto lays out at zero and then snaps to
     560 (the measured shift was a 450px growth). A definite height reserves the
     box from first paint; width follows the aspect ratio off the attributes.
   - IMG gets a definite WIDTH. An img with width/height attributes always has an
     aspect ratio available, so a definite width reserves the height immediately,
     and the max-height cap still recomputes the width for portrait stills. This
     avoids the letterboxing that a definite height would force on landscape. */
.proof-pair video {
  height: 560px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  margin: 0 auto;
}
.proof-pair img {
  width: 100%;
  height: auto;
  max-width: 100%;
  max-height: 560px;
  margin: 0 auto;
}
.proof-out {
  padding: var(--space-md);
}
.proof-out strong {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.15rem;
  color: var(--color-text-primary);
  margin-bottom: var(--space-xs);
}
.proof-say {
  margin: 0;
  font-size: 0.97rem;
  line-height: 1.65;
  color: var(--color-text-secondary-strong);
}

/* --- Evidence list (mirrors the demo widget's dd-clues) ---- */

.evidence-list {
  list-style: none;
  margin: var(--space-sm) 0 0;
  padding: 0;
}
.evidence-list li {
  position: relative;
  padding-left: var(--space-md);
  margin-bottom: var(--space-xs);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--color-text-secondary-strong);
}
.evidence-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}

/* --- The honest-limit panel ------------------------------- */
/* A peer of a success panel, never a smaller footnote. */

.limit-panel {
  background: var(--color-canvas);
  border-left: 4px solid var(--gold-deep);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  margin-top: var(--space-lg);
}
.limit-panel h2,
.limit-panel h3 {
  font-family: var(--font-serif);
  font-size: 1.3rem;
  color: var(--color-text-primary);
  margin: 0 0 var(--space-sm);
}
.limit-panel p {
  font-size: 1.02rem;
  line-height: 1.75;
  color: var(--color-text-secondary-strong);
  max-width: 34rem; /* rem, not ch: a ch-based measure is computed from the FALLBACK font and rewraps when the webfont swaps, which reflows the section and shows up as CLS (PERF-P2). */
  margin: 0 0 var(--space-sm);
}
.limit-panel p:last-child { margin-bottom: 0; }

/* --- Permanence / ownership block ------------------------- */

.permanence-block {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  margin-top: var(--space-lg);
}

/* --- Index card grid -------------------------------------- */

/* --- Hub masthead -----------------------------------------
   The hub used to open with a full-height hero (headline left,
   nothing right) followed by a SECOND full-height section that
   re-asked the same question, so the cards, which are the whole
   point of the page, started on screen two.

   Now one section: headline and answer side by side, cards
   directly beneath, the lot inside a laptop viewport. */

.cap-hero--index {
  padding-top: var(--space-xl);
  padding-bottom: var(--space-xl);
}
.cap-masthead {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: end;
}
.cap-masthead__title h1 {
  margin-bottom: 0;
}
.cap-masthead__say h2 {
  font-size: 1.15rem;
  line-height: 1.4;
  margin-bottom: var(--space-xs);
}
/* The lede is measure-capped globally; inside the masthead the column
   is already the measure, so let it fill and stop stranding space. */
.cap-masthead__say .cap-lede {
  max-width: none;
  font-size: 1.05rem;
  line-height: 1.6;
  margin-bottom: 0;
}

.cap-section--tail {
  padding-top: var(--space-lg);
  padding-bottom: var(--space-xl);
}

.cap-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-md);
  margin-top: var(--space-xl);
}
.cap-card {
  display: block;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  text-decoration: none;
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--transition-normal), transform var(--transition-normal);
}
a.cap-card:hover,
a.cap-card:focus-visible {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.cap-card h3 {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  color: var(--color-text-primary);
  margin: 0 0 var(--space-xs);
}
.cap-card p {
  margin: 0;
  font-size: 0.96rem;
  line-height: 1.6;
  color: var(--color-text-secondary-strong);
}
/* Unshipped capabilities render as plain cards with no anchor:
   no dead links, no fake pages (plan Decision 1). */
.cap-card--soon {
  background: var(--color-canvas);
  box-shadow: none;
}
.cap-card__soon {
  display: inline-block;
  margin-top: var(--space-sm);
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary-strong);
}

.cap-links {
  margin-top: var(--space-lg);
  font-size: 0.98rem;
  line-height: 1.8;
  color: var(--color-text-secondary-strong);
}

/* --- Working replicas (`cap-replica`) ---------------------- *

   A replica is the real mechanism rebuilt in marketing markup and
   driven by a sample family: it FILTERS, it SWEEPS, it responds.
   It is not a screenshot and must never be captioned as one.

   Why rebuilt rather than captured: the app stylesheets are far too
   heavy to load here (atlas.css is 47KB, cortex.css 34KB) and they
   assume an authenticated shell. So the replica borrows the tokens,
   not the stylesheet.

   The honesty contract, enforced in tests/frontend/capability-replicas.test.js:
   every user-visible STRING a replica renders must also appear in the
   source that renders it for real. When the product's wording moves,
   the replica goes red rather than quietly going stale. Sample DATA
   is free to be invented; the MECHANISM's vocabulary is not.
   ---------------------------------------------------------- */

.cap-replica {
  background: var(--color-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  box-shadow: var(--shadow-card);
  color: var(--color-text-light);
}
.cap-replica__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  padding-bottom: var(--space-sm);
  margin-bottom: var(--space-md);
  border-bottom: 1px solid rgba(243, 240, 230, 0.14);
}
.cap-replica__title {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0;
}
/* Says plainly that the data is a sample. The replica is honest about
   being a demonstration; it is never honest about being a photograph
   of the app. */
.cap-replica__note {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin: 0;
}

/* --- Worldlines replica ------------------------------------ */

.wlr {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-sm);
}
.wlr__plot {
  position: relative;
  width: 100%;
}
.wlr__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
/* A person's line before the plane reaches them: drawn faintly so the
   shape of the century is legible, then lit as the slice passes. */
.wlr__track { stroke: rgba(243, 240, 230, 0.13); stroke-width: 2; fill: none; }
.wlr__live  { stroke: var(--color-accent); stroke-width: 2.5; fill: none; stroke-linecap: round; }
.wlr__birth { fill: rgba(243, 240, 230, 0.4); }
.wlr__collide {
  fill: var(--color-surface);
  stroke: var(--color-accent);
  stroke-width: 2;
}
.wlr__plane {
  stroke: var(--color-accent-hover);
  stroke-width: 2;
  stroke-dasharray: 4 4;
}
.wlr__name {
  font-family: var(--font-sans);
  font-size: 12px;
  fill: var(--color-text-light);
}
.wlr__year-tick {
  font-family: var(--font-sans);
  font-size: 11px;
  fill: var(--color-text-muted);
}

.wlr__readout {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}
.wlr__year {
  font-family: var(--font-serif);
  font-size: clamp(2rem, 6vw, 3rem);
  line-height: 1;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.wlr__crossline {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--color-text-light);
}
.wlr__controls {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.wlr__btn {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  min-height: 44px;
  padding: 0 var(--space-md);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-accent);
  background: transparent;
  color: var(--color-accent);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.wlr__btn:hover { background: var(--color-accent); color: var(--color-text-on-accent); }
.wlr__btn:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
.wlr__scrub {
  flex: 1;
  min-width: 140px;
  min-height: 44px;
  accent-color: var(--color-accent);
  cursor: pointer;
}
.wlr__moment {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--color-text-muted);
  min-height: 3.2em;
  margin: 0;
}

/* SVG text scales with the viewBox, so the narrow coordinate space the
   script switches to below 720px (viewBox 460 rather than 900) needs
   correspondingly larger nominal sizes to land at the same on-screen
   pixels. Without this the labels render at about eight pixels. */
@media (max-width: 719px) {
  .wlr__name { font-size: 18px; }
  .wlr__year-tick { font-size: 16px; }
}

/* The sweep is motion. Anyone who has asked for less of it gets the
   final year and every line drawn in full, with no animation to opt
   out of and nothing hidden behind a control they will not press. */
@media (prefers-reduced-motion: reduce) {
  .wlr__plane { display: none; }
}

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

@media (max-width: 960px) {
  .cap-cell--half,
  .cap-cell--wide,
  .cap-cell--narrow {
    grid-column: span 12;
  }
  /* Stack the masthead before the columns get too narrow to hold a
     readable measure. Headline first, answer under it. */
  .cap-masthead {
    grid-template-columns: 1fr;
    gap: var(--space-md);
    align-items: start;
  }
}
@media (max-width: 640px) {
  .cap-section { padding: var(--space-xl) var(--space-sm); }
  .limit-panel,
  .permanence-block { padding: var(--space-md); }
}
