/* Hallmark · macrostructure: Bento Grid · genre: modern-minimal
 * theme: custom (studied from a user-supplied iota.org screenshot, not a catalog
 *   theme — see tokens.css header for the exact sampled values) · vibe: cool
 *   near-white + one vivid blue/indigo signal, corporate-tech register
 * tone: professional/utilitarian · anchor hue: 264 (vivid blue/indigo) · nav: N5 Floating pill · footer: Ft2
 * pre-emit critique: P4 H4 E4 S4 R4 V5
 * contrast: accent-ink on accent should be very safe (blue has low WCAG relative
 *   luminance vs. its OKLCH lightness) — recommend a live devtools contrast check
 *   once rendered, same caveat as before
 * nav: N5 · footer: Ft2 · slop: pass (42-45) · honest: pass (46) · chrome: pass (47)
 * tokens: pass (48) · responsive: pass (49) · icons: pass (30) · mobile: pass (34, 49, 50-57)
 */

/* ============================= Reset ============================= */
*, *::before, *::after { box-sizing: border-box; }
html, body { overflow-x: clip; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink-2);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }

h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--color-ink);
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
  min-width: 0;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  transition: none;
}

.container {
  width: 100%;
  max-width: 76rem;
  margin-inline: auto;
  padding-inline: var(--space-md);
}

section { padding-block: var(--space-3xl); }
@media (max-width: 640px) { section { padding-block: var(--space-2xl); } }

/* ============================= Reveal (one-shot fade+rise) ============================= */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.reveal.is-in { opacity: 1; transform: none; }

/* Directional variants — slide in from the element's own outer edge, reinforcing
   whichever side of a text/device-frame pair it sits on, instead of a uniform rise. */
.reveal--from-left { transform: translateX(-24px); }
.reveal--from-right { transform: translateX(24px); }
.reveal--from-left.is-in, .reveal--from-right.is-in { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal--from-left, .reveal--from-right {
    opacity: 1; transform: none; transition: none;
  }
}

/* ============================= Buttons (8-state) ============================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  white-space: nowrap;
  border-radius: var(--radius-pill);
  padding: 0.75rem 1.5rem;
  font-size: var(--text-sm);
  font-weight: 600;
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--color-accent); color: var(--color-accent-ink); }
.btn--primary:hover, .btn--primary.is-hover { background: var(--color-accent-hover); }
.btn--primary:active, .btn--primary.is-active { background: var(--color-accent-hover); transform: translateY(1px); }
.btn--primary:disabled, .btn--primary.is-disabled { background: var(--color-rule); color: var(--color-ink-3); cursor: not-allowed; }

.btn--secondary { background: transparent; color: var(--color-ink); border-color: var(--color-rule-2); }
.btn--secondary:hover, .btn--secondary.is-hover { border-color: var(--color-accent); color: var(--color-accent); }
.btn--secondary:active, .btn--secondary.is-active { transform: translateY(1px); }
.btn--secondary:disabled, .btn--secondary.is-disabled { color: var(--color-ink-3); border-color: var(--color-rule); cursor: not-allowed; }

.btn--sm { padding: 0.5rem 1.125rem; font-size: var(--text-xs); }

.btn--whatsapp { background: var(--color-whatsapp); color: var(--color-accent-ink); }
.btn--whatsapp:hover, .btn--whatsapp.is-hover { background: var(--color-whatsapp-hover); }
.btn--whatsapp:active, .btn--whatsapp.is-active { transform: translateY(1px); }

.demo-form__send {
  display: flex;
  gap: var(--space-sm);
}
.demo-form__send .btn { flex: 1; }
@media (max-width: 480px) {
  .demo-form__send { flex-direction: column; }
}

.btn--loading { position: relative; color: transparent !important; }
.btn--loading::after {
  content: "";
  position: absolute;
  width: 1rem; height: 1rem;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  color: var(--color-accent-ink);
  animation: spin 700ms linear infinite;
}
@media (prefers-reduced-motion: reduce) { .btn--loading::after { animation-duration: 1400ms; } }
@keyframes spin { to { transform: rotate(360deg); } }

.link {
  font-weight: 600;
  color: var(--color-ink);
  border-bottom: 1px solid var(--color-rule-2);
  padding-bottom: 1px;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
  white-space: nowrap;
}
.link:hover, .link.is-hover { color: var(--color-accent); border-color: var(--color-accent); }

/* ============================= Nav — N10 scroll-morph =============================
 * Wide + flush by default (top of page); docks into the narrower floating pill once
 * `body.is-scrolled` is toggled by main.js. Total nav height never changes between
 * states (Law 1) — only width/chrome morph, so nothing below it jumps. The pill's
 * "lift" comes from `transform: translateY()`, never padding/margin (Law 2). One
 * timing curve across every morphed property (Law 4). See references/floating-nav.md.
 */
