/* Hallmark · service-area pages · redesign 3 · tone: technical-austere
 * theme: none - locked design language (brand-tokens.css).
 *
 * ONE KIT, FOUR ARGUMENTS. Pass two gave each page a different macrostructure
 * and a critique panel read that as four different builders. Pass three gives
 * the four siblings ONE spine - hero → stakes → 01 what we run → one dark
 * centrepiece → 02 named proof → a close that names the service, plus onward
 * links - and lets the CONTENT be the variety: a support panel, an evidence
 * panel, a change calendar, a boundary map. That is how /pricing, /industries
 * and /services already differ from each other while belonging to one site.
 *
 * The kit is the benchmark's own parts: the trace-field hero (sitewide rule),
 * pricing's tier cell (.tr-svc-cell) and numbered group head (.tr-svc-group),
 * industries' hairline proof cells, the dot-grid dark ground, one numbering
 * dialect. Ground rhythm on every page: ivory · ivory · ivory · DARK · ivory ·
 * ivory · CTA card - exactly one coloured band before the close.
 */

/* ═══ HERO ═══════════════════════════════════════════════════════════════
   Two forms, both taken from the benchmark: split-with-media (/services) and
   centred (/pricing, /industries, /contact). Never left copy over an empty
   right half - that form exists on none of the five. ═══════════════════ */

.tr-svc-hero {
    background: var(--mv-color-ivory);
    padding: calc(var(--tr-hero-clearance) + var(--tr-hero-gap)) 0 var(--tr-hero-gap);
    position: relative;
    overflow: hidden;
}
.tr-svc-hero__field {
    position: absolute; inset: 0; z-index: 0; pointer-events: none;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 60%, transparent 100%);
}
.tr-svc-hero__inner {
    position: relative; z-index: 1;
    max-width: 1420px; margin: 0 auto; padding: 0 32px;
}
.tr-svc-hero--split .tr-svc-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 80px;
    align-items: center;
}
.tr-svc-hero--centred .tr-svc-hero__inner { text-align: center; }
.tr-svc-hero--centred .tr-svc-hero__headline,
.tr-svc-hero--centred .tr-svc-hero__sub { margin-inline: auto; }
.tr-svc-hero--centred .tr-svc-hero__actions { justify-content: center; }

.tr-svc-hero .mv-eyebrow { margin-bottom: 18px; }
.tr-svc-hero__headline {
    font-family: var(--tr-font-display);
    font-size: var(--tr-size-h1);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-h1);
    line-height: var(--tr-leading-h1);
    color: var(--mv-color-evergreen);
    max-width: 22ch;
    margin: 0 0 20px;
    text-wrap: balance;
    overflow-wrap: break-word;
}
.tr-svc-hero__sub {
    font-size: var(--tr-size-body-lg);
    line-height: var(--tr-leading-body-lg);
    color: var(--tr-text-secondary);
    max-width: 58ch;
    margin: 0 0 28px;
}
.tr-svc-hero__actions { display: flex; flex-wrap: wrap; gap: 12px; }
/* The stroke button ships for DARK grounds (ivory text + border). Every ivory
   context on the site overrides it to evergreen - the /services hero, the FAQ.
   Without this the secondary label rendered ivory-on-ivory: invisible. Same
   values as .tr-services-hero__actions .mv-ascii-btn--stroke. */
.tr-svc-hero__actions .mv-ascii-btn--stroke {
    --ascii-color: var(--mv-color-evergreen);   /* the component reads this, not `color` */
    color: var(--mv-color-evergreen);
    border-color: var(--mv-color-evergreen);
    --ascii-accent: var(--mv-color-indigo);
}
.tr-svc-hero__actions .mv-ascii-btn--stroke:hover,
.tr-svc-hero__actions .mv-ascii-btn--stroke:focus-visible {
    color: var(--mv-color-indigo);
    border-color: var(--mv-color-indigo);
}

/* The media half: same box as /services - rounded, framed, cover-fit. */
.tr-svc-hero__media {
    position: relative;
    box-sizing: border-box;   /* theme is content-box globally; the 1px border made this 345px in a 343px column */
    border-radius: 20px;
    border: 1px solid var(--tr-ev-subtle);
    box-shadow: 0 4px 24px var(--tr-ev-subtle);
    overflow: hidden;
    background: #0a1f0d;
    min-height: 380px;
    align-self: stretch;
}
.tr-svc-hero__media .tr-media-scrub { position: absolute; inset: 0; border: 0; border-radius: inherit; }
/* Some pillar posters sit darker than the /services network graph in the same
   slot (p95 luminance 56 vs 103). Lift the frame, not the asset. */
.tr-svc-hero__media--lift .tr-media-scrub__poster,
.tr-svc-hero__media--lift .tr-media-scrub__frame { filter: brightness(1.28) contrast(1.04); }
.tr-svc-hero__headline--narrow { max-width: 19ch; }

/* ═══ SHARED PRIMITIVES ══════════════════════════════════════════════════ */

.tr-svc-inner { max-width: 1420px; margin: 0 auto; padding: 0 32px; }

/* Section heading - eyebrow, H2, lede, stacked. Used ONCE per section; never
   repeated by a group head with the same words. */
.tr-svc-head { max-width: 820px; margin-bottom: 40px; }
.tr-svc-head .mv-eyebrow { margin-bottom: 16px; }
.tr-svc-head__title {
    font-family: var(--tr-font-display);
    font-size: var(--tr-size-h2);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-h2);
    line-height: var(--tr-leading-h2);
    color: var(--mv-color-evergreen);
    margin: 0 0 14px;
    text-wrap: balance;
}
.tr-svc-head__lede {
    font-size: var(--tr-size-body-lg);
    line-height: var(--tr-leading-body-lg);
    color: var(--tr-text-secondary);
    margin: 0;
    max-width: 58ch;
}

