/* ============================================================
   AVX VISUAL SYSTEM — production layer (Jul 2026 rebuild)
   Source: VISUAL_BUILD_SPEC_FOR_MANUS.md + MANUS_VISUAL_PRODUCTION_ADDENDUM.md
   Doctrine: Black carries power · Bone carries the message ·
   Green shows revenue moving · Bronze shows authority · Evidence proves the claim.
   ============================================================ */

/* --- 17-token palette (exact spec hexes; aliases keep legacy rules working) --- */
:root{
  --obsidian:#05080A;
  --deep-carbon:#0A0F11;
  --graphite-panel:#101719;
  --elevated-graphite:#151D1F;
  --carbon-border:#263033;
  --warm-bone:#E8E3D8;
  --soft-bone:#CFC9BD;
  --titanium:#939B9D;
  --muted-titanium:#667174;
  --near-black-ink:#06110A;
  --altavex-green:#28E884;
  --mid-green:#16B968;
  --deep-green:#0B7A49;
  --highlight-green:#8CFFC1;
  --champagne-bronze:#B08D57;
  --deep-bronze:#72552E;
  --light-champagne:#D2B579;
  /* legacy aliases → spec values (overrides earlier :root) */
  --carbon:var(--deep-carbon);
  --panel:var(--graphite-panel);
  --raised:var(--elevated-graphite);
  --border:var(--carbon-border);
  --bone:var(--warm-bone);
  --soft:var(--soft-bone);
  --titanium-l:#AEB8B7; /* legacy value kept ONLY where small text needs contrast */
  /* --muted is a TEXT token: it is consumed by 26 `color:` rules (footer column
     headings, .foot-legal copyright, .trust line under the hero CTA, .wnote,
     step numerals). It was aliased to --muted-titanium (#667174), which measures
     4.00:1 on the footer, 3.84:1 on body and 3.61:1 on panels -- ALL below the
     WCAG AA 4.5:1 minimum for small text. Because this file loads after
     styles.css on all 40 pages, that alias silently overrode the accessible
     #8A9593 declared there and pushed every muted string on the site under AA.
     #8A9593 restores 6.50 / 6.24 / 5.87:1 respectively.
     --muted-titanium (#667174) is intentionally left untouched: it is the
     connector doctrine's IDLE GRAPHIC state (--avx-conn-idle) and is also used
     by .sq-blocked and .lg-state.suppressed. Idle diagram strokes are decorative
     and are not held to text contrast, so the two roles must stay separate. */
  --muted:#8A9593;
  --green:var(--altavex-green);
  --green-mid:var(--mid-green);
  --green-deep:var(--deep-green);
  --green-hi:var(--highlight-green);
  --bronze:var(--champagne-bronze);
  --bronze-hi:var(--light-champagne);
  /* gradients */
  --revenue-gradient:linear-gradient(135deg,#0B7A49 0%,#16B968 45%,#28E884 100%);
  --premium-gradient:linear-gradient(135deg,#72552E 0%,#B08D57 55%,#D2B579 100%);
  --carbon-depth:linear-gradient(180deg,#151D1F 0%,#101719 45%,#0A0F11 100%);
  --hero-overlay:linear-gradient(180deg,rgba(5,8,10,.72),rgba(5,8,10,.97));
}

/* contrast guard: legacy small text that used --titanium keeps AA */
.small-meta,.fine,.wnote{color:var(--titanium-l)}

/* --- Background tiles (SVG assets, sit BEHIND content) --- */
.avx-bg-foundation{background-color:var(--deep-carbon);background-image:url('avx-foundation-grid.svg?v=20260803c');background-size:64px 64px}
.avx-bg-node-field{background-color:var(--deep-carbon);background-image:url('avx-node-field.svg?v=20260803c');background-size:192px 192px}
.avx-bg-blueprint{background-color:var(--deep-carbon);background-image:url('avx-blueprint-grid.svg?v=20260803c');background-size:96px 96px}
.avx-bg-command{background-color:var(--obsidian);background-image:url('avx-command-grid.svg?v=20260803c');background-size:160px 160px}
.avx-bg-cinematic{background-color:var(--obsidian)}
.avx-overlay{position:relative}
.avx-overlay::before{content:"";position:absolute;inset:0;background:var(--hero-overlay);pointer-events:none}
.avx-overlay>*{position:relative;z-index:1}
/* softer wash so tiles read at ~12–18% effective opacity */
.avx-wash{position:relative}
.avx-wash::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,15,17,.55),rgba(10,15,17,.86));pointer-events:none}
.avx-wash>*{position:relative;z-index:1}

/* --- Typography system --- */
.avx-display{font-family:"Manrope",system-ui,sans-serif;font-size:clamp(46px,6.2vw,78px)!important;line-height:.98!important;font-weight:800!important;letter-spacing:-.045em!important;margin:0 0 18px}
.avx-statement{font-family:"Manrope",system-ui,sans-serif;font-size:clamp(32px,4.5vw,52px)!important;line-height:1.04!important;font-weight:800!important;letter-spacing:-.035em!important;max-width:900px}
.avx-heading{font-family:"Manrope",system-ui,sans-serif;font-size:clamp(27px,3.5vw,40px)!important;line-height:1.1!important;font-weight:750!important;letter-spacing:-.025em!important}
.avx-card-title{font-family:"Manrope",system-ui,sans-serif;font-size:19px;line-height:1.2;font-weight:750;color:var(--warm-bone)}
.avx-signal-label{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}