.nav-wrap {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  padding-inline: var(--space-md);
  padding-block: var(--space-sm);
  pointer-events: none;
}
.nav {
  pointer-events: auto;
  width: 100%;
  max-width: 88rem;               /* wide default — fills the viewport at the top of the page */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  background: transparent;
  backdrop-filter: blur(0);
  -webkit-backdrop-filter: blur(0);
  border: 1px solid transparent;
  border-radius: 0;
  padding: var(--space-2xs) var(--space-2xs) var(--space-2xs) var(--space-md);
  box-shadow: none;
  transform: translateY(0);
  transition:
    max-width var(--dur-slow) var(--ease-out),
    background var(--dur-slow) var(--ease-out),
    backdrop-filter var(--dur-slow) var(--ease-out),
    border-color var(--dur-slow) var(--ease-out),
    border-radius var(--dur-slow) var(--ease-out),
    box-shadow var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
body.is-scrolled .nav {
  max-width: 60rem;                /* docks to the original pill width once scrolled */
  background: var(--color-glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-color: var(--color-rule);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-nav);
  transform: translateY(4px);
}
@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
}
.nav__logo {
  display: inline-flex;
  align-items: center;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.nav__logo img {
  height: 1.75rem;
  width: auto;
  display: block;
}
.nav__logo:hover { opacity: 0.8; }
.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}
.nav__links a {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-ink-2);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__links a:hover { color: var(--color-accent); }
.nav__toggle { display: none; }

@media (max-width: 680px) {
  .nav__links { display: none; }
  .nav__links.is-open {
    display: flex;
    position: absolute;
    top: calc(100% + var(--space-2xs));
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--color-paper-2);
    border: 1px solid var(--color-rule);
    border-radius: var(--radius-md);
    padding: var(--space-2xs);
    box-shadow: var(--shadow-nav);
  }
  .nav__links.is-open a {
    padding: var(--space-sm);
    border-radius: var(--radius-sm);
  }
  .nav__links.is-open a:hover { background: var(--color-accent-soft); }
  .nav__toggle {
    display: inline-flex;
    width: 2.5rem; height: 2.5rem;
    align-items: center; justify-content: center;
    border-radius: 50%;
  }
  .nav__toggle:hover { background: var(--color-accent-soft); }
  .nav__row { position: relative; display: flex; align-items: center; gap: var(--space-2xs); }
}

/* ============================= Hero ============================= */
/* Hero — type-first editorial, left-aligned.
 * Left-aligned rather than centred: it matches every other section on this page,
 * and is the dominant layout for B2B/technology products. The previous mix of a
 * centred headline with left-aligned buttons read as a mistake rather than a
 * deliberate off-axis break. The hero no longer morphs its own max-width on
 * scroll (that slid left-aligned text sideways); the nav's N10 dock is untouched.
 * Note: no bare `.hero p` selector — explicit classes only, so the eyebrow can't
 * be caught by the lede's rule (element+class beats class alone on specificity).
 */
.hero {
  padding-block: var(--space-2xl) var(--space-3xl);
}
/* Two columns: type-first text left, suite illustration right (the dominant
   B2B/tech hero layout). Width comes from .container now that it's a split. */
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--space-2xl);
  align-items: center;
}
@media (max-width: 860px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xl);
  }
  .hero__figure {
    max-width: 20rem;
    margin-inline: auto;
  }
}
.hero__figure img {
  width: 100%;
  height: auto;
  display: block;
}
.hero__eyebrow {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-ink-3);
  margin-bottom: var(--space-md);
}
.hero h1 {
  font-size: var(--text-display);
  line-height: 1.08;
  max-width: 20ch;
  text-wrap: balance;
}
.hero__lede {
  margin-top: var(--space-md);
  font-size: var(--text-lg);
  color: var(--color-ink-2);
  max-width: 38ch;
}
.hero__actions {
  margin-top: var(--space-lg);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}
/* The eight module names as an editorial index line, closing the hero with real
   content instead of empty space. */
.hero__modules {
  list-style: none;
  margin: var(--space-2xl) 0 0;
  padding: var(--space-md) 0 0;
  border-top: 1px solid var(--color-rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-ink-3);
}
.hero__modules li:not(:last-child)::after {
  content: "·";
  margin-left: var(--space-sm);
  color: var(--color-rule-2);
}

@media (max-width: 480px) {
  .hero__actions { flex-direction: column; align-items: stretch; }
  .hero__actions .btn { width: 100%; }
}

/* ============================= Attendance spotlight (H2 Split Diptych) =============================
 * Text-left / media-right, eyebrow stacked directly above the heading in the same
 * column (never beside it — gate 54). One primary button + a quieter secondary row,
 * mirroring the single-CTA restraint of the studied reference.
 */
.spotlight {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: center;
}
@media (max-width: 860px) {
  .spotlight { grid-template-columns: minmax(0, 1fr); }
}
.spotlight__eyebrow {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-ink-3);
  margin-bottom: var(--space-sm);
}
.spotlight__eyebrow--top {
  margin-bottom: var(--space-md);
}
/* "Problem, solved" pattern: two short labeled paragraphs (the pain, then the
   fix) replace what used to be a single solution-only description — same
   general amount of text as before since this swaps content rather than
   stacking new content on top of the old description. Applies uniformly
   across every section regardless of which container class it otherwise
   uses (spotlight__desc / labour__desc / walkthrough__text p all differed
   before this), so problem/solution pairs read consistently sitewide. */