/* Group head - pricing's device, verbatim. The site's ONE numbering dialect. */
.tr-svc-group {
    display: flex; align-items: baseline; gap: 16px;
    padding-bottom: 14px; margin-bottom: 20px;
    border-bottom: 1px solid var(--mv-hairline-mid);
}
.tr-svc-group + .tr-svc-cells + .tr-svc-group,
.tr-svc-cells + .tr-svc-group { margin-top: 64px; }   /* the 01–05 ladder reads as one sequence, not four blocks */
.tr-svc-group__num {
    flex-shrink: 0;
    font-family: var(--tr-font-mono);
    font-size: var(--tr-size-body-sm);
    font-weight: var(--tr-weight-bold);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--tr-tracking-wide);
    color: var(--mv-color-indigo);
}
.tr-svc-group__label {
    flex-shrink: 0;
    font-family: var(--tr-font-display);
    font-size: var(--tr-size-h5);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-h5);
    line-height: var(--tr-leading-h5);
    color: var(--mv-color-evergreen);
    margin: 0;
}
.tr-svc-group__lede {
    font-size: var(--tr-size-body-sm);
    line-height: var(--tr-leading-body);
    color: var(--tr-text-tertiary);
    min-width: 0;
}

/* Cells - pricing's tier cell, verbatim. 3-up by default, 4-up by modifier.
   Content is written to a multiple of the column count; no orphan spans. */
.tr-svc-cells { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.tr-svc-cells--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.tr-svc-cell {
    padding: 26px 22px;
    box-sizing: border-box;
    border: 1px solid var(--tr-ev-subtle);
    background: var(--mv-bg-surface);
    border-radius: var(--tr-radius-md);
    position: relative; overflow: hidden; min-width: 0;
    transition: border-color 0.3s var(--tr-ease-out), box-shadow 0.3s var(--tr-ease-out), translate 0.3s var(--tr-ease-out);
}
.tr-svc-cell::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 0;
    background: linear-gradient(180deg, var(--tr-ind-subtle), var(--tr-ind-wash));
    pointer-events: none; z-index: 0;
    transition: height 0.3s var(--tr-ease-out);
}
.tr-svc-cell > * { position: relative; z-index: 1; }
.tr-svc-cell:hover { border-color: var(--tr-ind-muted); box-shadow: var(--tr-shadow-card-hover); translate: 0 -4px; }
.tr-svc-cell:hover::before { height: 100%; }
[data-animate="stagger"].is-visible .tr-svc-cell[data-animate-child] {
    transition: opacity 0.55s var(--tr-ease-spring), transform 0.55s var(--tr-ease-spring),
                border-color 0.3s var(--tr-ease-out), box-shadow 0.3s var(--tr-ease-out), translate 0.3s var(--tr-ease-out);
}
.tr-svc-cell__prefix {
    display: block;
    font-family: var(--tr-font-mono);
    font-size: var(--tr-size-label);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-wide);
    color: var(--mv-color-indigo);
    margin-bottom: 12px;
}
.tr-svc-cell__title {
    font-family: var(--tr-font-display);
    font-size: var(--tr-size-h5);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-h5);
    line-height: var(--tr-leading-h5);
    color: var(--mv-color-evergreen);
    margin: 0 0 8px;
    overflow-wrap: anywhere;
}
.tr-svc-cell__body { font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); margin: 0; }
.tr-svc-cell__list { list-style: none; margin: 12px 0 0; padding: 0; }
.tr-svc-cell__list li { font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); padding: 4px 0; }
.tr-svc-cell__list li::before { content: '\2192  '; color: var(--mv-color-indigo); }