/* --- Word emphasis --- */
.avx-word-revenue{color:var(--altavex-green)}
.avx-word-authority{color:var(--light-champagne)}
.avx-word-pending{color:var(--titanium)}
.avx-word-proof{color:var(--altavex-green)}
.avx-word-receipt{color:var(--champagne-bronze)}
.avx-word-evidence{color:var(--altavex-green)}

/* --- Three title systems --- */
.title-signal{display:inline-block;position:relative}
.title-signal::after{content:"";position:absolute;left:0;bottom:-9px;width:72px;height:3px;background:linear-gradient(90deg,var(--deep-green),var(--altavex-green));box-shadow:0 0 16px rgba(40,232,132,.30)}
.title-authority{border-left:3px solid var(--champagne-bronze);padding-left:18px}
.title-proof-lockup{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap}
.receipt-lockup{font-family:"IBM Plex Mono",monospace;font-size:10px;line-height:1.35;letter-spacing:.10em;text-transform:uppercase;color:var(--champagne-bronze);border:1px solid rgba(176,141,87,.50);padding:8px 10px;border-radius:6px;background:rgba(16,23,25,.72)}
.receipt-lockup .rl-ok{color:var(--altavex-green)}

/* --- Ghost words --- */
.avx-ghost-host{position:relative;overflow:hidden}
.section-ghost-word{position:absolute;top:8px;right:-8px;font-family:"Manrope",sans-serif;font-size:clamp(80px,14vw,190px);font-weight:800;letter-spacing:-.07em;color:rgba(232,227,216,.025);line-height:.8;pointer-events:none;user-select:none;z-index:0}
.avx-ghost-host>.container,.avx-ghost-host>.wrap{position:relative;z-index:1}

/* --- Buttons (align to spec; layer over legacy .btn-*) --- */
.btn-primary,.avx-btn-primary{background:var(--altavex-green);color:var(--near-black-ink);border:1px solid var(--altavex-green)}
.btn-primary:hover,.avx-btn-primary:hover{background:var(--highlight-green);border-color:var(--highlight-green);color:var(--near-black-ink)}
.avx-btn-command,.btn-command{background:transparent;color:var(--light-champagne);border:1px solid rgba(176,141,87,.55)}
.avx-btn-command:hover,.btn-command:hover{background:rgba(176,141,87,.08);border-color:var(--champagne-bronze)}

/* --- Card states (hierarchy, not uniform glow) --- */
.avx-card{background:var(--graphite-panel);border:1px solid var(--carbon-border);border-radius:14px;padding:22px 20px}
.avx-card--featured{position:relative;border-color:rgba(40,232,132,.35)}
.avx-card--featured::before{content:"";position:absolute;top:0;left:14px;right:14px;height:2px;background:var(--revenue-gradient);border-radius:2px}
.avx-card--authority{position:relative;background:linear-gradient(180deg,#131a1a,var(--graphite-panel))}
.avx-card--authority::after{content:"";position:absolute;top:10px;right:10px;width:8px;height:8px;background:var(--champagne-bronze);border-radius:1px}
.avx-card--proof .p-state{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.08em;text-transform:uppercase}
.avx-card--human{border:1px solid rgba(232,227,216,.45)}
.avx-card--human .human-badge{display:inline-block;font:600 9.5px/1 "IBM Plex Mono",monospace;letter-spacing:.12em;color:var(--warm-bone);border:1px solid rgba(232,227,216,.4);border-radius:4px;padding:4px 7px;text-transform:uppercase}
.avx-card--locked{opacity:.55;border-style:dashed}

/* --- Signal state legend (squares) --- */
.sq{display:inline-block;width:10px;height:10px;border-radius:2px;flex:0 0 auto}
.sq-dormant{border:1px solid var(--carbon-border);background:transparent}
.sq-active{border:1px solid var(--mid-green);background:rgba(22,185,104,.15)}
.sq-pending{border:1px solid var(--titanium);background:rgba(147,155,157,.15)}
.sq-confirmed{background:var(--altavex-green);border:1px solid var(--altavex-green)}
.sq-exec{border:1px solid var(--champagne-bronze);background:rgba(176,141,87,.15)}
.sq-human{border:1px solid var(--warm-bone);background:transparent}
.sq-blocked{border:1px solid var(--muted-titanium);background:repeating-linear-gradient(45deg,transparent,transparent 2px,rgba(102,113,116,.35) 2px,rgba(102,113,116,.35) 4px)}

/* --- Evidence ledger rows --- */
.avx-ledger{border:1px solid var(--carbon-border);border-radius:14px;overflow:hidden;background:var(--graphite-panel)}
.avx-ledger .lg-row{display:grid;grid-template-columns:1.4fr .9fr .9fr 1fr;gap:12px;align-items:center;padding:14px 18px;border-top:1px solid var(--carbon-border);font-size:13.5px;color:var(--soft-bone)}
.avx-ledger .lg-row:first-child{border-top:none}
.avx-ledger .lg-head{background:var(--elevated-graphite);font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--titanium)}
.lg-state{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;display:inline-flex;align-items:center;gap:7px}
.lg-state.requested{color:var(--titanium)}
.lg-state.pending{color:var(--titanium)}
.lg-state.confirmed{color:var(--altavex-green)}
.lg-state.human{color:var(--warm-bone)}
.lg-state.suppressed{color:var(--muted-titanium)}
.lg-receipt{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--champagne-bronze)}
@media(max-width:760px){.avx-ledger .lg-row{grid-template-columns:1fr 1fr;row-gap:6px}}