.problem-solution p {
  font-size: var(--text-lg);
  color: var(--color-ink-2);
  max-width: 30rem;
  margin-bottom: var(--space-sm);
}
.problem-solution p:last-child {
  margin-bottom: var(--space-lg);
}
.problem-solution strong {
  color: var(--color-ink);
  font-weight: 600;
}
/* Before/after pairing (Attendance pilot): explicit viewport-relative sizing
   per direct spec — row is 70% of viewport height, each column exactly half
   the row's width, media matched by HEIGHT (not width or a cropped box) so
   neither gets cropped and both read as literally the same size. object-fit:
   contain (not cover) specifically so nothing is cut off this time. */
.attendance-compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  height: 70vh;
  gap: var(--space-md);
  margin-bottom: var(--space-2xl);
}
.attendance-compare__col {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* flex-end, not center: the "after" image has the geofence ring extending
     below the character's feet, which "center" would otherwise treat as
     just more image height — pushing that character up relative to
     "before" (which has no such empty space below its feet). Bottom-aligning
     both keeps them standing on the same visual ground line instead. */
  justify-content: flex-end;
  gap: var(--space-2xs);
  height: 100%;
  overflow: hidden;
}
.attendance-compare__col img,
.attendance-compare__col video {
  max-height: calc(100% - 2rem);
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}
/* "Before" specifically sized down 10% and nudged left, on request. */
.attendance-compare__col:first-child img {
  max-height: calc((100% - 2rem) * 0.9);
  transform: translateX(-1.5rem) translateY(-1.5rem);
}
/* Label + caption sit in an absolutely-positioned head, out of the flex
   flow entirely — this keeps them from adding to the column's content
   height (which would otherwise push the flex-end-aligned image/video
   upward and off its previously-tuned size/position). */
.attendance-compare__head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  text-align: center;
}
.attendance-compare__label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-ink-3);
}
.attendance-compare__caption {
  font-size: var(--text-sm);
  color: var(--color-ink-2);
  text-align: center;
  margin-top: var(--space-2xs);
  max-width: 90%;
  margin-inline: auto;
  line-height: 1.4;
}
@media (max-width: 640px) {
  .attendance-compare {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    gap: var(--space-lg);
    /* Mobile-only: the "Before" label/caption overlap the element above
       when the block sits flush at the top of its section — pushed down
       to clear it. Desktop is untouched (rule only exists in this query). */
    margin-top: 3rem;
  }
  .attendance-compare__col {
    height: auto;
  }
  /* The label+caption are absolutely positioned so they don't add to the
     column's height on desktop, where the column is a fixed 70vh and the
     image sits far below in the dead space this creates. On mobile the
     column height is auto instead, so that same absolute positioning left
     nothing to push the image down — it started filling from the very top
     of the column, directly behind the label and caption. Static here puts
     the head back in normal flow, so the image is simply pushed down by
     its real height, with no fixed size touched. */
  .attendance-compare__head {
    position: static;
  }
  .attendance-compare__col img,
  .attendance-compare__col video {
    max-height: 50vh;
  }
  /* The desktop :first-child rule's percentage max-height doesn't resolve
     sensibly against this breakpoint's auto-height column, letting "before"
     render uncapped while "after" correctly obeys 50vh — this explicit
     override (same specificity family, so it actually wins here) fixes that,
     landing "before" about 35-40% smaller than the shared 50vh cap. */
  .attendance-compare__col:first-child img {
    margin-top: 3rem;
    max-height: 35.7vh;
  }
}
.stats__grid--2x2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-bottom: var(--space-2xl);
}
@media (max-width: 480px) {
  .stats__grid--2x2 { grid-template-columns: minmax(0, 1fr); }
}
.spotlight__text h2 {
  font-size: var(--text-display-s);
  line-height: 1.05;
  margin-bottom: var(--space-md);
}
.spotlight__desc {
  font-size: var(--text-lg);
  color: var(--color-ink-2);
  max-width: 30rem;
  margin-bottom: var(--space-lg);
}
.spotlight__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
}
.spotlight__secondary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  font-size: var(--text-sm);
}


/* ============================= Attendance stats — real facts, no invented metrics ============================= */
.stats { padding-block-start: var(--space-lg); }
.stats__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-md);
}
@media (max-width: 860px) {
  .stats__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .stats__grid { grid-template-columns: minmax(0, 1fr); }
}
.stat {
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
}
.stat--highlight {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.stat__label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-ink-2);
  margin-bottom: var(--space-md);
}
.stat--highlight .stat__label { color: var(--color-accent-ink); opacity: 0.85; }
.stat__value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: 1.2;
  font-weight: 600;
  color: var(--color-ink);
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}
.stat--highlight .stat__value { color: var(--color-accent-ink); }