/* Dark textured ground - the industries callout / footer / CTA texture. */
.tr-svc-dark { background: var(--mv-color-evergreen); position: relative; overflow: hidden; }
.tr-svc-dark--indigo { background: linear-gradient(150deg, #382C67 0%, #342861 48%, #2a2058 100%); }
.tr-svc-dark::after {
    content: ''; position: absolute; inset: 0;
    background-image: radial-gradient(circle, var(--tr-iv-wash) 1px, transparent 1px);
    background-size: 28px 28px;
    pointer-events: none; z-index: 0;
}
.tr-svc-dark > * { position: relative; z-index: 1; }
.tr-svc-dark .tr-svc-head__title { color: var(--mv-color-ivory); }
.tr-svc-dark .tr-svc-head__lede  { color: var(--tr-light-secondary); }

/* Scroll-scrubbed video + ASCII vignette (js/tr-service-media.js). */
.tr-media-scrub { position: relative; overflow: hidden; background: #0a1f0d; border-radius: var(--tr-radius-md); border: 1px solid var(--tr-lime-border); }
.tr-media-scrub__poster, .tr-media-scrub__frame, .tr-media-scrub__ascii { position: absolute; inset: 0; width: 100%; height: 100%; max-width: 100%; max-height: 100%; display: block; border-radius: inherit; }
.tr-media-scrub__poster { object-fit: cover; z-index: 0; pointer-events: none; }
.tr-media-scrub__frame  { z-index: 1; }
.tr-media-scrub__ascii  { z-index: 2; pointer-events: none; }
.tr-media-scrub__video  { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* ═══ SPINE SECTIONS ═════════════════════════════════════════════════════ */

/* Stakes - the page's problem statement in the company's own voice; never a
   third-party statistic. A CARD, not a band: same construction as the
   /industries S2 callout and the contact page's testimonial block, on INDIGO
   rather than evergreen. Ivory SECTION ground, dark block inset inside it.

   No vertical padding on the section. The hero carries its own bottom gap and
   .tr-run its own top gap, so anything here would stack on a gap that already
   exists and read as a double gap around the callout. */
.tr-stakes { background: var(--mv-color-ivory); padding: 0; }
.tr-stakes__wrap { max-width: 1420px; margin: 0 auto; padding: 0 32px; }
.tr-stakes__card {
    background: var(--mv-color-indigo);
    border-radius: var(--tr-radius-md);
    overflow: hidden;
    padding: 64px 0;
    position: relative;
}
/* Interactive ASCII field - js/tr-stakes-ascii.js. Positioned exactly as the
   /industries and contact canvases are: full bleed, no mask. */
.tr-stakes__canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; 
    /* Ceiling so an inline pixel width set by the canvas script can never
       exceed its box. The scripts write canvas.style.width in px, which beats
       the stylesheet's width:100%; if the ResizeObserver misses a beat on a
       viewport shrink the element stays oversized and pushes the page wide -
       393px of horizontal overflow at 375 before this. */
    max-width: 100%; max-height: 100%;
}
.tr-stakes__inner { position: relative; z-index: 1; max-width: 1420px; margin: 0 auto; padding: 0 32px; }
.tr-stakes .tr-svc-head { margin: 0 auto; max-width: 820px; text-align: center; }
.tr-stakes .tr-svc-head__lede { margin-inline: auto; color: var(--tr-light-secondary); }
.tr-stakes .tr-svc-head__title {
    font-size: var(--tr-size-h3); letter-spacing: var(--tr-tracking-h3);
    line-height: var(--tr-leading-h3); color: var(--mv-color-ivory);
}
/* The eyebrow gets its OWN ground rather than sitting on the animated field.
   Lime is correct on a dark card but it is 12px, and the cursor blob is what
   costs it - the same reading that put an evergreen chip behind the
   /industries eyebrow. Indigo here so the chip belongs to this card. 0.88 not
   1.0, so the field still reads faintly behind it. */
.tr-stakes__inner .mv-eyebrow {
    background:
        linear-gradient(rgba(58, 205, 72, 0.08), rgba(58, 205, 72, 0.08)),
        rgba(61, 49, 114, 0.88);
}

/* What we run - ivory, group heads over full-width cell grids. */
.tr-run { background: var(--mv-color-ivory); padding: var(--tr-space-section-lg) 0; }
.tr-run .tr-svc-head { margin-bottom: 36px; }

/* Proof - ivory, industries' hairline cells with a mono attribution. */
/* Proof always follows a section that carries its own bottom air (a cell run
   or the dark band), so it adds none on top - two stacked tokens measured
   198px on Managed IT against a benchmark vocabulary of 96–108. */
.tr-proof { background: var(--mv-color-ivory); padding: var(--tr-space-section-lg) 0 var(--tr-space-section-sm); }
.tr-run + .tr-proof { padding-top: 0; }   /* the run's own bottom token is the seam */
/* Two items, both complete (stat · text · quote · attribution). Six real
   studies across four pages cannot fill twelve slots without repeating, and a
   repeated testimonial reads as one testimonial pretending to be several. */
.tr-proof__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--tr-space-gap-xl); }
.tr-proof .tr-svc-group { border-bottom: 0; margin-bottom: 4px; }
.tr-proof__item { min-width: 0; border-top: 1px solid var(--mv-hairline-mid); padding-top: 20px; }
.tr-proof__stat {
    display: block;
    font-family: var(--tr-font-display);
    font-size: var(--tr-size-h3);
    font-weight: var(--tr-weight-heading);
    letter-spacing: var(--tr-tracking-h3);
    line-height: 1.05;
    color: var(--mv-color-evergreen);
    font-variant-numeric: tabular-nums;
    margin-bottom: 8px;
}
.tr-proof__text { font-size: var(--tr-size-body); line-height: var(--tr-leading-body); color: var(--tr-text-secondary); margin: 0 0 12px; }
.tr-proof__quote { font-family: var(--tr-font-display); font-size: var(--tr-size-h6); font-style: italic; line-height: var(--tr-leading-h6); color: var(--mv-color-evergreen); margin: 0 0 12px; }
.tr-proof__who { display: block; font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: var(--tr-leading-label); letter-spacing: 0.02em; color: var(--tr-text-tertiary); }

/* Onward - every page routes back to its parent and across to its siblings. */
.tr-svc-next { background: var(--mv-color-ivory); padding: 0 0 var(--tr-space-section-sm); }   /* the locked pages sit 108px of ivory above the CTA card; the card carries that itself */
.tr-svc-next { padding-bottom: 0; }
.tr-run + .tr-run { padding-top: 0; }   /* Managed IT's Documentation run follows the panel's own bottom air */
.tr-svc-next__inner {
    max-width: 1420px; margin: 0 auto; padding: 0 32px;
}
.tr-svc-next__strip {
    display: grid; grid-template-columns: auto minmax(0, 1fr);
    align-items: center; gap: 12px 40px;
    padding: 18px 20px;
    border: 1px solid var(--mv-hairline-mid);
    border-radius: var(--tr-radius-md);
    background: var(--mv-bg-surface);
}
.tr-svc-next__list { display: flex; flex-wrap: wrap; gap: 4px 26px; justify-content: flex-end; }
.tr-svc-next__back, .tr-svc-next__link {
    font-family: var(--tr-font-mono);
    font-size: var(--tr-size-label);
    line-height: var(--tr-leading-label);
    letter-spacing: 0.02em;
    text-decoration: none;
    padding: 8px 0;
    color: var(--tr-text-secondary);
    border-bottom: 1px solid transparent;
    transition: color 0.2s var(--tr-ease-out), border-color 0.2s var(--tr-ease-out);
}
.tr-svc-next__back { color: var(--mv-color-evergreen); }
.tr-svc-next__link[aria-current="page"] { color: var(--mv-color-indigo); border-bottom-color: var(--mv-color-indigo); }
.tr-svc-next__back:hover, .tr-svc-next__link:hover,
.tr-svc-next__back:focus-visible, .tr-svc-next__link:focus-visible { color: var(--mv-color-indigo); border-bottom-color: var(--mv-color-indigo); outline: none; }

/* ═══ CENTREPIECE A · THE PANEL (managed-it: support · cybersecurity: evidence)
   Sticky scrubbed media left, copy right. Sticky top clears the floating
   header - pass two pinned it to 0 and slid the video under the pill.

   The COPY HALF IS IVORY, not a dark ground. In a 50/50 with video on one
   side, a coloured text half competes with the image instead of framing it,
   and the reader gets two grounds fighting across one seam. The media half
   stays dark because the asset is; everything to its right is page. ═══ */

.tr-panel { background: var(--mv-color-ivory); position: relative; }
/* Dividers above and below, as on the homepage pillars section. One rule can't
   do it: the band is half dark media and half ivory copy, and --mv-hairline
   (evergreen 0.07) is invisible on evergreen while --tr-iv-border is invisible
   on ivory. So each divider is a gradient that swaps colour at the 50% seam. */
.tr-panel::before,
.tr-panel::after {
    content: ''; position: absolute; left: 0; right: 0; height: 1px; z-index: 2;
    background: linear-gradient(90deg,
        var(--tr-iv-border) 0 50%,
        var(--mv-hairline) 50% 100%);
}
.tr-panel::before { top: 0; }
.tr-panel::after  { bottom: 0; }
/* The homepage pillars treatment: the media half pins at ~100vh and scrubs
   while the copy half travels past it. The LEFT HALF OF THE GRID is painted
   evergreen for the section's whole height, so the pinned media never leaves
   bare ivory above or below itself - which is what made the earlier sticky
   attempt look broken and forced the --static fallback. */
.tr-panel__grid {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    background: linear-gradient(90deg,
        #0a1f0d 0 50%,                      /* == .tr-media-scrub's own base */
        var(--mv-color-ivory) 50% 100%);
}
.tr-panel__media {
    /* The COLUMN stretches to the row, so the row is exactly as tall as the
       copy plus its padding. The sticky element is the scrub wrap INSIDE it,
       sized to the smaller of the viewport and the column. Short copy: the
       media is the copy's height and never pins, so a tall monitor gets no
       band of empty ivory under the text (Jacob, 2026-09-10). Long copy: the
       media is viewport-height and pins while the copy travels past, exactly
       as before. No overflow:hidden here - a clipping ancestor would become
       the sticky's scroll container and kill the pin. */
    align-self: stretch;
    position: relative;
    background: #0a1f0d;
}
.tr-panel__media .tr-media-scrub {
    position: sticky;
    top: var(--tr-hero-clearance);
    display: block;
    width: 100%;
    height: min(calc(100vh - var(--tr-hero-clearance)), 100%);
    border-radius: 0; border: 0;   /* the ground change is the divider */
}
/* No artificial minimum height. An earlier pass padded this column to 128vh to
   manufacture sticky travel, which on cybersecurity - where the copy is short -
   just produced a column of empty ivory. Travel is whatever the copy naturally
   gives over the media's height; a short panel pins briefly, and that is
   honest. */
.tr-panel__copy { padding: var(--tr-space-section-xl) 64px; }
.tr-panel__copy .tr-svc-head { margin-bottom: 36px; }
.tr-panel__label {
    display: block;
    font-family: var(--tr-font-mono);
    font-size: var(--tr-size-label);
    line-height: var(--tr-leading-label);
    letter-spacing: 0.06em;
    color: var(--mv-color-indigo);
    margin: 0 0 16px;
}
.tr-panel__block + .tr-panel__block { margin-top: 44px; }

.tr-panel__item { padding: 18px 0; border-top: 1px solid var(--mv-hairline); }
.tr-panel__item:last-child { border-bottom: 1px solid var(--mv-hairline); }
.tr-panel__item-title { font-family: var(--tr-font-display); font-size: var(--tr-size-h5); font-weight: var(--tr-weight-heading); line-height: var(--tr-leading-h5); color: var(--mv-color-evergreen); margin: 0 0 6px; }
.tr-panel__item-body  { font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); margin: 0; max-width: 58ch; }