/* --- Kinetic/entrance motion: run-once, transform+opacity only --- */
.avx-rise{opacity:0;transform:translateY(10px);transition:opacity .6s ease,transform .6s ease}
.avx-rise.in{opacity:1;transform:none}
.avx-kinetic-swap{display:inline-block;transition:opacity .26s ease;color:var(--altavex-green)}

/* --- Proof state sequence (REQUESTED → PENDING → CONFIRMED) --- */
.state-seq{display:flex;gap:14px;flex-wrap:wrap;font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.state-seq .st{color:var(--titanium);opacity:.5;transition:opacity .4s,color .4s}
.state-seq .st.on{opacity:1}
.state-seq .st.ok{color:var(--altavex-green);opacity:1}
.state-seq .st.rc{color:var(--champagne-bronze);opacity:1}

/* --- Section rhythm helpers --- */
.avx-fullwidth-statement{padding:110px 0 90px;text-align:left}
.avx-split{display:grid;grid-template-columns:1.05fr .95fr;gap:40px;align-items:center}
@media(max-width:860px){.avx-split{grid-template-columns:1fr;gap:24px}}
.avx-asym{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:14px}
@media(max-width:980px){.avx-asym{grid-template-columns:1fr 1fr}}
@media(max-width:620px){.avx-asym{grid-template-columns:1fr}}
.avx-asym .feat{grid-row:span 2}
@media(max-width:980px){.avx-asym .feat{grid-row:auto}}

/* --- Reduced motion (global, spec-mandated) --- */
@media (prefers-reduced-motion:reduce){
  .avx-rise{opacity:1!important;transform:none!important;transition:none!important}
  .avx-kinetic-swap{transition:none!important}
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}
}
/* --- Mobile: lighter treatment --- */
@media(max-width:640px){
  .section-ghost-word{font-size:clamp(60px,18vw,110px);opacity:.8}
  .avx-bg-node-field,.avx-bg-command{background-size:150px 150px}
}