/* ============================= Section head ============================= */
.section-head {
  max-width: 40rem;
  margin-bottom: var(--space-xl);
}
.section-head.center { margin-inline: auto; text-align: center; }
.section-head h2 { font-size: var(--text-3xl); line-height: 1.15; }
.section-head p { margin-top: var(--space-xs); color: var(--color-ink-2); font-size: var(--text-base); }

/* ============================= Bento Grid ============================= */
.bento {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-md);
  grid-auto-rows: minmax(15rem, auto);
  grid-auto-flow: dense;
}
.tile {
  grid-column: span 2;
  grid-row: span 1;
  display: flex;
  flex-direction: column;
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  transition: border-color var(--dur-base) var(--ease-out);
}
.tile:hover { border-color: var(--color-rule-2); }
.tile--lg { grid-column: span 4; grid-row: span 2; }
@media (min-width: 860px) { .tile--lg { grid-column: span 2; grid-row: span 2; } }

.tile__media {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--color-accent-soft);
  margin-bottom: var(--space-md);
  min-width: 0;
}
.tile--lg .tile__media { aspect-ratio: 16 / 8; }
.tile__media-label {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  flex-direction: column;
  gap: var(--space-2xs);
  color: var(--color-accent-soft-ink);
  font-size: var(--text-xs);
  font-weight: 600;
  text-align: center;
  padding: var(--space-sm);
}
.tile__play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-scrim);
  color: var(--color-accent-ink);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.tile__media:hover .tile__play, .tile__media:focus-within .tile__play { opacity: 1; }
.tile__play-icon {
  width: 3rem; height: 3rem;
  border-radius: 50%;
  background: var(--color-overlay);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent);
}

.tile__kicker {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-ink-3);
  margin-bottom: var(--space-3xs);
}
.tile h3 { font-size: var(--text-xl); margin-bottom: var(--space-2xs); }
.tile--lg h3 { font-size: var(--text-2xl); }
.tile p.tile__desc { color: var(--color-ink-2); font-size: var(--text-sm); flex-grow: 1; }

.tile__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3xs);
  margin-top: var(--space-sm);
}
.chip {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-ink-2);
  background: var(--color-paper);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-sm);
  padding: 0.25rem 0.625rem;
}

.tile__meta {
  margin-top: var(--space-sm);
  font-size: var(--text-xs);
  color: var(--color-ink-3);
  font-style: italic;
}

.tile__actions {
  margin-top: var(--space-md);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm) var(--space-md);
}

.badge-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-accent-soft-ink);
  background: var(--color-accent-soft);
  border-radius: var(--radius-pill);
  padding: 0.375rem 0.75rem;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out);
}
.badge-link:hover { background: var(--color-badge-hover); }

@media (max-width: 768px) {
  .bento { grid-template-columns: minmax(0, 1fr); }
  .tile, .tile--lg { grid-column: span 1; grid-row: span 1; }
}

/* ============================= Proof band ============================= */
.proof {
  background: var(--color-paper-3);
  border-top: 1px solid var(--color-rule);
  border-bottom: 1px solid var(--color-rule);
}
.proof__row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-xl);
}
.proof__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  flex: 1 1 16rem;
  min-width: 0;
  padding-inline-start: var(--space-xl);
  border-left: 1px solid var(--color-rule);
}
.proof__item:first-child {
  padding-inline-start: 0;
  border-left: none;
}
@media (max-width: 720px) {
  .proof__item { padding-inline-start: 0; border-left: none; flex-basis: 100%; }
}
.proof__item h3 {
  font-size: var(--text-base);
  margin-bottom: var(--space-3xs);
}
.proof__item p { font-size: var(--text-sm); color: var(--color-ink-2); }
.proof__icon {
  flex-shrink: 0;
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
  display: flex; align-items: center; justify-content: center;
}

/* ============================= Request a demo ============================= */
.demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: start;
}
@media (max-width: 860px) {
  .demo { grid-template-columns: minmax(0, 1fr); }
}

.picker {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2xs);
}
@media (max-width: 420px) { .picker { grid-template-columns: minmax(0, 1fr); } }

.picker label {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-sm);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.picker label:hover { border-color: var(--color-rule-2); }
.picker input[type="checkbox"] {
  width: 1.125rem; height: 1.125rem;
  accent-color: var(--color-accent);
  flex-shrink: 0;
}
.picker label:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
}

.field { margin-bottom: var(--space-sm); }
.field label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-ink-2);
  margin-bottom: var(--space-3xs);
}
.field input, .field textarea {
  width: 100%;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--color-ink);
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule-2);
  border-radius: var(--radius-sm);
  padding: 0.75rem var(--space-sm);
  outline: 2px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.field input:hover, .field textarea:hover { border-color: var(--color-ink-3); }
.field input:focus-visible, .field textarea:focus-visible {
  border-color: var(--color-accent);
  outline: 2px solid var(--color-focus);
  outline-offset: 1px;
}
.field input:disabled, .field textarea:disabled { background: var(--color-paper-3); color: var(--color-ink-3); cursor: not-allowed; }
.field textarea { resize: vertical; min-height: 6rem; }