.tr-panel__sla { border-top: 1px solid var(--mv-hairline); }
.tr-panel__sla-row {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "label time" "desc time";
    gap: 2px var(--tr-space-gap-md); align-items: baseline;
    padding: 16px 0; border-bottom: 1px solid var(--mv-hairline);
}
.tr-panel__sla-label { grid-area: label; font-family: var(--tr-font-display); font-size: var(--tr-size-h6); font-weight: var(--tr-weight-heading); color: var(--mv-color-evergreen); }
/* P1–P4, as the live site publishes them. Mono + tabular like every other
   ordinal on the site; the priority code reads as a key, not a heading. */
.tr-panel__sla-pri {
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label);
    font-weight: var(--tr-weight-bold); font-variant-numeric: tabular-nums;
    letter-spacing: var(--tr-tracking-wide); color: var(--mv-color-indigo);
    margin-right: 10px;
}
.tr-panel__sla-desc  { grid-area: desc;  font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); }
.tr-panel__sla-time  { grid-area: time;  font-family: var(--tr-font-mono); font-size: var(--tr-size-body-sm); color: var(--mv-color-indigo); white-space: nowrap; }
.tr-panel__note { margin: 16px 0 0; font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: var(--tr-leading-label); color: var(--tr-text-tertiary); }

/* Evidence ledger rows (cybersecurity). Marks are mono so they belong to the
   system; the two refusals are not bolded - the mark already differentiates. */