/* ===== AVX mobile hamburger navigation ===== */
.avx-hamburger{display:none;background:none;border:1px solid rgba(233,236,232,.18);border-radius:8px;padding:9px 10px;margin-left:10px;cursor:pointer;flex-direction:column;gap:4px;align-items:center;justify-content:center;min-width:42px;min-height:38px}
.avx-hamburger:focus-visible{outline:2px solid var(--altavex-green,#28e884);outline-offset:2px}
.avx-hb-line{display:block;width:18px;height:2px;background:var(--soft-bone,#e9ece8);border-radius:1px;transition:transform .18s ease,opacity .18s ease}
.avx-hamburger.is-open .avx-hb-line:nth-child(1){transform:translateY(6px) rotate(45deg)}
.avx-hamburger.is-open .avx-hb-line:nth-child(2){opacity:0}
.avx-hamburger.is-open .avx-hb-line:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
.avx-mobile-menu{position:absolute;top:100%;left:0;right:0;background:rgba(10,12,11,.98);border-bottom:1px solid rgba(233,236,232,.12);box-shadow:0 18px 40px rgba(0,0,0,.55);padding:10px 20px 22px;z-index:120}
.avx-mm-links{display:flex;flex-direction:column}
.avx-mm-links a{display:block;padding:13px 6px;color:var(--soft-bone,#e9ece8);text-decoration:none;font-size:16px;border-bottom:1px solid rgba(233,236,232,.08)}
.avx-mm-links a[aria-current="page"]{color:var(--altavex-green,#28e884)}
.avx-mm-links a:focus-visible{outline:2px solid var(--altavex-green,#28e884);outline-offset:-2px}
.avx-mm-ctas{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.avx-mm-ctas .btn{text-align:center;justify-content:center}
html.avx-menu-open{overflow:hidden}
nav.nav{position:relative}
@media(max-width:1000px){
  .avx-hamburger{display:inline-flex}
}
@media(min-width:1001px){
  .avx-mobile-menu{display:none!important}
}
/* Mobile nav bar fit: keep one primary CTA + burger fully visible */
@media(max-width:640px){
  .nav-actions .navsched{display:none}
  .nav-actions .btn-primary{padding:10px 14px;font-size:13px}
}
.avx-mobile-menu{background:#0a0c0b}

/* ============================================================
   VISUAL SYSTEM RECONCILIATION — Jul 31 2026
   The shipped stylesheet above uses unprefixed token names
   (--obsidian, --warm-bone, ...). The Jul 31 handoff sheet uses
   --avx-* names and adds three pieces the shipped sheet lacks:
   .title-proof state colours, .avx-state chips, and title depth.
   This block aliases the --avx-* contract onto the shipped values
   and adds only the missing rules. No shipped rule is overridden,
   so importing it cannot regress a page that already renders.
   ============================================================ */
:root{
  /* --avx-* aliases → shipped spec values (same hexes, new names) */
  --avx-obsidian:var(--obsidian);
  --avx-deep-carbon:var(--deep-carbon);
  --avx-graphite:var(--graphite-panel);
  --avx-graphite-elev:var(--elevated-graphite);
  --avx-carbon-border:var(--carbon-border);
  --avx-border-2:rgba(38,48,51,.55);
  --avx-bone:var(--warm-bone);
  --avx-bone-soft:var(--soft-bone);
  --avx-titanium:var(--titanium);
  --avx-titanium-muted:var(--muted-titanium);
  --avx-ink:var(--near-black-ink);
  --avx-green:var(--altavex-green);
  --avx-green-mid:var(--mid-green);
  --avx-green-deep:var(--deep-green);
  --avx-green-hi:var(--highlight-green);
  --avx-bronze:var(--champagne-bronze);
  --avx-bronze-deep:var(--deep-bronze);
  --avx-champagne:var(--light-champagne);
  --avx-danger:#FF8F6B;

  /* Title depth — verbatim from the spec */
  --avx-title-shadow:0 1px 0 rgba(0,0,0,.55), 0 12px 34px rgba(0,0,0,.45);
  --avx-title-shadow-active:0 1px 0 rgba(0,0,0,.55), 0 12px 34px rgba(0,0,0,.45),
    0 0 26px rgba(40,232,132,.16);
}

/* ============================================================
   CONNECTOR-LINE & NODE HIERARCHY (Jason, Aug 1 — doc 11)
   Green reads as movement THROUGH the system, not a coat ON it.
   Shared tokens + reusable state classes — never page-by-page overrides.
     default/idle  muted titanium #667174 @ ~32%, no glow
     active path   green #28E884 @ ~72%, restrained glow
     confirmed     green 100% — a SINGLE endpoint, never the whole diagram
     authority     champagne bronze #B08D57, no glow
   ============================================================ */
:root{
  --avx-conn-idle:#667174;            /* muted titanium — GRAPHICS ONLY (stroke/border/background) */
  /* The doctrine picked #667174 as a STROKE colour, but 10 rules were applying it
     with `color:` to real words — the "01 Trigger / 02 Nova / 03 Qualify / 04 Book"
     labels on all 12 industry strips, plus step numerals on business-ai-operations,
     what-we-do, why-altavex and revenue-system. As text it measures 3.84:1 on the
     body and 3.61:1 on panels, below the WCAG AA 4.5:1 floor for small text.
     A decorative 1px stroke has no contrast obligation; a 10px word does.
     #7C888B is the nearest tone to the doctrine value that clears AA on all three
     backgrounds (5.28 / 4.96 / 5.50:1), so idle labels stay recessive and clearly
     un-lit while remaining legible. Graphic strokes keep #667174 exactly. */
  --avx-conn-idle-text:#7C888B;       /* idle LABELS — AA-safe counterpart of --avx-conn-idle */
  --avx-conn-idle-op:.32;             /* 25–40% */
  --avx-conn-active:#28E884;          /* altavex green */
  --avx-conn-active-op:.72;           /* 60–80% */
  --avx-conn-authority:#B08D57;       /* champagne bronze */
  --avx-node-border:#263033;          /* carbon border */
  --avx-glow-active:0 0 6px rgba(40,232,132,.26);  /* restrained; ~50% of old */
}
/* SVG connector paths/lines. NOTE: the site currently ships zero inline <svg>,
   so these match nothing today — kept verbatim per spec for future SVG work.
   DOM connectors use the .avx-dom variant below. */
.avx-connector{stroke:var(--avx-conn-idle);stroke-opacity:var(--avx-conn-idle-op);filter:none;
  transition:stroke .3s,stroke-opacity .3s,filter .3s}
.avx-connector.is-active{stroke:var(--avx-conn-active);stroke-opacity:var(--avx-conn-active-op);
  filter:drop-shadow(var(--avx-glow-active))}
.avx-connector.is-confirmed{stroke:var(--avx-conn-active);stroke-opacity:1}      /* endpoint segment only */
.avx-connector.is-authority{stroke:var(--avx-conn-authority);stroke-opacity:.8;filter:none}

/* Non-SVG connectors (div/span rules and lines) */
.avx-connector.avx-dom{background:var(--avx-conn-idle);opacity:var(--avx-conn-idle-op);box-shadow:none}
.avx-connector.avx-dom.is-active{background:var(--avx-conn-active);opacity:var(--avx-conn-active-op);box-shadow:var(--avx-glow-active)}
.avx-connector.avx-dom.is-confirmed{background:var(--avx-conn-active);opacity:1;box-shadow:none}
.avx-connector.avx-dom.is-authority{background:var(--avx-conn-authority);opacity:.8;box-shadow:none}

/* Nodes / cards / step markers.
   IMPORTANT: colour-only, never the `border` shorthand. Using the shorthand here
   reset border-top-width/color and silently destroyed components that carry their
   own accent stripe (e.g. .rp-step's 2px top border). Width and style stay with
   the component; .avx-node only decides WHICH state colour it wears. Likewise no
   `box-shadow:none`, which was wiping legitimate neutral depth shadows.
   The idle case deliberately sets NO border-color at all: components already ship
   a carbon/titanium idle border, and `border-color` here would flatten any accent
   stripe (e.g. .rp-step's 2px top edge) that the component sets on one side only.
   Idle = leave it alone; the state classes are the only thing that repaints. */
.avx-node{transition:border-color .3s,box-shadow .3s}
.avx-node.is-active{border-color:var(--avx-conn-active);box-shadow:var(--avx-glow-active)}
.avx-node.is-confirmed{border-color:var(--avx-conn-active)}
.avx-node.is-authority{border-color:var(--avx-conn-authority)}

/* Idle nodes read muted titanium (the connector token, not the looser palette
   --titanium, so the doctrine value is authoritative for connector graphics).
   Scoped with :not() so it can never leak into CTAs, eyebrows or headline accents. */
.avx-node:not(.is-active):not(.is-confirmed):not(.is-authority){color:var(--avx-conn-idle-text,#7C888B)}
.avx-node.is-authority{color:var(--avx-conn-authority)}

@media(prefers-reduced-motion:reduce){.avx-connector,.avx-node{transition:none}}

/* ============================================================
   HERO & IMAGE-PROTECTION CLASSES (Execution Authority §4 / doc 11)
   Shared, opt-in utilities. None were previously defined; nothing in the HTML
   references them yet, so adding them cannot regress an existing page.
   ============================================================ */
/* Pattern A — split screen: text on solid carbon, image beside */
.avx-hero-split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,4vw,56px);align-items:center}
@media(max-width:760px){.avx-hero-split{grid-template-columns:1fr}}

/* Pattern B — copy safe zone (45–55%) when imagery sits behind */
.avx-hero-safe-left{position:relative;z-index:2;max-width:54%}
.avx-hero-safe-right{position:relative;z-index:2;max-width:54%;margin-left:auto}
@media(max-width:760px){.avx-hero-safe-left,.avx-hero-safe-right{max-width:100%;margin:0}}

/* 85–95% Obsidian protection gradient behind overlaid copy */
.avx-copy-protection{position:relative}
.avx-copy-protection::before{content:"";position:absolute;inset:0 -24px;z-index:-1;pointer-events:none;
  background:linear-gradient(90deg,rgba(5,8,10,.93),rgba(5,8,10,.86) 45%,rgba(5,8,10,0) 72%)}
.avx-copy-protection.is-right::before,.avx-hero-safe-right .avx-copy-protection::before{
  background:linear-gradient(270deg,rgba(5,8,10,.93),rgba(5,8,10,.86) 45%,rgba(5,8,10,0) 72%)}

/* Pattern C — image below copy on mobile */
@media(max-width:760px){
  .avx-hero-image-below-mobile{display:flex;flex-direction:column}
  .avx-hero-image-below-mobile>.avx-hero-media{order:2;margin-top:20px}
  .avx-hero-image-below-mobile>.avx-hero-copy{order:1}}

/* Editorial image card + protection overlay for any overlaid caption */
.avx-image-card{position:relative;overflow:hidden;border-radius:16px;border:1px solid var(--avx-carbon-border,#263033);background:#0A0F11}
.avx-image-card img{display:block;width:100%;height:100%;object-fit:cover}
.avx-image-card-protection::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(5,8,10,0) 40%,rgba(5,8,10,.72))}

/* Image fit / emphasis tiers. FLAGGED IN SPEC as an interpretation of intent
   (featured = 16:9 landscape, strong = 4:5 portrait) — confirm with Jason.
   Deliberately avx- prefixed: industries.html already uses .fit-featured /
   .fit-strong for tier RIBBON labels and must not receive an aspect-ratio. */
.avx-fit-featured{aspect-ratio:16/9}
.avx-fit-strong{aspect-ratio:4/5}
@media(max-width:760px){.avx-fit-featured,.avx-fit-strong{aspect-ratio:16/10}}

/* Mono utility (shipped sheet styles .avx-signal-label but not .avx-mono) */
.avx-mono{font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace}

/* Title depth applied to the display ladder */
.avx-display,.avx-statement{text-shadow:var(--avx-title-shadow)}
.title-signal.is-active{text-shadow:var(--avx-title-shadow-active)}

/* Title system 1 — signal: bone setup, green result */
.title-signal .result,.title-signal .accent,.title-signal b{color:var(--avx-green)}

/* Title system 2 — authority: bone + champagne accent */
.title-authority .accent,.title-authority b{color:var(--avx-champagne)}

/* Title system 3 — proof: titanium unconfirmed / green confirmed / bronze receipt */
.title-proof{font-family:"IBM Plex Mono",ui-monospace,monospace;letter-spacing:.06em}
.title-proof .st-unconfirmed{color:var(--avx-titanium)}
.title-proof .st-confirmed{color:var(--avx-green)}
.title-proof .st-receipt{color:var(--avx-bronze)}
.title-proof .noclaim{color:var(--avx-bronze);font-weight:700;letter-spacing:.04em}

/* Operational state chips */
.avx-state{display:inline-block;font:700 10px/1 "IBM Plex Mono",ui-monospace,monospace;
  letter-spacing:.05em;text-transform:uppercase;padding:5px 9px;border-radius:6px}
.avx-state.req{background:rgba(124,134,138,.18);color:var(--avx-bone-soft)}
.avx-state.pending{background:rgba(176,141,87,.14);color:var(--avx-bronze)}
.avx-state.confirmed{background:rgba(40,232,132,.16);color:var(--avx-green)}
.avx-state.suppressed{background:rgba(255,143,107,.10);color:var(--avx-danger)}

/* Ghost words: hard cap at .02 per spec, regardless of authoring */
.section-ghost-word{opacity:.02!important;color:#fff}

/* ---- bg-footer-foundation: calm obsidian footer geometry ----
   The only one of the spec's six reusable backgrounds with no live plate.
   Static by design: the footer is a foundation, nothing travels here. */
.avx-footer-foundation{position:relative;background-color:var(--avx-obsidian);
  background-image:url('images/avx-footer-foundation.svg?v=20260803c');
  background-repeat:no-repeat;background-position:center bottom;background-size:cover}
.avx-footer-foundation>*{position:relative;z-index:1}
.avx-footer-foundation::before{content:"";position:absolute;inset:0;z-index:0;
  background:linear-gradient(180deg,rgba(5,8,10,.55) 0%,rgba(5,8,10,.88) 70%,var(--avx-obsidian) 100%);
  pointer-events:none}

/* Motion discipline: no infinite animation anywhere in the visual system,
   and everything decorative stops under reduced-motion. */
@media(prefers-reduced-motion:reduce){
  .title-signal,.title-authority,.avx-state{transition:none!important;animation:none!important}
  .avx-footer-foundation{background-image:none}
}


/* ==========================================================================
   R3 mobile tap-target floor (added 2026-07-31)
   WCAG 2.5.8 Target Size (Minimum) asks for 24x24; Apple HIG and WCAG 2.5.5
   Enhanced ask for 44x44. Preview measurement at 390px found conversion-critical
   controls between 19px and 42px tall. Raising to a 44px floor.
   Scoped to <=760px: desktop rendering is deliberately untouched.
   Appended as a guarded block -- overrides nothing above.
   ========================================================================== */
@media (max-width: 760px) {
  /* Primary + secondary CTAs. 42px -> 44px. */
  .btn,
  a.btn,
  button.btn,
  .avx-mm-ctas .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Mobile nav toggle. Was 38px and is the entry point to the whole menu.
     NOTE: do NOT use min-width here. The nav .container reserves a 14px gutter
     and .avx-hamburger carries margin-left:10px, so forcing a 44px horizontal
     minimum pushed the right edge to 388px and overflowed 375/360 viewports.
     Gain the touch area from padding + min-height instead, per the icon-button
     guidance: icon stays visually restrained, hit area meets 44px. */
  .avx-hamburger {
    min-height: 44px;
    min-width: 0;
    padding: 11px 12px;
    box-sizing: border-box;
  }
  /* Keep the three icon lines visually small regardless of the larger hit box. */
  .avx-hamburger .avx-hb-line {
    width: 18px;
  }

  /* "Back to top" was 19px -- the worst offender on the page. */
  .avx-continuation .top,
  a.top {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 0 4px;
  }

  /* Contact links in the footer: phone, sales, support. Were 33px. */
  footer a[href^="tel:"],
  footer a[href^="mailto:"],
  .foot-links a,
  .foot-col a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  /* Section-rail / continuation destination links. Were 34px. */
  .avx-section-rail a,
  .avx-continuation a,
  .avx-mm-links a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  /* Inline text CTAs such as "Discuss a Custom Build" (was 22px). */
  a.link2 {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}



/* ==========================================================================
   R3 compliance-adjacent legibility floor (2026-07-31)

   Owner directive: consent, limitation, pricing-qualifier and other
   compliance-adjacent copy must not use micro-label sizing. Floor is 12.5px.

   Deliberately NOT touched: decorative eyebrow / kicker / signal labels
   ("SYSTEM ACTIVE", "Trigger", "Start here", "What Nova does") which are the
   intended editorial type system at 10-11.5px.
   ========================================================================== */

/* "Illustrative workflow - the path every conversation follows." Was 10px.
   This qualifies what the diagram represents, so it is a disclaimer. */
.wnote {
  font-size: 12.5px !important;
  line-height: 1.5;
}

/* Plan contract term - "Month-to-month - 30-day cancellation". Was 11px.
   This is the canonical term surfaced by avx-pricing-render.js; it should not
   read as small print. */
.avx-plan-term {
  font-size: 12.5px !important;
  line-height: 1.45;
}

/* Trust-strip items flagged as compliance statements: "AI identification &
   disclosures", "Consent-gated messaging". Was 11px. */
.trust-strip .b {
  font-size: 12.5px !important;
}

/* Any consent checkbox label, wherever it appears. Defensive: catches forms
   added later so consent copy can never regress below the floor. */
label:has(input[type="checkbox"][name^="consent"]),
label.avx-consent,
.avx-consent label {
  font-size: 12.5px !important;
  line-height: 1.5;
}

/* Illustrative / "runs once" run-once markers that carry a qualifier. */
.avx-runonce-note,
.bt .runonce,
span.avx-illustrative {
  font-size: 12.5px !important;
}

/* ---------------------------------------------------------------------------
   R3 nav flex fit (2026-07-31)

   At a 360px viewport the nav row overflowed by exactly 10px:
     .container.nav-inner  right=346  (correct, inside the viewport)
     .avx-hamburger        right=370  (pushed past its own parent)

   Cause: the flex row's children + gap:18px + the button's own margin-left:10px
   exceeded the 332px container track, and nothing was allowed to shrink, so the
   last child was pushed out rather than the row compressing.

   The button's width (26px) is correct -- its 44px touch target comes from
   min-height + padding, not from width. So this is a placement fix, not a
   sizing fix, and it must not reduce the hit area.
   --------------------------------------------------------------------------- */
@media (max-width: 760px) {
  /* The widest flexible child; let it give ground instead of pushing siblings out. */
  .nav .container.nav-inner > .nav-actions {
    min-width: 0;
    flex-shrink: 1;
  }
  /* The container already supplies gap:18px. The extra margin-left double-spaced
     the row and was what tipped it over the edge at 360. */
  .nav .container.nav-inner > .avx-hamburger {
    margin-left: 0;
    flex-shrink: 0;   /* never shrink the tap target itself */
  }
  /* Tighten the row gap slightly at the narrowest widths so all three children
     (brand, actions, toggle) fit the 332px track without clipping. */
  .nav .container.nav-inner {
    gap: 10px;
  }

  /* `.nav-actions` shrinking is not sufficient on its own: the flex ITEM narrows
     (156px at 360) but its `.btn-primary` child keeps its intrinsic 172px width
     and simply overhangs, so the button's painted right edge (308) crossed the
     hamburger's left edge (302) -- a 6px ambiguous-tap strip that produced no
     scroll overflow and no clipping, and so passed every prior assertion.
     Allow the button itself to give ground; the 44px touch floor comes from
     min-height, so narrowing the width does not weaken the tap target. */
  .nav .container.nav-inner > .nav-actions {
    overflow: hidden;
  }
  .nav .container.nav-inner .nav-actions .btn,
  .nav .container.nav-inner .nav-actions .btn-primary {
    min-width: 0;
    flex-shrink: 1;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ---------------------------------------------------------------------------
   R3 tap-target height floor (2026-07-31)

   Owner directive: every interactive target >= 44x44 touch area.

   Measured at 390px/isMobile after full-page scroll, all short on HEIGHT only
   (widths were already 85-221px):
     34px  .avx-secnav li > a          section rail links
     40px  .dest                       mobile menu destinations
     40px  .haccess-btns .btn          accessibility bar buttons
     42px  .nav-actions .btn-primary   "Find My Revenue Gaps"
     16px  .reach-emails a             standalone sales@/support@ contact links

   Uses min-height + inline-flex centring instead of raw vertical padding so text
   stays optically centred and no baseline shifts.

   Inline links inside prose sentences are deliberately NOT enlarged -- WCAG 2.5.8
   excludes inline text links, and padding them breaks line rhythm.
   --------------------------------------------------------------------------- */

/* Section rail: 34 -> 44. This makes the rail taller on mobile (visible change,
   flagged for review) but the links are primary navigation and must be tappable. */
.avx-secnav li > a,
.avx-secnav ul li a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
}

/* Mobile menu destinations: 40 -> 44 */
.dest {
  min-height: 44px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

/* Accessibility bar buttons: 40 -> 44 */
.haccess-btns .btn,
.haccess .btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

  /* Primary nav CTA: 42 -> 44 */
.nav-actions .btn,
.nav-actions .btn-primary {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

/* REGRESSION GUARD (2026-07-31)
   The rule above is unmediated, so its `display:inline-flex` overrode
   `@media(max-width:640px){.nav-actions .navsched{display:none}}` on specificity
   (0,2,0 beats 0,2,0 by source order -- the tap-target block is appended later).
   That resurrected the "Schedule" secondary button at <=640px, pushing
   "Find My Revenue Gaps" from right:316 to right:412 in a 360px viewport, where
   it painted over the hamburger and was clipped mid-word.

   The nav is width-constrained, so this never produced horizontal SCROLL --
   maxScrollX stayed 0 and every overflow assertion passed while the nav was
   visibly broken. Re-assert the hide with matching media scope. */
@media (max-width: 640px) {
  .nav-actions .navsched,
  .nav-actions .btn.navsched,
  .nav-actions .btn-secondary.navsched {
    display: none !important;
  }
}

/* Standalone contact links (sales@ / support@): 16px inline -> 44px touch area.
   These are list items, not prose, so a block touch area is correct here. */
.reach-emails a,
.reach-emails li > a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
}

/* Belt-and-braces: any footer/nav list link that is still a bare inline box gets
   a 44px touch height. Scoped to list contexts so prose links are untouched. */
@media (max-width: 900px) {
  .foot-col li > a,
  .footer-nav li > a,
  .mobilebar a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
  }
}

/* ---------------------------------------------------------------------------
   R3 demo-widget tap targets (2026-07-31)

   The remaining sub-44px controls, all inside the Nova demo widgets. These are
   the primary interaction surface of the product demo, so they matter more than
   chrome links: a prospect taps these to see Nova work.

   Measured at 390px/isMobile, unclassed buttons targeted via container:
     27px  button.nseq-replay   "Replay sequence"        (sequence player)
     35px  .flowpick > button   6 scenario chips
     40px  .gopts > button      6 operating-lane cards

   Height-only fixes via min-height + flex centring.
   --------------------------------------------------------------------------- */

/* Sequence player replay control: 27 -> 44 (worst offender on the site) */
button.nseq-replay,
.nseq-replay {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

/* Nova scenario chips: 35 -> 44 */
.flowpick > button,
.flowpick button {
  min-height: 44px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

/* Operating-lane selector cards: 40 -> 44 */
.gopts > button,
.gopts button {
  min-height: 44px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

/* ---------------------------------------------------------------------------
   R3 tap-target closeout (2026-07-31)

   Final sweep against the Preview build. The preceding blocks cleared the
   nav, footer contact, demo-widget and CTA controls; these are the remaining
   sub-44px targets measured at 390px/isMobile after full-page scroll.

     36px  .opts button              33 answer chips on /ai-operations-assessment
     36px  .actions .btn             "See recommended modules" / "Discuss a
                                     custom build" / "Discuss an AI Operations
                                     Blueprint" -- the page's conversion exits
     42px  details.avx-drawer>summary  "See what we map" (/)
     43px  .avx-drawer summary        "Show calculation details" (/pricing)
     40px  .foot-col a                "Terms" and siblings, 11 pages

   Height-only corrections via min-height + flex centring, consistent with the
   blocks above: no font-size, colour, padding-x or layout changes, so the
   desktop composition and the mobile visual rhythm are unchanged.
   --------------------------------------------------------------------------- */
@media (max-width: 760px) {
  /* Assessment answer chips. These ARE the assessment -- a prospect taps 33 of
     them to reach a recommendation, so they are conversion-critical. The pill
     shape and 13.5px label are preserved; only the touch height grows. */
  .opts button,
  .opts > button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
  }

  /* Assessment / result action buttons. The page defines its own .btn at
     14px 22px padding, which lands at 36px; the sitewide .btn floor above does
     not reach it because this page's rule is more specific. */
  .actions .btn,
  .actions button.btn,
  .actions a.btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
  }

  /* Disclosure drawers. The summary is the only control that opens the panel,
     so it must be tappable; the marker and mono label are left alone. */
  details.avx-drawer > summary,
  .avx-drawer summary {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
  }
}

/* Footer column links resolved to 40px because styles.css sets
   `.foot-col a{display:block;padding:5px 0}` -- a block box with 14px/1.4 text
   plus 10px padding. The earlier rule at <=900px set min-height but `display:
   inline-flex` on a block-level anchor in a stacked column did not reliably
   win over the base declaration order. Raising the padding gives the same 44px
   result without depending on display resolution, and keeps the links visually
   identical (same font, same colour, same left alignment). */
@media (max-width: 900px) {
  .foot-col a {
    min-height: 44px;
    padding-top: 10px;
    padding-bottom: 10px;
    box-sizing: border-box;
  }

  /* Height is now 44px, but short labels ("Terms" 38px, "Pricing" 43px)
     are still narrow. min-width would reserve a 44px box for every link and
     is harmless in a stacked column, but it would also widen the flex line
     box; because these are inline-flex in a block column the safer expression
     of the same touch area is a horizontal pad that does not shift the text
     origin. `padding-right` grows the hit box to the right, into empty column
     space, so the left alignment of the whole footer list is preserved. */
  .foot-col a {
    min-width: 44px;
    padding-right: 8px;
  }
}

/* ---- avx-grid-2x2: balanced 2x2 for 4-item card sets (added 2026-08-01) ----
   Replaces `repeat(auto-fit,minmax(240px,1fr))` on 4-item grids. Inside a 900px
   container with a 32px gap, auto-fit resolved to 3 columns, laying 4 items out
   as 3+1 and leaving a measured 621px void beside the orphan at >=1024px.
   Explicit: one column on narrow, exactly two from 720px up. */
.avx-grid-2x2{display:grid;grid-template-columns:minmax(0,1fr)}
@media(min-width:720px){
  .avx-grid-2x2{grid-template-columns:repeat(2,minmax(0,1fr))}
}