.field.has-error input, .field.has-error textarea { border-color: var(--color-danger); }
.field__error {
  min-height: 1.2em;
  margin-top: var(--space-3xs);
  font-size: var(--text-xs);
  color: var(--color-danger);
  opacity: 0;
  visibility: hidden;
}
.field.has-error .field__error { opacity: 1; visibility: visible; }

.form__status {
  display: none;
  margin-top: var(--space-sm);
  padding: var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
}
.form__status.is-success { display: block; background: var(--color-success-soft); color: var(--color-success-ink); }
.form__status.is-error { display: block; background: var(--color-danger-soft); color: var(--color-danger-ink); }

/* ============================= Footer (Ft2) ============================= */
.footer {
  border-top: 1px solid var(--color-rule);
  padding-block: var(--space-lg);
}
.footer__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-ink-3);
}
.footer__brand {
  display: inline-flex;
  align-items: center;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.footer__brand img {
  height: 1.5rem;
  width: auto;
  display: block;
}
.footer__brand:hover { opacity: 0.8; }
.footer__contact { display: flex; flex-wrap: wrap; gap: var(--space-sm) var(--space-md); }
.footer__contact a:hover { color: var(--color-accent); }

/* ============================= Sticky WhatsApp button =============================
 * Fixed bottom-left, sitewide. No pulsing/attention motion — this page has zero
 * ambient animation everywhere else (verified: only a spin keyframe for a loading
 * state), and this shouldn't be the one exception. Hover/active only. */
.whatsapp-fab {
  position: fixed;
  left: var(--space-lg);
  bottom: var(--space-lg);
  z-index: 45;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  background: var(--color-whatsapp);
  color: var(--color-accent-ink);
  box-shadow: var(--shadow-modal);
  transition: background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.whatsapp-fab:hover { background: var(--color-whatsapp-hover); }
.whatsapp-fab:active { transform: translateY(1px); }
@media (max-width: 640px) {
  .whatsapp-fab {
    left: var(--space-md);
    bottom: var(--space-md);
    width: 3rem;
    height: 3rem;
  }
}

/* ============================= Video modal ============================= */
.modal-backdrop {
  position: fixed; inset: 0;
  background: var(--color-scrim-strong);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  z-index: 100;
}
.modal-backdrop.is-open { display: flex; }
.modal {
  width: 100%;
  max-width: 48rem;
  background: var(--color-video-bg);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-modal);
  position: relative;
  aspect-ratio: 16 / 9;
}
.modal iframe { width: 100%; height: 100%; border: 0; }
.modal__close {
  position: absolute;
  top: var(--space-sm); right: var(--space-sm);
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  background: var(--color-overlay);
  color: var(--color-ink);
  display: flex; align-items: center; justify-content: center;
  z-index: 1;
}
.modal__close:hover { background: var(--color-overlay-hover); color: var(--color-accent); }

/* ============================= Try-it-live credentials panel ============================= */
.tryit-panel {
  position: relative;
  width: 100%;
  max-width: 30rem;
  max-height: 85vh;
  overflow-y: auto;
  background: var(--color-paper-2);
  border-radius: var(--radius-md);
  padding: var(--space-xl);
  box-shadow: var(--shadow-modal);
}
.tryit-panel h3 { font-size: var(--text-xl); margin-bottom: var(--space-2xs); padding-right: var(--space-xl); }
.tryit-panel__intro { font-size: var(--text-sm); color: var(--color-ink-2); margin-bottom: var(--space-lg); }
.tryit-card {
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-sm);
  padding: var(--space-md);
}
.tryit-card + .tryit-card { margin-top: var(--space-sm); }
.tryit-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-2xs);
}
.tryit-card__label { font-weight: 600; font-size: var(--text-sm); }
.tryit-card__badge {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 0.125rem 0.5rem;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.tryit-card__badge--ok { background: var(--color-success-soft); color: var(--color-success-ink); }
.tryit-card__badge--fail { background: var(--color-danger-soft); color: var(--color-danger-ink); }
.tryit-card__desc { font-size: var(--text-sm); color: var(--color-ink-2); margin-bottom: var(--space-sm); }
.tryit-cred {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}
.tryit-cred + .tryit-cred { margin-top: var(--space-2xs); }
.tryit-cred__field {
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-ink);
  background: var(--color-paper);
  border: 1px solid var(--color-rule-2);
  border-radius: var(--radius-sm);
  padding: 0.5rem var(--space-sm);
  overflow-wrap: anywhere;
}
.tryit-cred__copy {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-ink-2);
  background: var(--color-paper);
  border: 1px solid var(--color-rule-2);
  border-radius: var(--radius-sm);
  padding: 0.5rem var(--space-sm);
  min-width: 4.5rem;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.tryit-cred__copy:hover { border-color: var(--color-accent); color: var(--color-accent); }
.tryit-cred__copy.is-copied { border-color: var(--color-success); color: var(--color-success-ink); }
.tryit-note {
  font-size: var(--text-xs);
  color: var(--color-ink-3);
  margin-top: var(--space-md);
}
.tryit-panel__open {
  margin-top: var(--space-lg);
  width: 100%;
}