.tr-ledger__row { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 14px 0; border-top: 1px solid var(--mv-hairline); }
.tr-ledger__row:last-child { border-bottom: 1px solid var(--mv-hairline); }
.tr-ledger__mark { font-family: var(--tr-font-mono); font-size: var(--tr-size-body-sm); }
.tr-ledger__row--yes .tr-ledger__mark { color: var(--tr-ev-strong); }
.tr-ledger__row--no  .tr-ledger__mark { color: var(--tr-color-red); }
.tr-ledger__text { font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); }
.tr-ledger__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ═══ CENTREPIECE B · THE CHANGE CALENDAR (it-projects) - indigo ═════════
   Five lanes across twelve months: one lane per legend key, so every key is
   drawn and every mark has a key. The fifth lane marks the months none of
   the windows touch - the page's actual answer. Placement is explicit
   (--m, --lane) so the grid reflows without re-ordering. ═══════════════ */

.tr-cal { padding: var(--tr-space-section-lg) 0; }
.tr-cal .tr-svc-head { max-width: 900px; }

.tr-cal__grid {
    display: grid;
    grid-template-columns: 148px repeat(12, minmax(0, 1fr));
    grid-template-rows: 22px repeat(5, 30px);
    position: relative;                        /* the badge is centred on this box */
    gap: 10px 0;
    margin: 8px 0 26px;
}
.tr-cal__grid--3 { grid-template-rows: 22px repeat(3, 46px); }
.tr-cal__mon { grid-row: 1; grid-column: calc(var(--m) + 2); font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: 22px; color: var(--tr-light-secondary); text-align: center; }
.tr-cal__mon--q { color: var(--mv-color-ivory); }
.tr-cal__lane-label {
    grid-column: 1; grid-row: calc(var(--lane) + 2);
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: 30px;
    color: var(--tr-light-secondary); white-space: nowrap; padding-right: 10px;
}
.tr-cal__lane-label .tr-cal__short { display: none; }
/* Each lane is ONE continuous track spanning all twelve months, with the
   month divisions drawn on it as hairlines and the quarter ends heavier. The
   old chart gave every month its own bordered, filled box - sixty of them -
   which read as a spreadsheet rather than a year, and left the sparse lanes
   (K-1, calls, change) looking like holes rather than marks on a track. */
.tr-cal__track {
    grid-column: 2 / -1; grid-row: calc(var(--lane) + 2);
    border-radius: 4px; background: rgba(251, 252, 239, 0.05);
    background-image:
        repeating-linear-gradient(90deg, transparent 0 calc(100% / 12 - 1px), rgba(13, 44, 17, 0.30) calc(100% / 12 - 1px) calc(100% / 12)),
        repeating-linear-gradient(90deg, transparent 0 calc(100% / 4 - 1px),  rgba(13, 44, 17, 0.55) calc(100% / 4 - 1px)  calc(100% / 4));
}
.tr-cal__cell { grid-column: calc(var(--m) + 2); grid-row: calc(var(--lane) + 2); position: relative; z-index: 1; margin: 9px 0; border-radius: 2px; }

/* ONE MEANING PER COLOUR. Lavender = booked, lime = available; lime appears
   exactly once on the chart.

   The chart is ONE FIRM'S YEAR, not four audiences stacked into one. The
   earlier version drew a family office's K-1 season, a hedge fund's NAV close
   and a PE firm's capital calls across the same twelve months, then computed
   the free months across all three - a composite true of no actual client.
   Bands are placed WITHIN each month (--l/--r and --a/--b, percentages),
   because a month-end close does not consume a month; it consumes its edges. */

/* lane 0 · the books close - blocked at both ends of every month, wider at Q */
.tr-cal__cell--close {
    background: linear-gradient(90deg,
        rgba(206,202,226,0.55) 0 var(--l),
        transparent var(--l) var(--r),
        rgba(206,202,226,0.55) var(--r) 100%);
}
/* lane 1 · the annual audit - one continuous band */
.tr-cal__cell--audit {
    background: linear-gradient(90deg, transparent 0 var(--a), rgba(206,202,226,0.34) var(--a) var(--b), transparent var(--b) 100%);
}
/* lane 2 · what is left - the only lime on the chart */
.tr-cal__cell--go {
    background: linear-gradient(90deg, transparent 0 var(--a), var(--mv-color-lime) var(--a) var(--b), transparent var(--b) 100%);
    opacity: 0.9;
}

/* The nudge from the homepage terminal section, repurposed: same chip, same
   shadow, no arrows and no bounce. Centred on the chart so the illustrative
   status is read before the data is. */
.tr-cal__badge {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    z-index: 3; max-width: 92%; white-space: nowrap; text-align: center;
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label);
    line-height: var(--tr-leading-label); letter-spacing: 0.04em;
    /* Glass: thin enough to read the lanes through, blurred and saturated so
       the marks behind stay legible as colour rather than detail. The text
       carries its own shadow because the backdrop varies from bare track to a
       lime bar. */
    color: var(--mv-color-ivory);
    background: rgba(13, 44, 17, 0.38);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid rgba(251, 252, 239, 0.22);
    border-radius: var(--tr-radius-sm);
    padding: 11px 18px;
    text-shadow: 0 1px 3px rgba(13, 44, 17, 0.75);
    box-shadow:
        inset 0 1px 0 rgba(251, 252, 239, 0.20),
        inset 0 -1px 0 rgba(13, 44, 17, 0.35),
        0 8px 28px rgba(0, 0, 0, 0.34);
}

/* Reading the chart: how to, in one sentence, at a readable measure. */
.tr-cal__caption {
    max-width: 78ch; margin: 0 0 34px;
    font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body);
    color: var(--tr-light-secondary);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .tr-cal__badge { background: rgba(13, 44, 17, 0.92); }
}

.tr-cal__legend {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--tr-space-gap-lg);
    padding-top: 26px; border-top: 1px solid var(--tr-iv-border);
}
.tr-cal__key { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 10px; align-items: start; }
.tr-cal__swatch { width: 18px; height: 18px; border-radius: 3px; margin-top: 2px; background: rgba(251,252,239,0.035); position: relative; }
.tr-cal__swatch--close { background: linear-gradient(90deg, rgba(206,202,226,0.55) 0 30%, transparent 30% 70%, rgba(206,202,226,0.55) 70% 100%); }
.tr-cal__swatch--audit { background: rgba(206,202,226,0.34); }
.tr-cal__swatch--go    { background: var(--mv-color-lime); opacity: 0.9; }
.tr-cal__key-who  { display: block; font-family: var(--tr-font-display); font-size: var(--tr-size-h6); font-weight: var(--tr-weight-heading); color: var(--mv-color-ivory); margin-bottom: 4px; }
.tr-cal__key-when { display: block; font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-light-secondary); }

/* The workflow - five stages on a rail. The rail is drawn per step (from
   each marker to the next), so it ends ON the last marker, never past it. */
/* ═══ HOW A PROJECT RUNS (it-projects) - its own beat, on ivory ══════════
   This was a footnote below the calendar's legend, inside the indigo band.
   It is a five-stage process that applies to every project on the page, not
   a detail of the change-window chart, so it is now a numbered section of
   its own and the ladder runs 01-02-03-04. ═══════════════════════════════ */
.tr-flow { background: var(--mv-color-ivory); padding: var(--tr-space-section-lg) 0; }
.tr-flow + .tr-proof { padding-top: 0; }   /* the flow's bottom token is the seam */
.tr-flow__steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--tr-space-gap-md); }
.tr-flow__step { min-width: 0; position: relative; cursor: default; }

/* Hover follows the homepage pain-point nodes verbatim (.tr-pain-nodes__node):
   the dot scales on a spring, its ring grows, the title takes the indigo hover
   accent and the body lifts one step. The one addition is the FILL - this dot
   is an outline at rest where the homepage's is already solid.

   The lift lives on the DOT, not the <li>: [data-animate-child] already owns
   `transform` on the step for its 0.55s reveal, so a hover transform there
   fights the reveal and inherits its duration. */
.tr-flow__step:hover .tr-flow__step-dot {
    transform: scale(1.5);
    box-shadow: 0 0 0 5px var(--tr-ind-muted);
}
.tr-flow__step:hover .tr-flow__step-title { color: var(--mv-color-indigo); }
.tr-flow__step:hover .tr-flow__step-text  { color: var(--tr-text-secondary); }
.tr-flow__step-dot {
    display: block; width: 10px; height: 10px; border-radius: 50%;
    background: var(--mv-color-indigo);
    box-shadow: 0 0 0 3px var(--tr-ind-border);
    margin: 8px 0 16px; position: relative; z-index: 1;
    transition: transform 0.3s var(--tr-ease-spring),
                box-shadow 0.3s ease;
}
.tr-flow__step:not(:last-child)::before {
    content: ''; position: absolute; left: 18px; right: calc(-1 * var(--tr-space-gap-md)); top: 13px; height: 1px;
    background: var(--mv-hairline-mid);
}
.tr-flow__step-title { transition: color 0.2s var(--tr-ease-out); font-family: var(--tr-font-display); font-size: var(--tr-size-h6); font-weight: var(--tr-weight-heading); color: var(--mv-color-evergreen); margin: 0 0 6px; }
.tr-flow__step-text  { transition: color 0.2s ease; font-size: var(--tr-size-body-sm); line-height: var(--tr-leading-body); color: var(--tr-text-tertiary); margin: 0; }

/* ═══ CENTREPIECE C · THE BOUNDARY MAP (planning) - evergreen ════════════
   Their platforms as nodes above, one bus rule, what we run below. Every
   connector is sized from ONE custom property, --tr-map-drop, and the bus is
   a single absolutely positioned rule that the label knocks out with its own
   background - so connectors meet the line by construction, not by luck.
   Nodes stay OUTLINE. Connectors go to the bus, not to specific layers. ═══ */

.tr-map { padding: var(--tr-space-section-xl) 0; --tr-map-drop: 36px; }
.tr-map .tr-svc-head { max-width: 900px; }

.tr-map__theirs, .tr-map__ours { list-style: none; margin: 0; padding: 0; }
.tr-map__layer-label {
    display: block;
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: var(--tr-leading-label);
    text-transform: uppercase; letter-spacing: 0.06em;
}
.tr-map__layer-label--theirs { color: var(--tr-light-tertiary); margin-bottom: 14px; }
.tr-map__layer-label--ours   { color: var(--mv-color-lime); margin-top: 14px; }   /* BELOW the blocks: keeps the riser corridor clear */
.tr-map__layer-note { font-family: var(--tr-font-body); text-transform: none; letter-spacing: 0; color: var(--tr-light-secondary); margin-left: 10px; }

/* BASE = the form that holds at every width: the eleven wrap, the rule below
   them runs edge to edge, the blocks sit under it. Per-node connectors and the
   4-up block row are DETAIL, added back at >=1100px where they fit - see the
   min-width block below. Built this way round because the nowrap row needs
   ~1020px of chips plus gaps, so anything narrower used to overflow its own
   border, and the old <=1024 rules replaced the rule with a vertical stub,
   which deleted the boundary at exactly the size that most needed it. */