/* ============================= Attendance walkthrough — device frame =============================
 * Deliberately generic: a rounded bezel + one small camera dot, not an attempt to
 * replicate a specific real phone/tablet's exact chrome (no fake notch, no fake
 * home button) — that level of faking is the actual anti-pattern, a plain
 * abstract frame is not.
 */
.walkthrough__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: center;
}
@media (max-width: 860px) {
  .walkthrough__grid { grid-template-columns: minmax(0, 1fr); }
}
.walkthrough__text h2 {
  font-size: var(--text-display-s);
  line-height: 1.05;
  margin-bottom: var(--space-md);
}
.walkthrough__text p:not(.spotlight__eyebrow) {
  font-size: var(--text-lg);
  color: var(--color-ink-2);
  max-width: 28rem;
  margin-bottom: var(--space-lg);
}
.walkthrough .problem-solution p {
  text-align: justify;
}

.device-frame {
  width: 100%;
  max-width: 25rem;
  margin-inline: auto;
  background: var(--color-ink);
  border-radius: 2rem;
  padding: 0.875rem;
  box-shadow: var(--shadow-modal);
  position: relative;
}
/* Stagger — the frame reveals a beat after its paired text, not simultaneously. */
.device-frame.reveal { transition-delay: 150ms; }
.device-frame::before {
  content: "";
  position: absolute;
  top: 0.45rem;
  left: 50%;
  transform: translateX(-50%);
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--color-ink-3);
  opacity: 0.7;
}
.device-frame__screen {
  position: relative;
  border-radius: 1.25rem;
  overflow: hidden;
  aspect-ratio: 812 / 1080;
  background: var(--color-video-bg);
  min-width: 0;
}
.device-frame__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ============================= Off-Track Alerts — "how it works" strip, not a text+media split =============================
 * Deliberately a different section shape from Attendance/Site Monitoring/Timesheet:
 * this module is a 3-step process (deadline passes → daily check → PM notified),
 * not a single screen to browse. Eyebrow + numbered step strip (left-aligned) sit
 * on top; the video + heading/copy pair below reuses .walkthrough__grid (video left,
 * text right) rather than introducing a third grid pattern.
 */
.offtrack__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-xl);
  margin-bottom: var(--space-2xl);
}
@media (max-width: 760px) {
  .offtrack__steps { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
}
.offtrack__step-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-accent-soft-ink);
  margin-bottom: var(--space-sm);
}
.offtrack__step h3 {
  font-size: var(--text-lg);
  margin-bottom: var(--space-2xs);
}
.offtrack__step p {
  color: var(--color-ink-2);
  font-size: var(--text-base);
}

/* Text sits left, paired with a "before" problem illustration on the
   right (reusing .walkthrough__grid), with the screenshot walkthrough
   still living below, full-width, per the earlier restructure. */
.offtrack__head {
  /* Text column wider than the image column — the paragraph's own
     max-width (below) was the real cause of early wrapping, but the
     image doesn't need a full 1fr share either, so give text more room. */
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.9fr);
  margin-bottom: var(--space-2xl);
}
.offtrack .problem-solution p {
  /* .walkthrough__text p had a 28rem cap that ignored the actual
     available width beside the image — widened slightly so lines run
     further before wrapping, without stretching the full column. */
  max-width: 34rem;
  text-align: justify;
}
@media (max-width: 860px) {
  .offtrack__head {
    grid-template-columns: minmax(0, 1fr);
  }
}
.offtrack__problem-figure {
  max-width: 22rem;
  margin-inline: auto;
}
.offtrack__problem-figure.reveal { transition-delay: 150ms; }
.offtrack__problem-figure img {
  width: 100%;
  height: auto;
  display: block;
}
@media (max-width: 860px) {
  .offtrack__problem-figure {
    max-width: 18rem;
  }
}

.offtrack__card {
  width: 100%;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 1600 / 784;
  background: var(--color-video-bg);
  box-shadow: var(--shadow-modal);
}
.offtrack__card.reveal { transition-delay: 150ms; }
/* Below the text, centered, sized to match the other module video cards
   (Labour/PM/Approval) rather than stretching full container width. */
.offtrack__card--below {
  max-width: 56rem;
  margin-inline: auto;
  margin-bottom: var(--space-lg);
}
.offtrack__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.offtrack__actions { justify-content: center; }

/* ============================= Labour Scheduling — "week strip" shape =============================
 * A third distinct section shape: this module's real identity is a week broken
 * into 7 day-tabs rolling up into weekly totals, so it gets a day-strip + real
 * stat numbers instead of another text+media split or numbered-step row.
 */