.tr-map__theirs { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 8px; padding-bottom: var(--tr-map-drop); }
.tr-map__node {
    position: relative; flex: 0 1 auto; min-width: 0;
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: 1;
    color: var(--tr-light-secondary);
    padding: 9px 11px;
    border: 1px solid var(--tr-iv-border); border-radius: var(--tr-radius-sm);
    background: transparent; white-space: nowrap;
}
/* the bus row: a fixed-height band with the rule at exactly y=0 */
.tr-map__bus { position: relative; height: 2px; margin: 0 0 var(--tr-map-drop); }
.tr-map__bus::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--tr-iv-strong); }
.tr-map__bus-label {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    font-family: var(--tr-font-mono); font-size: var(--tr-size-label); line-height: var(--tr-leading-label);
    letter-spacing: 0.04em; color: var(--mv-color-ivory); text-align: center; white-space: nowrap;
    padding: 8px 14px; border: 1px solid var(--tr-iv-strong); border-radius: var(--tr-radius-sm);
    background: var(--mv-color-evergreen);   /* knocks the rule out behind itself */
}

.tr-map__ours { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.tr-map__block {
    position: relative;
    padding: 18px 18px 16px;
    border: 1px solid var(--tr-iv-strong); border-radius: var(--tr-radius-sm);
    background: rgba(13, 44, 17, 0.55);
}
.tr-map__block-title { display: block; font-family: var(--tr-font-display); font-size: var(--tr-size-h6); font-weight: var(--tr-weight-heading); color: var(--mv-color-ivory); margin-bottom: 4px; }
.tr-map__block-body  { display: block; font-size: var(--tr-size-label); line-height: var(--tr-leading-label); color: var(--tr-light-secondary); }

/* DETAIL LAYER - only where the eleven fit on one line. Their natural widths
   sum to ~1020px plus ten 8px gaps, and .tr-svc-inner is viewport minus 64,
   so 1100 is the first width where space-between is honest. Below it the
   chips wrap and the connectors would point at nothing. */
@media (min-width: 1100px) {
    .tr-map__theirs { flex-wrap: nowrap; justify-content: space-between; }
    /* connector from each node down to the bus - exactly --tr-map-drop, so it
       meets the rule by construction rather than by luck */
    .tr-map__node::after { content: ''; position: absolute; left: 50%; top: 100%; width: 1px; height: var(--tr-map-drop); background: var(--tr-iv-border); }
    .tr-map__ours { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    /* riser from the block top up to the bus - same measure, same reason */
    .tr-map__block::before { content: ''; position: absolute; left: 50%; bottom: 100%; width: 1px; height: var(--tr-map-drop); background: var(--tr-iv-strong); }
}

/* ═══ RESPONSIVE ═════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
    .tr-svc-hero__inner, .tr-svc-inner, .tr-stakes__wrap, .tr-stakes__inner, .tr-svc-next__inner { padding-left: 24px; padding-right: 24px; }
    .tr-run, .tr-flow { padding: var(--tr-space-section-sm) 0; }
    .tr-proof { padding: var(--tr-space-section-sm) 0; }
    .tr-cal, .tr-map { padding: var(--tr-space-section-md) 0; }

    .tr-svc-hero--split .tr-svc-hero__inner { grid-template-columns: minmax(0, 1fr); gap: 36px; }
    /* min-height must be 0 here: with aspect-ratio set, a min-height of 300px
       made the browser derive WIDTH from height (480px) and the box overflowed
       the 16px gutter to the viewport edge on every phone. Width leads now. */
    .tr-svc-hero__media { width: 100%; min-height: 0; aspect-ratio: 16 / 10; align-self: auto; }

    .tr-svc-cells, .tr-svc-cells--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tr-proof__grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
    .tr-proof__item { padding: 20px 0; }
    .tr-proof__item:last-child { border-bottom: 1px solid var(--mv-hairline-mid); }

    /* display:block alone was not enough. The grid also carries a 90deg
       gradient that paints its LEFT HALF evergreen for the section's full
       height - the device that keeps the pinned desktop media off bare ivory.
       Stacked, that half-and-half paint ran straight down the copy column and
       put evergreen text on an evergreen ground. The media block below keeps
       its own #0a1f0d, so resetting the grid to ivory costs nothing here. */
    .tr-panel__grid { display: block; background: var(--mv-color-ivory); }
    /* Stacked: media on top, copy below - so each divider needs one colour. */
    .tr-panel::before { background: var(--tr-iv-border); }
    .tr-panel::after  { background: var(--mv-hairline); }
    .tr-panel__media { position: relative; height: 46vh; min-height: 300px; overflow: hidden; }
    .tr-panel__media .tr-media-scrub { position: absolute; inset: 0; height: auto; border-right: 0; }
    .tr-panel__copy { padding: var(--tr-space-section-sm) 24px; }

    .tr-cal__legend { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--tr-space-gap-md) var(--tr-space-gap-lg); }
    /* The rail turns vertical below 1025px so the sequence survives the stack. */
    .tr-flow__steps { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .tr-flow__step { display: grid; grid-template-columns: 10px minmax(0, 1fr); gap: 0 20px; }
    .tr-flow__step-dot { margin: 4px 0 0; grid-row: 1 / 3; }
    .tr-flow__step-title { grid-column: 2; }
    .tr-flow__step-text { grid-column: 2; }
    .tr-flow__step:not(:last-child)::before { left: 4px; right: auto; top: 18px; bottom: -18px; width: 1px; height: auto; }

    /* The map's nodes would wrap and drop connectors through the next row, so
       below 1025px the diagram becomes its vertical form: node cloud, a
       spine with the label ON it, the four blocks. Stubs touch both layers. */
    /* The rule, the knockout label and the above/below reading are all kept.
       Only the drop tightens. */
    .tr-map { --tr-map-drop: 30px; }
    .tr-svc-next__strip { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .tr-svc-next__list { justify-content: flex-start; }
}

@media (max-width: 768px) {
    .tr-svc-hero__inner, .tr-svc-inner, .tr-stakes__wrap, .tr-stakes__inner, .tr-svc-next__inner { padding-left: 16px; padding-right: 16px; }
    .tr-run, .tr-flow, .tr-cal, .tr-map { padding: var(--tr-space-section-xs) 0; }
    /* less air on a phone: 64px top and bottom is a lot of empty indigo */
    .tr-stakes__card { padding: 44px 0; }
    .tr-proof { padding: var(--tr-space-section-xs) 0; }

    .tr-svc-hero__headline { max-width: none; }
    .tr-svc-cells, .tr-svc-cells--4 { grid-template-columns: minmax(0, 1fr); }
    /* The group head's rule earns its keep on desktop, where it spans a 3- or
       4-up grid and reads as the edge of that block. Stacked into one column it
       lands 20px above the first card's own top border - two parallel hairlines
       doing one job, with a dead band between them. The number, the label and
       the space still mark the group; the cards bring their own edges. */
    .tr-svc-group { flex-wrap: wrap; gap: 8px 14px; border-bottom: 0; padding-bottom: 0; margin-bottom: 14px; }
    .tr-svc-cells + .tr-svc-group,
    .tr-svc-group + .tr-svc-cells + .tr-svc-group { margin-top: 44px; }

    .tr-panel__copy { padding: var(--tr-space-section-xs) 16px; }
    .tr-panel__media { height: 40vh; min-height: 240px; }

    /* Calendar: the twelve columns stay - lanes must not wrap - with
       single-letter month labels and a narrower lane-label column. */
    .tr-cal__grid { grid-template-columns: 58px repeat(12, minmax(0, 1fr)); grid-template-rows: 20px repeat(5, 26px); gap: 8px 0; }
    .tr-cal__grid--3 { grid-template-rows: 20px repeat(3, 34px); }
    /* On a phone the chart is ~110px tall and the badge is ~90px, so centring
       it over the lanes erases them. It becomes a full-width block in an
       implicit row under the chart instead - same message, chart intact. */
    .tr-cal__badge {
        position: static; transform: none; grid-column: 1 / -1; grid-row: 5;
        max-width: none; white-space: normal; margin-top: 14px; font-size: 11px;
        padding: 9px 12px; letter-spacing: 0.02em;
    }
    .tr-cal__mon { font-size: 10px; line-height: 20px; }
    .tr-cal__mon > span { display: none; }
    .tr-cal__mon::before { content: attr(data-l); }
    .tr-cal__lane-label { font-size: 10px; line-height: 26px; padding-right: 6px; }
    .tr-cal__lane-label .tr-cal__long { display: none; }
    .tr-cal__lane-label .tr-cal__short { display: inline; }
    .tr-cal__legend { grid-template-columns: minmax(0, 1fr); gap: var(--tr-space-gap-md); }

    /* On a phone the diagram is a list read top-down, so each layer gets its
       label ABOVE it: "Your platforms" + chips, the rule, "What we run" +
       blocks. On desktop the second label sits below the blocks to keep the
       riser corridor clear; here there are no risers. Blocks go two-up
       because each is a title and one short line. */
    .tr-map .tr-svc-inner { display: flex; flex-direction: column; }
    .tr-map__layer-label--ours { order: 4; margin: 0 0 14px; }
    .tr-map__ours { order: 5; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .tr-map__block { padding: 14px 14px 12px; }
    .tr-map__bus { margin-bottom: 24px; }
    .tr-map__theirs { padding-bottom: 24px; }
    .tr-proof__grid { grid-template-columns: minmax(0, 1fr); }

    /* Stacked, so each row is its own line. Rows are sized by their padding
       alone - a 44px touch floor here inflated every row to 61px and left the
       card reading as five items floating in a lot of ivory. The rows carry a
       hairline between them instead, which is what makes a short vertical list
       look deliberate rather than merely spaced out. The link's own
       border-bottom stays free for the hover / current-page indicator. */
    .tr-svc-next__strip { padding: 8px 18px 12px; gap: 0; }
    .tr-svc-next__inner { gap: 6px 18px; }
    .tr-svc-next__list { flex-direction: column; align-items: flex-start; gap: 0; }
    /* Rows are sized by their own padding. A 44px touch floor inflated each one
       to 61px and left five links floating in a card of ivory. Links stay at
       content width so the current-page rule still reads as an underline on the
       text rather than a divider across the card. */
    .tr-svc-next__back, .tr-svc-next__link { padding: 9px 0; }
}

/* ── Numbered group heads on dark grounds (the centrepieces are numbered in
      the same dialect as the ivory sections, so the count never skips) ── */
.tr-svc-dark .tr-svc-group { border-bottom-color: var(--tr-iv-border); }
.tr-svc-dark .tr-svc-group__num { color: var(--mv-color-lime); }
.tr-svc-dark .tr-svc-group__label { color: var(--mv-color-ivory); }
.tr-svc-dark .tr-svc-group__lede { color: var(--tr-light-secondary); }
.tr-cal .tr-svc-group, .tr-map .tr-svc-group { margin-bottom: 28px; }
.tr-cal .tr-svc-head, .tr-map .tr-svc-head { margin-bottom: 32px; }

/* The scale is decorative - drop it when motion is not wanted. The fill and
   the colour shifts stay: they are the state change, not the animation. */
@media (prefers-reduced-motion: reduce) {
    .tr-flow__step-dot { transition: box-shadow 0.2s ease; }
    .tr-flow__step:hover .tr-flow__step-dot { transform: none; }
}

@media (max-width: 400px) {
    .tr-map__ours { grid-template-columns: minmax(0, 1fr); }
}