.labour__head {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.9fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-xl);
}
@media (max-width: 860px) {
  .labour__head {
    grid-template-columns: minmax(0, 1fr);
  }
}
.labour__problem-figure {
  max-width: 20rem;
  margin-inline: auto;
}
.labour__problem-figure.reveal { transition-delay: 150ms; }
.labour__problem-figure img {
  width: 100%;
  height: auto;
  display: block;
}
@media (max-width: 860px) {
  .labour__problem-figure {
    max-width: 18rem;
  }
}
.labour h2 {
  font-size: var(--text-display-s);
  line-height: 1.05;
  margin-bottom: var(--space-md);
}
.labour__desc {
  font-size: var(--text-lg);
  color: var(--color-ink-2);
  max-width: 32rem;
}
.labour__week {
  list-style: none;
  margin: 0 0 var(--space-xl);
  padding: 0;
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
  justify-content: center;
}
.labour__day {
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule);
  color: var(--color-ink-3);
  font-size: var(--text-sm);
  font-weight: 500;
}
.labour__day--active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
  font-weight: 700;
}
.labour .problem-solution p {
  /* Narrowed from the earlier full-width version — space on the right
     is now reserved for a problem illustration, similar to Off-Track. */
  max-width: 34rem;
  text-align: justify;
}
.labour__card {
  width: 100%;
  max-width: 56rem;
  margin-inline: auto;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 1468 / 720;
  background: var(--color-video-bg);
  box-shadow: var(--shadow-modal);
  margin-bottom: var(--space-lg);
}
.labour__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.labour__actions { justify-content: center; }

/* ============================= Project Management — "capability tabs" shape =============================
 * A fourth distinct section shape: this module is 4 parallel capabilities, not a
 * screen, a process, or a week — so it gets a tab switcher (one shared video
 * element, source swapped on click) instead of yet another split or strip.
 * Tabs reuse the same active/inactive pill language as Labour Scheduling's
 * week strip (.labour__day) for visual consistency, just as clickable <button>s.
 */
.pm h2 {
  font-size: var(--text-display-s);
  line-height: 1.05;
  max-width: 46rem;
  margin-bottom: var(--space-md);
}
.pm .labour__desc {
  max-width: 42rem;
  margin-bottom: var(--space-xl);
}
.pm .problem-solution p {
  text-align: justify;
}
.pm__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-xl);
}
.pm__tab {
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  background: var(--color-paper-2);
  border: 1px solid var(--color-rule);
  color: var(--color-ink-3);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.pm__tab:hover { border-color: var(--color-accent-soft); }
.pm__tab--active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
  font-weight: 700;
}
.pm__card {
  position: relative;
  width: 100%;
  max-width: 56rem;
  margin-inline: auto;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 1600 / 784;
  background: var(--color-video-bg);
  box-shadow: var(--shadow-modal);
}
.pm__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.pm__video[data-loaded="true"] ~ .pm__placeholder { display: none; }
.pm__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  color: var(--color-ink-3);
  background: var(--color-paper-2);
  text-align: center;
  padding: var(--space-lg);
}
.pm__placeholder svg { opacity: 0.5; }
.pm__placeholder-text {
  font-size: var(--text-sm);
  font-weight: 500;
}
.pm__caption {
  text-align: center;
  color: var(--color-ink-2);
  font-size: var(--text-base);
  max-width: 34rem;
  margin: var(--space-lg) auto var(--space-lg);
}

/* ============================= Vendor Payment / Journal Entry Approval — connected stepper =============================
 * A fifth distinct section shape: unlike Off-Track's flat numbered-fact cards,
 * this is a literal chain of custody (a document moving through real people
 * before money moves), so it gets a connected stepper — dots joined by a line,
 * color-coded done/current/pending — the standard checkout/tracking-progress
 * pattern, not a plain step grid.
 */
.approval__head {
  margin-bottom: var(--space-xl);
}
.approval__head h2 {
  font-size: var(--text-display-s);
  line-height: 1.05;
  margin-bottom: var(--space-md);
}
.approval .problem-solution p {
  max-width: none;
  text-align: justify;
}
.approval .walkthrough__grid {
  margin-bottom: var(--space-2xl);
}
.approval__figure img {
  width: 100%;
  height: auto;
  display: block;
}
.approval__stepper {
  list-style: none;
  margin: 0 0 var(--space-2xl);
  padding: 0;
  display: flex;
}
@media (max-width: 640px) {
  .approval__stepper { flex-wrap: wrap; row-gap: var(--space-lg); }
}
.approval__step {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 5rem;
}
.approval__step:not(:first-child)::before {
  content: "";
  position: absolute;
  top: 0.55rem;
  right: 50%;
  width: 100%;
  height: 2px;
  background: var(--color-rule);
  z-index: 0;
}
.approval__step.is-done:not(:first-child)::before {
  background: var(--color-accent);
}
.approval__dot {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 50%;
  background: var(--color-paper-2);
  border: 2px solid var(--color-rule);
  color: var(--color-accent-ink);
  margin-bottom: var(--space-sm);
}
.approval__step.is-done .approval__dot {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.approval__step.is-current .approval__dot {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px var(--color-accent-soft);
}
.approval__label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-ink-3);
}
.approval__step.is-done .approval__label,
.approval__step.is-current .approval__label {
  color: var(--color-ink);
  font-weight: 700;
}
.approval__card {
  position: relative;
  width: 100%;
  max-width: 56rem;
  margin-inline: auto;
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 1468 / 720;
  background: var(--color-video-bg);
  box-shadow: var(--shadow-modal);
  margin-bottom: var(--space-lg);
}
.approval__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.approval__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  color: var(--color-ink-3);
  background: var(--color-paper-2);
  text-align: center;
  padding: var(--space-lg);
}
.approval__placeholder svg { opacity: 0.5; }
.approval__placeholder-text {
  font-size: var(--text-sm);
  font-weight: 500;
}
.approval__actions { justify-content: center; }

/* ============================= Bridge section — illustration, no device frame ============================= */
.bridge__figure {
  position: relative;
  max-width: 22rem;
  margin-inline: auto;
  display: flex;
  justify-content: center;
}
.bridge__figure.reveal { transition-delay: 150ms; }
.bridge__figure::before {
  content: "";
  position: absolute;
  inset: 8% 12%;
  background: var(--color-accent-soft);
  filter: blur(2.5rem);
  opacity: 0.45;
  border-radius: 50%;
  z-index: -1;
}
.bridge__figure img {
  width: 100%;
  height: auto;
  display: block;
}

/* PM's "problem" illustration — plain, no accent-colored glow behind it
   (unlike .bridge__figure's), since green stays reserved for solved-state
   visuals and this is deliberately the problem side. */
/* Scoped to .pm specifically — .walkthrough__grid itself has no margin-bottom
   (several other sections reuse that class and don't need one), so nothing
   was separating this grid from the tabs row below it here. */
.pm .walkthrough__grid {
  margin-bottom: var(--space-2xl);
}
.pm__problem-figure {
  max-width: 28rem;
  margin-inline: auto;
}
.pm__problem-figure.reveal { transition-delay: 150ms; }
.pm__problem-figure img {
  width: 100%;
  height: auto;
  display: block;
}
@media (max-width: 860px) {
  /* Same breakpoint .walkthrough__grid stacks at, same cap .hero__figure
     already uses once stacked — 28rem would otherwise run nearly edge to
     edge on a phone, oversized relative to the text above it. */
  .pm__problem-figure {
    max-width: 20rem;
  }
}

/* ============================= Mobile-only overrides =============================
 * Everything in this block is scoped to a max-width query on purpose — none of
 * it should ever affect desktop, and nothing here touches any section/feature
 * beyond what's listed: (1) justified problem/solution text reads with ragged,
 * uneven word-gaps on narrow columns, so it switches to left-aligned once each
 * section's own grid has already stacked to one column; (2) the Attendance
 * before/after block gets pushed down (handled above, in its own existing
 * 640px query) so its "Before" label clears whatever sits above it; (3) the
 * problem illustration in Off-Track/Labour/PM moves to sit between the
 * problem and solution paragraphs instead of trailing after both, matching
 * how a reader actually encounters "problem → picture of it → the fix".
 */
@media (max-width: 860px) {
  .walkthrough .problem-solution p,
  .offtrack .problem-solution p,
  .labour .problem-solution p,
  .pm .problem-solution p,
  .approval .problem-solution p {
    text-align: left;
  }

  /* Off-Track: unwrap the text column so h2 / problem / image / solution
     become orderable siblings within the same grid. The text wrapper's own
     reveal fade-in is inherently skipped once unwrapped (display:contents
     has no box to animate) — everything else's animation is unaffected. */
  .offtrack__head .walkthrough__text,
  .offtrack__head .problem-solution {
    display: contents;
  }
  .offtrack__head h2 { order: 1; }
  .offtrack__head .problem-solution p:first-child { order: 2; }
  .offtrack__problem-figure { order: 3; }
  .offtrack__head .problem-solution p:last-child { order: 4; }

  /* Labour Scheduling: same unwrap, but the eyebrow/h2/problem-solution here
     each already carry their own .reveal class, so unwrapping the plain
     wrapper doesn't drop any animation. */
  .labour__head-text,
  .labour__head .problem-solution {
    display: contents;
  }
  .labour__head .spotlight__eyebrow { order: 1; }
  .labour__head h2 { order: 2; }
  .labour__head .problem-solution p:first-child { order: 3; }
  .labour__problem-figure { order: 4; }
  .labour__head .problem-solution p:last-child { order: 5; }

  /* Project Management: scoped to .pm's own grid instance specifically —
     .walkthrough__grid is shared by other sections that aren't part of
     this request, so a bare .walkthrough__grid selector would leak into
     those. Same trade-off as Off-Track: the text wrapper's own reveal
     fade-in is skipped once unwrapped. */
  .pm .walkthrough__grid .walkthrough__text,
  .pm .walkthrough__grid .problem-solution {
    display: contents;
  }
  .pm .walkthrough__grid .spotlight__eyebrow { order: 1; }
  .pm .walkthrough__grid h2 { order: 2; }
  .pm .walkthrough__grid .problem-solution p:first-child { order: 3; }
  .pm__problem-figure { order: 4; }
  .pm .walkthrough__grid .problem-solution p:last-child { order: 5; }
}

/* ============================= Skip link (a11y) ============================= */
.skip-link {
  position: fixed;
  top: -3rem; left: var(--space-md);
  background: var(--color-ink);
  color: var(--color-paper);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-sm);
  z-index: 200;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-md); }