/* ==========================================================================
   mo.css - MissionOaks.dev, LLC
   The entire stylesheet for the one-page site. Nothing else is loaded.
   --------------------------------------------------------------------------
   READ THIS FIRST.

   This file is mobile-first. The :root token values are the SMALL-screen
   values and min-width queries widen them. hex.tech (whose measured layout
   rhythm this reproduces) is desktop-first with max-width queries at
   1250/800/600/450; those have been re-expressed here as min-width queries at
   451/601/801/1251 so the cascade runs small -> large. The computed value at
   every viewport width is identical to hex's. Do NOT "simplify" these back
   into max-width queries - the cascade order is what makes them equivalent.

   PROVENANCE. Layout, glass and motion numbers were read out of hex.tech's
   live CSS, not eyeballed. The green palette is the approved translation in
   .claude/tasks/one-page-hex-redesign.md section 3. Every token is --mo-.

   CONTRAST. Ratios quoted in comments are computed, not guessed. The single
   most important one: #14A876 on the page background is 2.92:1, which fails
   even the 3:1 non-text floor. Accent green is therefore restricted to FILLS
   (where its own foreground, --mo-on-accent, gives 5.88:1) and to the dark
   panel. Anything green that must be read on a light ground uses
   --mo-accent-deep #0f6b5b (6.15:1 on --mo-bg, 6.41:1 on white).

   TABLE OF CONTENTS
     1.  Tokens
     2.  Responsive token overrides
     3.  Dark-panel theme scope
     4.  Reset and base
     5.  Utilities
     6.  Buttons
     7.  Nav
     8.  Hero
     9.  Section shell
     10. Feature rows
     11. Visual cards
     12. Proof strip
     13. Dark panel (OzyOps)
     14. FAQ accordion
     15. Contact and form
     16. Footer
     17. Reduced motion
     18. Print
   ========================================================================== */


/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {

  /* ---- 1.1 Core palette - approved, plan section 3 ---------------------- */
  --mo-bg:                  #fbfaf8;   /* hex opal #fbf9f9, warmed            */
  --mo-surface:             #ffffff;
  --mo-ink:                 #0b1a14;   /* hex black #01011b, green-cast       */
  --mo-ink-muted:           #5a6b63;   /* hex cement #717a94, green-cast      */
  --mo-accent:              #14A876;   /* MissionOaks brand green             */
  --mo-accent-deep:         #0f6b5b;   /* hex's own --appUI-intent-success    */
  --mo-accent-lite:         #43d59d;   /* hex --colorVars-lightGreen verbatim */
  --mo-panel:               #0c211a;   /* replaces hex obsidian #14141c       */
  --mo-border:              #e4e8e5;

  /* ---- 1.2 Derived palette - each value hits a contrast target ---------- */
  --mo-accent-hover:        #13a171;   /* --mo-on-accent on it = 5.43:1       */
  --mo-accent-active:       #12996b;   /* --mo-on-accent on it = 4.94:1       */
  --mo-on-accent:           #0b1a14;   /* text/icon ON any accent fill = 5.88:1 on #14A876.
                                          NEVER re-point this in the dark theme block. */
  --mo-tint:                #edf6f2;   /* faint green wash: hover fills, bands */
  --mo-tint-strong:         #dff0e8;
  --mo-border-strong:       #7d8d86;   /* 3.34:1 on --mo-bg, 3.48:1 on white - the ONLY
                                          border allowed on a form control or any
                                          boundary that carries meaning (WCAG 1.4.11) */
  --mo-danger:              #b3261e;   /* 6.54:1 on white - validation errors */

  /* dark-panel family */
  --mo-panel-surface:       #112b22;   /* inset card inside the dark panel */
  --mo-panel-ink:           #e8f0ec;   /* 14.51:1 on --mo-panel */
  --mo-panel-muted:         #a9bdb4;   /*  8.51:1 on --mo-panel */
  --mo-panel-border:        #234a3d;   /*  1.70:1 - DECORATIVE hairlines only */
  --mo-panel-border-strong: #4f7a69;   /*  3.46:1 - control boundaries */

  /* ---- 1.3 Alpha ramp (hex --fgA* pattern, re-cast onto --mo-ink) ------- */
  --mo-a-03:  rgba(11, 26, 20, 0.03);
  --mo-a-05:  rgba(11, 26, 20, 0.05);
  --mo-a-06:  rgba(11, 26, 20, 0.06);
  --mo-a-09:  rgba(11, 26, 20, 0.09);
  --mo-a-14:  rgba(11, 26, 20, 0.14);
  --mo-a-22:  rgba(11, 26, 20, 0.22);
  --mo-a-32:  rgba(11, 26, 20, 0.32);
  --mo-accent-a-08: rgba(20, 168, 118, 0.08);
  --mo-accent-a-16: rgba(20, 168, 118, 0.16);
  --mo-accent-a-30: rgba(20, 168, 118, 0.30);

  /* ---- 1.4 Layout rhythm - hex measured -------------------------------- */
  --mo-max-width:    1240px;  /* --home-section-max-width */
  --mo-gutter:         20px;  /* --home-section-gutter, small end */
  --mo-section-pad:    40px;  /* --home-section-padding-block, small end */
  --mo-col-gap:        40px;  /* --home-section-column-gap, small end */
  --mo-row-gap:        60px;  /* --home-section-row-gap */
  --mo-copy-max:      425px;  /* --home-section-copy-max-width */
  --mo-prose-max:     650px;  /* hex .HomeHero__Description max-width */
  --mo-faq-max:       604px;  /* hex .FAQ__Inner max-width */
  --mo-nav-h:          60px;  /* hex .ClientNav__NavPlaceholder 3.75rem */

  /* ---- 1.5 Glass - hex --home-glass-* with the surface swapped ---------- */
  --mo-glass-blur:      7.5px;
  --mo-glass-surface:   #fdfdfd;
  /* hex's literal 40% value, kept for reference. It is NOT applied to the nav:
     over the dark .mo-panel it drops the nav links to ~2:1. See the note at
     .mo-nav--scrolled before using it anywhere text sits on top. */
  --mo-glass-bg:        color-mix(in srgb, var(--mo-glass-surface) 40%, transparent);
  --mo-glass-bg-solid:  rgba(253, 253, 253, 0.86);
  --mo-glass-ring:      0 0 0 1px var(--mo-a-06);
  --mo-glass-shadow:
      0 16px 24px -8px var(--mo-a-05),
      0 8px 12px -4px var(--mo-a-05),
      0 4px 6px -2px var(--mo-a-05),
      var(--mo-glass-ring),
      inset 0 0 11px 0 var(--mo-a-05);

  /* ---- 1.6 Elevation --------------------------------------------------- */
  --mo-shadow-surface:
      0 0 0 1px var(--mo-a-22),
      0 26px 57px 0 var(--mo-a-05),
      0 103px 103px 0 var(--mo-a-03);
  --mo-shadow-surface-hover:
      0 0 0 1px var(--mo-a-32),
      0 26px 57px 0 rgba(11, 26, 20, 0.15),
      0 103px 103px 0 rgba(11, 26, 20, 0.12);
  --mo-shadow-nav: 0 1px 0 0 var(--mo-border), 0 8px 24px -14px var(--mo-a-09);

  /* ---- 1.7 Radii - hex marketing buttons are SQUARE --------------------- */
  --mo-r-0:     0;
  --mo-r-sm:    3px;
  --mo-r-md:    6px;    /* inner white surface (hex InteractiveFeatureWrapper) */
  --mo-r-lg:   12px;    /* glass card shell    (hex Card__Wrapper)            */
  --mo-r-pill: 999px;

  /* ---- 1.8 Type families - self-hosted from /webfonts/ via mo-fonts.css - */
  --mo-font-sans:  'Archivo', ui-sans-serif, system-ui, -apple-system,
                   'Segoe UI', Roboto, Arial, sans-serif;
  --mo-font-serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --mo-font-mono:  'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo,
                   Consolas, 'Liberation Mono', monospace;

  /* ---- 1.9 Fluid type scale -------------------------------------------- */
  /* LEARNING NOTE - how this clamp() works, and why the bounds are in rem.
     clamp(MIN, PREFERRED, MAX) picks PREFERRED unless it falls outside the
     bounds. The preferred term here is a straight line through two measured
     points: the small size at a 450px viewport and the large size at 1250px.
     (100vw - 450px) / 800 is 0 at 450px and 1 at 1250px, so multiplying it by
     the size difference and adding the floor interpolates smoothly between
     them - no breakpoints, no jumps.

     hex bounds their clamps in px. Ours are in rem. That is a deliberate
     accessibility divergence: a px floor ignores the reader's browser font
     size entirely, so someone who has set 24px as their default gets the same
     34px headline as everyone else (WCAG 1.4.4). rem bounds honour it. The
     vw term stays in px so the interpolation curve is unchanged. */
  --mo-step-6:  clamp(2.125rem,  calc(2.125rem  + (64 - 34) * ((100vw - 450px) / 800)), 4rem);       /* 34 -> 64  h1  */
  --mo-step-5:  clamp(1.75rem,   calc(1.75rem   + (46 - 28) * ((100vw - 450px) / 800)), 2.875rem);   /* 28 -> 46  h2  */
  --mo-step-4:  clamp(1.5rem,    calc(1.5rem    + (38 - 24) * ((100vw - 450px) / 800)), 2.375rem);   /* 24 -> 38  h2 sm */
  --mo-step-3:  clamp(1.25rem,   calc(1.25rem   + (28 - 20) * ((100vw - 450px) / 800)), 1.75rem);    /* 20 -> 28  h3  */
  --mo-step-2:  clamp(1.125rem,  calc(1.125rem  + (24 - 18) * ((100vw - 450px) / 800)), 1.5rem);     /* 18 -> 24  lede */
  --mo-step-1:  clamp(1.0625rem, calc(1.0625rem + (19 - 17) * ((100vw - 450px) / 800)), 1.1875rem);  /* 17 -> 19  body lg */
  --mo-step-0:    1rem;        /* 16px body                          */
  --mo-step--1:   0.875rem;    /* 14px UI, buttons, nav              */
  --mo-step--2:   0.8125rem;   /* 13px fine print, legal row         */
  --mo-step-mono: 0.75rem;     /* 12px mono labels (hex .annotation) */

  /* ---- 1.10 Type metrics ----------------------------------------------- */
  --mo-lh-h1:     1.08;
  --mo-lh-h2:     1.14;
  --mo-lh-h3:     1.25;
  --mo-lh-body:   1.6;
  --mo-lh-tight:  1.3;
  --mo-ls-h1:    -0.028em;
  --mo-ls-h2:    -0.026em;
  --mo-ls-h3:    -0.02em;
  --mo-ls-mono:   0.0833em;   /* hex .annotation letter-spacing, verbatim */
  --mo-wdth-display: 112;     /* Archivo wdth axis - semi-extended headline */
  --mo-wdth-sub:     106;
  --mo-wdth-ui:      100;

  /* ---- 1.11 Motion - hex --role-transition-* ---------------------------- */
  --mo-ease:          cubic-bezier(.25, .1, .25, 1);
  --mo-dur:           .18s;   /* --role-transition-duration */
  --mo-dur-slow:      .25s;   /* hex Button transition */
  --mo-dur-reveal:    .5s;
  --mo-reveal-shift:  12px;
  --mo-reveal-stagger: 60ms;

  /* ---- 1.12 Focus - hex --app-focus-outline ----------------------------- */
  --mo-focus-color:  var(--mo-accent-deep);   /* 6.15:1 on --mo-bg */
  --mo-focus-width:  2px;
  --mo-focus-offset: 2px;

  /* ---- 1.13 Z-index ----------------------------------------------------- */
  --mo-z-base:      0;
  --mo-z-raised:    1;
  --mo-z-sticky:   50;
  --mo-z-nav:     100;
  --mo-z-drawer:  110;
  --mo-z-skip:    200;

  /* ---- 1.14 Decorative patterns (hex GridLines, recoloured) ------------- */
  --mo-checker: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="4" height="4"><rect width="2" height="2" fill="%23e7ebe8"/><rect x="2" y="2" width="2" height="2" fill="%23e7ebe8"/></svg>');
  --mo-dotgrid: radial-gradient(circle at 1px 1px, var(--mo-a-06) 1px, transparent 0);
  --mo-dotgrid-size: 20px 20px;
}


/* ==========================================================================
   2. RESPONSIVE TOKEN OVERRIDES
   hex measured:  gutter 20/30/40 - section pad 40/60/80 - column gap 40/80
   ========================================================================== */

@media (min-width: 451px)  { :root { --mo-gutter: 30px; } }
@media (min-width: 601px)  { :root { --mo-section-pad: 60px; } }
@media (min-width: 801px)  { :root { --mo-gutter: 40px; --mo-section-pad: 80px; } }
@media (min-width: 1251px) { :root { --mo-col-gap: 80px; } }


/* ==========================================================================
   3. DARK-PANEL THEME SCOPE
   --------------------------------------------------------------------------
   LEARNING NOTE - this is the whole trick behind the OzyOps panel.
   Instead of writing per-component overrides (.mo-panel .mo-btn { ... }), the
   wrapper re-declares the SAME token names inside its own subtree. Every
   nested component reads --mo-ink, --mo-border, --mo-focus-color and so on
   without knowing anything about themes, and inverts for free. hex does
   exactly this with [data-theme='dark']. If you ever find yourself writing a
   descendant override for the panel, the token block below is missing
   something - add the token, not the override.

   NOTE WHAT IS DELIBERATELY ABSENT: --mo-on-accent. It must stay #0b1a14 so
   an accent-filled button keeps 5.88:1 inside the panel. Re-pointing it to
   --mo-panel-ink would silently drop that pair to 3.05:1 and fail AA, and it
   would still LOOK fine, which is exactly why it is written down here.
   ========================================================================== */

[data-mo-theme="dark"] {
  --mo-bg:            var(--mo-panel);   /* #0c211a - single source of truth */
  --mo-surface:       var(--mo-panel-surface);
  --mo-ink:           var(--mo-panel-ink);
  --mo-ink-muted:     var(--mo-panel-muted);
  --mo-border:        var(--mo-panel-border);
  --mo-border-strong: var(--mo-panel-border-strong);
  --mo-tint:          rgba(67, 213, 157, 0.08);
  --mo-focus-color:   var(--mo-accent-lite);   /* 9.01:1 on --mo-panel */
  --mo-a-05:          rgba(255, 255, 255, 0.05);
  --mo-a-06:          rgba(255, 255, 255, 0.07);
  --mo-a-22:          rgba(255, 255, 255, 0.16);
  color-scheme: dark;
}


/* ==========================================================================
   4. RESET AND BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  /* Never a px root size: the fluid scale's rem bounds exist precisely so the
     reader's own base font size is honoured (WCAG 1.4.4). */
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;                              /* switched off under reduced motion */
  scroll-padding-top: calc(var(--mo-nav-h) + 12px);     /* anchors clear the sticky nav */
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--mo-font-sans);
  font-weight: 400;          /* hex uses 300; Archivo 300 is fragile at 16px on an
                                off-white ground. Deliberate divergence. */
  font-stretch: 100%;
  font-size: var(--mo-step-0);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink);
  background: var(--mo-bg);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, p, ul, ol, figure, blockquote, hr { margin: 0; }
ul, ol { padding: 0; list-style: none; }
h1, h2, h3, h4 { text-wrap: balance; }
p { text-wrap: pretty; }

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

/* Global focus ring. :focus-visible so a mouse click does not paint a ring,
   but keyboard and assistive-tech focus always does. */
:focus-visible {
  outline: var(--mo-focus-width) solid var(--mo-focus-color);
  outline-offset: var(--mo-focus-offset);
}

::selection { background: var(--mo-tint-strong); color: var(--mo-ink); }


/* ==========================================================================
   5. UTILITIES
   ========================================================================== */

/* hex .annotation, verbatim metrics. IBM Plex Mono ships only 400 and 500 in
   /webfonts/ - asking for 600/700 makes the browser synthesise a fake bold. */
.mo-mono {
  font-family: var(--mo-font-mono);
  font-weight: 500;
  font-size: var(--mo-step-mono);
  letter-spacing: var(--mo-ls-mono);
  line-height: 1.571;
  text-transform: uppercase;
}

.mo-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.mo-container {
  width: 100%;
  max-width: var(--mo-max-width);
  margin-inline: auto;
  padding-inline: var(--mo-gutter);
}

.mo-skip-link {
  position: absolute;
  left: var(--mo-gutter);
  top: -100px;
  z-index: var(--mo-z-skip);
  background: var(--mo-surface);
  color: var(--mo-ink);
  border: 1px solid var(--mo-border-strong);
  border-radius: var(--mo-r-sm);
  padding: 10px 16px;
  font-size: var(--mo-step--1);
  font-weight: 550;
  text-decoration: none;
  transition: top var(--mo-dur) var(--mo-ease);
}
.mo-skip-link:focus { top: 8px; }

/* Shared check glyph used in every bulleted list. */
.mo-check {
  flex: none;
  width: 16px; height: 16px;
  margin-top: 0.36em;                /* optical alignment with the first text line */
  color: var(--mo-accent-deep);      /* 6.41:1 on white - well over the 3:1 floor */
}

/* The legal disclaimer carried over from the old site. Rendered as a distinct
   fine-print line with a hairline rule above it, not as a peer bullet, because
   it is a disclaimer and must read as one. */
.mo-disclaimer {
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--mo-border);
  font-size: var(--mo-step--2);
  line-height: 1.5;
  color: var(--mo-ink-muted);
}

/* ---- Scroll reveal -------------------------------------------------------
   LEARNING NOTE - the .mo-js scoping is a correctness decision, not a taste
   one. The opacity:0 base below only applies when <html> carries .mo-js, a
   class added by a single inline script in <head>. If JS is disabled, blocked
   by an extension, or throws before that line, the class never lands, this
   rule never matches, and the page renders fully visible. Without the scoping,
   a broken script leaves the visitor staring at a blank page.
   -------------------------------------------------------------------------- */
.mo-js .mo-reveal {
  opacity: 0;
  transform: translateY(var(--mo-reveal-shift));
  transition: opacity var(--mo-dur-reveal) var(--mo-ease),
              transform var(--mo-dur-reveal) var(--mo-ease);
  transition-delay: calc(var(--mo-reveal-i, 0) * var(--mo-reveal-stagger));
}
.mo-js .mo-reveal--in { opacity: 1; transform: none; }


/* ==========================================================================
   6. BUTTONS
   hex's marketing buttons are SQUARE - no radius at all. Do not round them.
   ========================================================================== */

.mo-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex: none;
  height: 48px;
  padding-inline: 20px;
  border-radius: var(--mo-r-0);
  border: 1px solid transparent;
  font-family: var(--mo-font-sans);
  font-weight: 500;
  font-stretch: 100%;
  font-size: var(--mo-step--1);
  line-height: 1;
  letter-spacing: -0.005em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  background: transparent;
  transition: background-color var(--mo-dur-slow) var(--mo-ease),
              border-color var(--mo-dur-slow) var(--mo-ease),
              box-shadow var(--mo-dur-slow) var(--mo-ease),
              transform var(--mo-dur) var(--mo-ease);
}

.mo-btn:focus-visible {
  outline: var(--mo-focus-width) solid var(--mo-focus-color);
  outline-offset: var(--mo-focus-offset);
}

.mo-btn--sm { height: 36px; padding-inline: 15px; font-size: var(--mo-step--2); }

.mo-btn__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 100%;
}

.mo-btn__label {
  position: relative;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mo-btn[disabled],
.mo-btn[aria-disabled="true"] { opacity: .6; cursor: progress; }

/* ---- Primary -------------------------------------------------------------
   CONTRAST, and this is the whole reason the fill is not paired with white:
     #0b1a14 on #14A876 (rest)   = 5.88:1  PASS AA
     #0b1a14 on #13a171 (hover)  = 5.43:1  PASS AA
     #0b1a14 on #12996b (active) = 4.94:1  PASS AA
     #ffffff on #14A876          = 3.05:1  FAIL AA for 14px text
   Because the fill supplies its own background, this button keeps 5.88:1 on
   the light page AND inside the dark panel. That is why --mo-on-accent is
   excluded from the [data-mo-theme="dark"] block in section 3.
   -------------------------------------------------------------------------- */
.mo-btn--primary {
  background-color: var(--mo-accent);
  border-color: var(--mo-accent);
  color: var(--mo-on-accent);
}
.mo-btn--primary:hover  { background-color: var(--mo-accent-hover);  border-color: var(--mo-accent-hover); }
.mo-btn--primary:active { background-color: var(--mo-accent-active); border-color: var(--mo-accent-active); transform: translateY(1px); }

/* hex CornerCircles, copied: four 13px circles pinned outside the corners that
   fade OUT on hover. Purely decorative - the markup carries aria-hidden. */
.mo-btn__circles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 1;
  transition: opacity var(--mo-dur-slow) var(--mo-ease);
}
.mo-btn__circles > span { position: absolute; inset: 0; }
.mo-btn__circles > span::before,
.mo-btn__circles > span::after {
  content: '';
  position: absolute;
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--mo-on-accent) 30%, transparent);
}
.mo-btn__circles > span:nth-child(1)::before { top: -7px; left: -7px; }
.mo-btn__circles > span:nth-child(1)::after  { top: -7px; right: -7px; }
.mo-btn__circles > span:nth-child(2)::before { bottom: -7px; left: -7px; }
.mo-btn__circles > span:nth-child(2)::after  { bottom: -7px; right: -7px; }
.mo-btn--primary:hover .mo-btn__circles { opacity: 0; }

/* ---- Secondary -----------------------------------------------------------
   hex's own outlined button uses a #dbd7da border = 1.4:1, which fails
   WCAG 1.4.11 for a control boundary. We use --mo-border-strong #7d8d86 =
   3.34:1 on --mo-bg. Deliberate divergence.
   Inside the dark panel the token re-pointing does all the work: --mo-ink
   becomes #e8f0ec (14.51:1) and --mo-border-strong becomes #4f7a69 (3.46:1).
   No per-panel override needed.
   -------------------------------------------------------------------------- */
.mo-btn--secondary {
  background-color: transparent;
  color: var(--mo-ink);
  border-color: var(--mo-border-strong);
}
.mo-btn--secondary:hover  { background-color: var(--mo-tint); border-color: var(--mo-accent-deep); }
.mo-btn--secondary:active { background-color: var(--mo-tint-strong); transform: translateY(1px); }

/* hex CornerLines, copied: four L-marks that fade IN and translate 5px
   diagonally outward on hover. */
.mo-btn__corners {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--mo-dur-slow) var(--mo-ease);
}
.mo-btn__corner { position: absolute; width: 15px; height: 15px; }
.mo-btn__corner::before {
  content: '';
  position: absolute;
  inset: 0;
  transition: transform var(--mo-dur-slow) var(--mo-ease);
}
.mo-btn__corner:nth-child(1) { top: -1px; left: -1px; }
.mo-btn__corner:nth-child(2) { top: -1px; right: -1px; }
.mo-btn__corner:nth-child(3) { bottom: -1px; left: -1px; }
.mo-btn__corner:nth-child(4) { bottom: -1px; right: -1px; }
.mo-btn__corner:nth-child(1)::before { border-top: 1px solid var(--mo-border-strong); border-left: 1px solid var(--mo-border-strong); }
.mo-btn__corner:nth-child(2)::before { border-top: 1px solid var(--mo-border-strong); border-right: 1px solid var(--mo-border-strong); }
.mo-btn__corner:nth-child(3)::before { border-bottom: 1px solid var(--mo-border-strong); border-left: 1px solid var(--mo-border-strong); }
.mo-btn__corner:nth-child(4)::before { border-bottom: 1px solid var(--mo-border-strong); border-right: 1px solid var(--mo-border-strong); }
.mo-btn--secondary:hover .mo-btn__corners { opacity: 1; }
.mo-btn--secondary:hover .mo-btn__corner:nth-child(1)::before { transform: translate(-5px, -5px); }
.mo-btn--secondary:hover .mo-btn__corner:nth-child(2)::before { transform: translate(5px, -5px); }
.mo-btn--secondary:hover .mo-btn__corner:nth-child(3)::before { transform: translate(-5px, 5px); }
.mo-btn--secondary:hover .mo-btn__corner:nth-child(4)::before { transform: translate(5px, 5px); }


/* ==========================================================================
   7. NAV
   ========================================================================== */

/* The IntersectionObserver target. 1px tall and statically positioned so it
   scrolls away with the page; js/mo.js flips .mo-nav--scrolled when it exits
   the viewport. No scroll listener means no per-frame work. */
.mo-nav__sentinel { height: 1px; }

.mo-nav {
  position: sticky;
  top: 0;
  z-index: var(--mo-z-nav);
  width: 100%;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--mo-dur) var(--mo-ease),
              box-shadow var(--mo-dur) var(--mo-ease),
              border-color var(--mo-dur) var(--mo-ease),
              backdrop-filter var(--mo-dur) var(--mo-ease);
}

/* LEARNING NOTE - the glass nav, and a contrast trap that was live here.
   backdrop-filter blurs whatever is painted BEHIND the element, which is what
   makes the bar read as frosted glass rather than a flat translucent panel.

   hex's recipe is blur(7.5px) over color-mix(in srgb, #fdfdfd 40%, transparent).
   It is safe on hex.tech because nothing dark ever scrolls under their nav.
   THIS page has a full-bleed dark inset panel (.mo-panel, #0c211a, the OzyOps
   section), and 40% #fdfdfd composited over #0c211a is rgb(108,121,117):
   measured in headless Chrome, the five nav links rendered at 1.97-2.77:1
   against it, where WCAG AA wants 4.5:1, for roughly 13% of the page's scroll
   height at every width tested.

   Blur does NOT rescue that. Blurring a large uniform dark area preserves its
   mean luminance; the bar just becomes an evenly dark bar.

   So the ALPHA is now the same on both paths - 86%, which composites to
   rgb(219,222,221) over the panel and puts the links back at 6.62:1 - and the
   @supports block adds ONLY the blur. The frosted look comes from the blur;
   the transparency was never what was doing that work, it was only ever
   deciding whether the text could be read. */
.mo-nav--scrolled {
  background: var(--mo-glass-bg-solid);
  border-bottom-color: var(--mo-border);
  box-shadow: var(--mo-shadow-nav);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mo-nav--scrolled {
    -webkit-backdrop-filter: blur(var(--mo-glass-blur));
    backdrop-filter: blur(var(--mo-glass-blur));
  }
}

.mo-nav__inner {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  max-width: var(--mo-max-width);
  margin-inline: auto;
  padding-inline: var(--mo-gutter);
  min-height: var(--mo-nav-h);
}

.mo-nav__brand {
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--mo-ink);            /* 17.18:1 on --mo-bg */
}
.mo-nav__logo { width: 28px; height: 28px; object-fit: contain; }
.mo-nav__wordmark {
  font-family: var(--mo-font-sans);
  font-weight: 650;
  font-stretch: 104%;
  font-size: var(--mo-step--1);
  letter-spacing: -0.01em;
  line-height: 1;
}

.mo-nav__links { display: none; }

.mo-nav__link {
  position: relative;
  font-family: var(--mo-font-sans);
  font-weight: 500;
  font-size: var(--mo-step--1);
  line-height: 1;
  color: #3d4d46;                  /* 8.57:1 on --mo-bg */
  text-decoration: none;
  padding-block: 8px;
  transition: color var(--mo-dur) var(--mo-ease);
}
/* Decorative underline only - the COLOUR change carries the state, so the
   2.92:1 accent-on-bg ratio of this bar is not load-bearing. */
.mo-nav__link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 2px;
  width: 0; height: 1.5px;
  background: var(--mo-accent);
  transition: width var(--mo-dur) var(--mo-ease);
}
.mo-nav__link:hover,
.mo-nav__link:focus-visible { color: var(--mo-ink); }
.mo-nav__link:hover::after,
.mo-nav__link:focus-visible::after { width: 100%; }

.mo-nav__actions { display: flex; align-items: center; gap: 10px; }

.mo-nav__toggle {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 44px; height: 44px;       /* full touch target */
  background: transparent;
  /* NOT --mo-border-strong (#7d8d86). This control is the ONLY one that sits
     on the scrolled glass, and over the dark .mo-panel that composite is
     rgb(219,222,221), where #7d8d86 measures 2.57:1 - under the 3:1 WCAG
     1.4.11 wants for a control boundary. #6e7c76 is 3.22:1 there and 4.19:1
     on the ordinary page background, so one value is correct everywhere the
     hamburger can appear. */
  border: 1px solid #6e7c76;
  border-radius: var(--mo-r-sm);
  cursor: pointer;
}
.mo-nav__toggle-bar {
  width: 18px; height: 1.5px;
  background: var(--mo-ink);
  transition: transform var(--mo-dur) var(--mo-ease),
              opacity var(--mo-dur) var(--mo-ease);
}
.mo-nav--open .mo-nav__toggle-bar:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.mo-nav--open .mo-nav__toggle-bar:nth-child(2) { opacity: 0; }
.mo-nav--open .mo-nav__toggle-bar:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* The drawer is OPAQUE, not glass: glass over arbitrary scrolled content
   cannot guarantee 4.5:1 on the links inside it. Deliberate divergence. */
.mo-nav__drawer {
  position: absolute;
  top: 100%; left: 0; right: 0;
  z-index: var(--mo-z-drawer);
  background: var(--mo-surface);
  border-bottom: 1px solid var(--mo-border);
  box-shadow: var(--mo-shadow-nav);
  padding: 8px var(--mo-gutter) 20px;
}
.mo-nav__drawer[hidden] { display: none; }

.mo-nav__drawer-link {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-family: var(--mo-font-sans);
  font-weight: 500;
  font-size: var(--mo-step-1);
  line-height: 1.3;
  color: var(--mo-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--mo-border);
}
.mo-nav__drawer-cta { margin-top: 16px; width: 100%; }

@media (min-width: 880px) {
  .mo-nav__links { display: flex; gap: 28px; margin-inline: auto; }
  .mo-nav__toggle,
  .mo-nav__drawer { display: none; }
}


/* ==========================================================================
   8. HERO
   hex's HomeHero is a CENTRED flex column, not a side-by-side split. Copied.
   ========================================================================== */

.mo-hero {
  position: relative;
  overflow-x: clip;
  padding-top: calc(var(--mo-nav-h) + var(--mo-section-pad));
  padding-bottom: var(--mo-section-pad);
  background-color: var(--mo-bg);
  /* LEARNING NOTE - fading the dot grid WITHOUT mask-image.
     The obvious way to fade this texture out toward the fold is
     mask-image: linear-gradient(to top, transparent, black 65%). Do not do
     that here. mask-image masks the element AND ALL ITS DESCENDANTS, so it
     would fade out the headline, the lede and the buttons along with the dots
     - the CTAs would literally go transparent at the bottom of the hero.
     Instead we stack two background layers on the same element: the dot grid
     underneath, and a gradient that runs from transparent at the top to the
     solid page colour by 65% down painted over it. The visual result is
     identical and no text is touched. Background layers paint first-listed on
     top, which is why the fade gradient is written first. */
  background-image:
    linear-gradient(to bottom, transparent 0%, var(--mo-bg) 65%),
    var(--mo-dotgrid);
  background-size: auto, var(--mo-dotgrid-size);
  background-repeat: no-repeat, repeat;
  scroll-margin-top: calc(var(--mo-nav-h) + 20px);
}

/* hex GridLines__CheckeredMargin, recoloured. Wide screens only. */
.mo-hero::before,
.mo-hero::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 40px;
  background-image: var(--mo-checker);
  display: none;
}
.mo-hero::before { left: 0;  border-right: 1px solid var(--mo-border); }
.mo-hero::after  { right: 0; border-left:  1px solid var(--mo-border); }

.mo-hero__inner {
  position: relative;
  z-index: var(--mo-z-raised);
  max-width: var(--mo-max-width);
  margin-inline: auto;
  padding-inline: var(--mo-gutter);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
}

.mo-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--mo-accent-deep);    /* 6.15:1 on --mo-bg */
  max-width: 100%;
}
.mo-hero__eyebrow::before,
.mo-hero__eyebrow::after {
  content: '';
  flex: none;
  width: 24px; height: 1px;
  background: var(--mo-border);
}

.mo-hero__title {
  font-family: var(--mo-font-sans);
  font-weight: 700;
  font-stretch: 112%;
  font-size: var(--mo-step-6);
  line-height: var(--mo-lh-h1);
  letter-spacing: var(--mo-ls-h1);
  color: var(--mo-ink);            /* 17.18:1 */
}

/* The one editorial accent. font-stretch MUST be reset: Instrument Serif has
   no wdth axis, and inheriting 112% would make the browser synthesise a
   stretch. hex uses 1.3em at weight 200; Instrument Serif ships only 400 and
   runs optically heavier, so 1.1em keeps the weights matched. */
.mo-hero__title-em {
  font-family: var(--mo-font-serif);
  font-style: italic;
  font-weight: 400;
  font-stretch: normal;
  font-size: 1.1em;
  letter-spacing: -0.005em;
}

.mo-hero__lede {
  max-width: var(--mo-prose-max);      /* 650px, hex exact */
  margin-inline: auto;
  font-size: var(--mo-step-2);
  line-height: var(--mo-lh-body);
  font-weight: 400;
  color: var(--mo-ink-muted);          /* 5.41:1 on --mo-bg */
}

.mo-hero__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 15px;                            /* hex exact */
  padding-top: 20px;                    /* hex exact */
  width: 100%;
  max-width: 320px;
}
.mo-hero__actions .mo-btn { width: 100%; }

.mo-hero__meta { color: var(--mo-ink-muted); font-size: var(--mo-step--2); }

@media (min-width: 480px) {
  .mo-hero__actions {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    width: auto;
    max-width: none;
  }
  .mo-hero__actions .mo-btn { width: auto; }
}

@media (min-width: 768px) {
  .mo-hero__title { max-width: 18ch; }
}

@media (min-width: 1024px) {
  .mo-hero { padding-top: calc(var(--mo-nav-h) + 110px); }
  .mo-hero::before,
  .mo-hero::after { display: block; }
}


/* ==========================================================================
   9. SECTION SHELL
   ========================================================================== */

.mo-section {
  position: relative;
  padding-block: var(--mo-section-pad);
  background: var(--mo-bg);
  scroll-margin-top: calc(var(--mo-nav-h) + 20px);
}

/* ink on --mo-tint = 16.27:1, --mo-ink-muted = 5.13:1,
   --mo-accent-deep = 5.82:1. All PASS AA. */
.mo-section--tint { background: var(--mo-tint); }

.mo-section__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  max-width: 760px;
  margin: 0 auto var(--mo-row-gap);
}

.mo-section__eyebrow { color: var(--mo-accent-deep); }

.mo-section__title {
  font-family: var(--mo-font-sans);
  font-weight: 700;
  font-stretch: 110%;
  font-size: var(--mo-step-5);
  line-height: var(--mo-lh-h2);
  letter-spacing: var(--mo-ls-h2);
  color: var(--mo-ink);
}

.mo-section__lede {
  font-size: var(--mo-step-1);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink-muted);
  max-width: 56ch;
}

/* hex GridLines__ContentMarginLine. Only from 1024px up - below that the rules
   would crowd the gutter, so they are dropped rather than squeezed. */
@media (min-width: 1024px) {
  .mo-container { border-inline: 1px solid var(--mo-border); }
}


/* ==========================================================================
   10. FEATURE ROWS
   hex's .sharedStyles__SectionWrapper flips row / row-reverse for alternate
   sections. Reproduced with grid so the MOBILE ORDER stays correct.
   ========================================================================== */

.mo-feature {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
}

.mo-feature__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  max-width: var(--mo-copy-max);       /* 425px, hex verbatim */
}

.mo-feature__eyebrow { color: var(--mo-accent-deep); }   /* 6.15:1 */

.mo-feature__title {
  font-family: var(--mo-font-sans);
  font-weight: 700;
  font-stretch: 110%;
  font-size: var(--mo-step-4);          /* one step down from centred section titles
                                           so the hero stays dominant */
  line-height: var(--mo-lh-h2);
  letter-spacing: var(--mo-ls-h2);
  color: var(--mo-ink);
  text-align: left;
}

.mo-feature__body {
  font-size: var(--mo-step-1);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink-muted);           /* 5.41:1 on --mo-bg */
}

.mo-feature__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}
.mo-feature__item {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 10px;
  align-items: start;
  font-size: var(--mo-step-0);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink);
}
.mo-feature__item strong { font-weight: 600; }

/* An inline text link, not a button. --mo-accent-deep because --mo-accent is
   2.92:1 on the page background and fails. */
.mo-feature__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 550;
  color: var(--mo-accent-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--mo-dur) var(--mo-ease),
              text-decoration-thickness var(--mo-dur) var(--mo-ease);
}
.mo-feature__cta svg { transition: transform var(--mo-dur) var(--mo-ease); }
.mo-feature__cta:hover,
.mo-feature__cta:focus-visible { color: var(--mo-ink); text-decoration-thickness: 2px; }
.mo-feature__cta:hover svg { transform: translateX(3px); }

.mo-feature__visual { min-width: 0; width: 100%; }

@media (min-width: 768px) {
  .mo-feature__visual { max-width: 640px; margin-inline: auto; }
}

@media (min-width: 1024px) {
  .mo-feature {
    grid-template-columns: minmax(0, var(--mo-copy-max)) minmax(0, 1fr);
    column-gap: var(--mo-col-gap);
  }
  .mo-feature__visual { max-width: none; margin-inline: 0; }

  /* The reverse modifier only exists from 1024px up. Below that it is inert,
     so the painted order can never disagree with the DOM order and the
     reading order stays correct for everyone. */
  .mo-feature--reverse { grid-template-columns: minmax(0, 1fr) minmax(0, var(--mo-copy-max)); }
  .mo-feature--reverse .mo-feature__copy   { grid-column: 2; }
  .mo-feature--reverse .mo-feature__visual { grid-column: 1; grid-row: 1; }
}


/* ==========================================================================
   11. VISUAL CARDS
   --------------------------------------------------------------------------
   HARD RULE: no photography, no screenshots, no fabricated dashboards, no
   invented metrics, no invented customer or host names, no number that could
   be read as a business claim. Every variant is drawn with CSS boxes and
   inline SVG, and the copy column always states the point in words - nothing
   inside these cards is the sole carrier of any information.

   SHELL: hex's Card__Wrapper (12px glass shell, 10px padding) wrapping an
   opaque 6px-radius inner surface. That two-layer construction is the single
   most recognisable hex idiom on the page.
   ========================================================================== */

.mo-visual {
  position: relative;
  padding: 10px;
  border-radius: var(--mo-r-lg);
  background: linear-gradient(105deg, var(--mo-accent-a-08) 10.56%, rgba(20, 168, 118, 0.02) 108.41%),
              rgba(253, 253, 253, 0.4);
  box-shadow: var(--mo-glass-shadow);
  -webkit-backdrop-filter: blur(var(--mo-glass-blur));
  backdrop-filter: blur(var(--mo-glass-blur));
}

/* hex .InteractiveFeatureWrapper WindowTitle, exact. */
.mo-visual__tab {
  position: absolute;
  bottom: 100%;
  left: 12px;
  font-family: var(--mo-font-mono);
  font-size: 11px;
  line-height: 28px;
  padding: 0 12px;
  opacity: .9;
  color: var(--mo-ink-muted);
  border-left: 1px solid var(--mo-border-strong);
  border-top: 1px dashed var(--mo-border-strong);
  border-right: 1px dashed var(--mo-border-strong);
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 90%, transparent 100%);
  mask-image: linear-gradient(to bottom, black 0%, black 90%, transparent 100%);
  transition: transform .2s ease-in-out, opacity .2s ease-in-out,
              color .2s ease-in-out, border-color .2s ease-in-out;
}

.mo-visual__surface {
  position: relative;
  border-radius: var(--mo-r-md);
  background: var(--mo-surface);
  box-shadow: var(--mo-shadow-surface);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  transition: box-shadow .2s ease-in-out, transform .2s ease-in-out;
}
.mo-visual__surface > svg { width: 100%; height: 100%; }

@media (min-width: 768px) {
  .mo-visual__surface { aspect-ratio: 16 / 11; }
}

/* Hover only where hover really exists, so a touch device never gets stuck in
   a hover state after a tap. hex's cursor:none trick is deliberately NOT
   copied - hiding the cursor is hostile. */
@media (hover: hover) {
  .mo-visual:hover .mo-visual__surface {
    box-shadow: var(--mo-shadow-surface-hover);
    transform: translateY(-2px);
  }
  .mo-visual:hover .mo-visual__tab {
    opacity: 1;
    transform: translateY(-2px);
    color: var(--mo-ink);
    border-color: var(--mo-border-strong);
  }
}

/* ---- .mo-visual--log  ("We secure it") ----------------------------------
   A findings reader whose every finding is redacted. The card reads as a real
   assessment output while asserting literally nothing. Line NUMBERS, not
   timestamps: a timestamp would imply a real engagement on a real date.
   -------------------------------------------------------------------------- */
.mo-log__head {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding-inline: 14px;
  background: var(--mo-tint);
  border-bottom: 1px solid var(--mo-border);
}
.mo-log__dot { width: 8px; height: 8px; border-radius: 2px; background: var(--mo-border-strong); }
.mo-log__title {
  margin-left: 8px;
  font-size: 10px;
  color: var(--mo-ink-muted);
}

.mo-log__body {
  position: relative;
  padding-left: 1px;
  /* A 1px rule down the left edge with a 3px tick every 24px - a ruler, drawn
     entirely with one repeating gradient rather than an extra element. */
  background-image:
    linear-gradient(to right, var(--mo-border) 0 1px, transparent 1px),
    repeating-linear-gradient(to bottom, var(--mo-border) 0 1px, transparent 1px 24px);
  background-size: 1px 100%, 3px 100%;
  background-repeat: no-repeat;
  background-position: 0 0, 0 0;
}

.mo-log__row {
  display: grid;
  grid-template-columns: 28px 52px 1fr;
  gap: 10px;
  align-items: center;
  padding: 7px 14px;
  border-bottom: 1px solid var(--mo-border);
}
.mo-log__gutter {
  font-family: var(--mo-font-mono);
  font-size: 10px;
  color: var(--mo-ink-muted);
  text-align: right;
}
.mo-log__chip {
  font-family: var(--mo-font-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border-radius: 4px;
  text-align: center;
}
.mo-log__chip--pass { background: var(--mo-accent-a-16); color: var(--mo-accent-deep); }
.mo-log__chip--note { background: var(--mo-a-06);        color: var(--mo-ink-muted); }
.mo-log__chip--open { background: rgba(179, 38, 30, 0.08); color: var(--mo-danger); }

/* THE REDACTION. This is the point of the card. */
.mo-log__bar { height: 7px; border-radius: 3px; background: var(--mo-border); }

/* ---- .mo-visual--arch  ("We build it") ----------------------------------
   Generic infrastructure nouns only. No product, vendor or client names.
   -------------------------------------------------------------------------- */
.mo-visual--arch .mo-visual__surface {
  background-color: var(--mo-surface);
  background-image: var(--mo-dotgrid);
  background-size: var(--mo-dotgrid-size);
}
.mo-arch__wires polyline { fill: none; stroke: var(--mo-border-strong); stroke-width: 1; }
.mo-arch__wires circle   { fill: var(--mo-border-strong); }
.mo-arch__node rect { fill: var(--mo-surface); stroke: var(--mo-border-strong); stroke-width: 1; }
/* Decorative emphasis on the client -> api -> db path. The labels stay
   legible either way, so the accent is never the sole signal. */
.mo-arch__node--focal rect { fill: var(--mo-accent-a-08); stroke: var(--mo-accent); stroke-width: 1.5; }
.mo-arch__node text {
  font-family: var(--mo-font-mono);
  font-size: 10px;
  fill: var(--mo-ink);               /* 17.9:1 on white */
  text-anchor: middle;
  dominant-baseline: middle;
}

/* ---- .mo-visual--flow  (the OzyOps dark panel) --------------------------
   These five labels are grounded in verified OzyOps facts. Do not add a sixth.
   -------------------------------------------------------------------------- */
.mo-visual--flow .mo-visual__surface {
  background: var(--mo-panel-surface);
  box-shadow: 0 0 0 1px var(--mo-panel-border-strong);
}
.mo-flow__wires polyline { fill: none; stroke: var(--mo-accent-lite); stroke-width: 1.25; }
.mo-flow__wires circle   { fill: var(--mo-accent-lite); }
.mo-flow__node rect { fill: rgba(67, 213, 157, 0.10); stroke: var(--mo-accent-lite); stroke-width: 1.25; }
.mo-flow__node text {
  font-family: var(--mo-font-mono);
  font-size: 10px;
  fill: var(--mo-panel-ink);         /* 14.02:1 on --mo-panel-surface */
  text-anchor: middle;
  dominant-baseline: middle;
}


/* ==========================================================================
   12. PROOF STRIP
   hex's logo-wall slot, reproduced down to the clip-path cutout that drops the
   section label into a gap in the top rule. The CONTENT is credentials and
   service area, because that is what we have - we have no customer logos and
   will not invent any.
   ========================================================================== */

.mo-proof {
  position: relative;
  z-index: var(--mo-z-raised);
  padding-block: 34px;
  background-color: var(--mo-tint);
  isolation: isolate;
  scroll-margin-top: calc(var(--mo-nav-h) + 20px);
}

/* hex's clip-path cutout technique, exact. The rules are drawn on a
   pseudo-element whose top edge is then clipped away in the middle, leaving a
   264px gap for the label to sit in. */
.mo-proof::before {
  content: '';
  position: absolute;
  box-sizing: content-box;
  inset: -1px 0 -1px 0;
  border-top: 1px solid var(--mo-border-strong);
  border-bottom: 1px solid var(--mo-border-strong);
  --cutout-width: 264px;
  --cutout-left-x: calc(50% - var(--cutout-width) * 0.5 - 1px);
  --cutout-right-x: calc(50% + var(--cutout-width) * 0.5 + 1px);
  clip-path: polygon(
    0% 0%,
    var(--cutout-left-x) 0%,
    var(--cutout-left-x) 5px,
    var(--cutout-right-x) 5px,
    var(--cutout-right-x) 0%,
    100% 0%,
    100% 100%,
    0% 100%
  );
  pointer-events: none;
}

.mo-proof__label {
  position: absolute;
  left: 50%; top: 0;
  transform: translate(-50%, -50%);
  width: min-content;
  white-space: nowrap;
  padding: 0 12px;
  line-height: 0.8;
  font-size: 10px;
  background: var(--mo-tint);
  color: var(--mo-ink-muted);        /* 5.13:1 on --mo-tint */
  border-left: 1px solid var(--mo-ink-muted);
  border-right: 1px solid var(--mo-ink-muted);
}
.mo-proof__label::before,
.mo-proof__label::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 7px; height: 1px;
  background: var(--mo-ink-muted);
}
.mo-proof__label::before { right: 100%; }
.mo-proof__label::after  { left: 100%; }

/* hex LAccents - 6px L-marks pinned to the container edges. */
.mo-proof__accents {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  pointer-events: none;
  display: none;
}
.mo-proof__accents::before,
.mo-proof__accents::after {
  content: '';
  position: absolute;
  top: -7px;
  width: 6px; height: 6px;
}
.mo-proof__accents::before { left: 0;  border-left: 1px solid var(--mo-border-strong);  border-bottom: 1px solid var(--mo-border-strong); }
.mo-proof__accents::after  { right: 0; border-right: 1px solid var(--mo-border-strong); border-bottom: 1px solid var(--mo-border-strong); }

.mo-proof__heading {
  font-family: var(--mo-font-sans);
  font-weight: 700;
  font-stretch: 110%;
  font-size: var(--mo-step-4);
  line-height: var(--mo-lh-h2);
  letter-spacing: var(--mo-ls-h2);
  color: var(--mo-ink);              /* 16.51:1 on --mo-tint */
  text-align: center;
  margin-bottom: 28px;
}

/* DIVERGENCE FROM hex, stated. hex's slot is a single flex row of logos. Ours
   carries a credential name PLUS a sentence of detail, which will not survive
   a five-across row at any readable size. The band chrome above (rules, label
   cutout, L accents, tint) is what makes this read as hex's logo wall; the
   inner arrangement is a responsive grid because our content is richer. */
.mo-proof__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px 40px;
}
.mo-proof__item { display: flex; align-items: flex-start; gap: 10px; }
.mo-proof__mark {
  flex: none;
  width: 22px; height: 22px;
  margin-top: 2px;
  color: var(--mo-accent-deep);      /* 5.82:1 on --mo-tint */
}
.mo-proof__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mo-proof__text {
  font-family: var(--mo-font-sans);
  font-weight: 550;
  font-size: var(--mo-step--1);
  line-height: 1.3;
  color: var(--mo-ink);              /* 16.51:1 on --mo-tint */
}
/* Sans 13px rather than the spec's mono 10px: these are full sentences, and a
   sentence set in 10px uppercase-tracked mono is not readable prose. */
.mo-proof__sub {
  font-size: var(--mo-step--2);
  line-height: 1.5;
  color: var(--mo-ink-muted);        /* 5.13:1 on --mo-tint */
}

@media (min-width: 600px) {
  .mo-proof__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
  .mo-proof__accents { display: block; }
}
@media (min-width: 900px) {
  .mo-proof__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* ==========================================================================
   13. DARK PANEL (OzyOps)
   The ONE #0c211a region on the page. Not the nav, not the footer, not the
   proof strip, not the contact section. It earns its darkness by being the
   one place that talks about a different product - the colour shift is doing
   semantic work.
   ========================================================================== */

.mo-section--panel { background: var(--mo-bg); }

.mo-panel {
  position: relative;
  border-radius: var(--mo-r-lg);
  background-color: var(--mo-panel);
  overflow: hidden;
  padding: clamp(32px, 4vw + 16px, 64px);
  isolation: isolate;
  box-shadow: 0 0 0 1px var(--mo-panel-border),
              0 24px 48px -16px rgba(11, 26, 20, 0.22);
}
/* Two decorative layers, both pointer-events:none, both well under 0.12 alpha
   so neither moves any measured contrast ratio. */
.mo-panel::before,
.mo-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.mo-panel::before { background: radial-gradient(60% 80% at 20% 0%, rgba(67, 213, 157, 0.10), transparent 70%); }
.mo-panel::after  {
  background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.05) 1px, transparent 0);
  background-size: var(--mo-dotgrid-size);
}

.mo-panel__inner {
  position: relative;
  z-index: var(--mo-z-raised);
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
}

.mo-panel__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }

/* --mo-accent-lite #43d59d = 9.01:1 on --mo-panel. Do NOT use
   --mo-accent-deep here: 2.62:1 on the panel, FAIL. */
.mo-panel__eyebrow { color: var(--mo-accent-lite); }

.mo-panel__title {
  font-family: var(--mo-font-sans);
  font-weight: 700;
  font-stretch: 110%;
  font-size: var(--mo-step-4);
  line-height: var(--mo-lh-h2);
  letter-spacing: var(--mo-ls-h2);
  color: var(--mo-panel-ink);        /* 14.51:1 */
  text-align: left;
}

.mo-panel__body {
  font-size: var(--mo-step-1);
  line-height: var(--mo-lh-body);
  color: var(--mo-panel-muted);      /* 8.51:1 */
}

.mo-panel__list { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.mo-panel__item {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 10px;
  align-items: start;
  font-size: var(--mo-step-0);
  line-height: var(--mo-lh-body);
  color: var(--mo-panel-ink);
}
.mo-panel__item .mo-check { color: var(--mo-accent-lite); }   /* 9.01:1 */

.mo-panel__actions { display: flex; gap: 15px; flex-wrap: wrap; padding-top: 8px; }

.mo-panel__visual { min-width: 0; width: 100%; }

@media (min-width: 1024px) {
  .mo-panel__inner {
    grid-template-columns: minmax(0, var(--mo-copy-max)) minmax(0, 1fr);
    column-gap: var(--mo-col-gap);
  }
}


/* ==========================================================================
   14. FAQ ACCORDION
   ========================================================================== */

.mo-faq {
  padding-block: var(--mo-section-pad);
  background: var(--mo-bg);
  scroll-margin-top: calc(var(--mo-nav-h) + 20px);
}

.mo-faq__inner {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--mo-faq-max);      /* 604px, hex exact */
  margin-inline: auto;
  padding-inline: var(--mo-gutter);
}

/* hex .FAQ__Top, exact. */
.mo-faq .mo-section__head {
  margin-bottom: 0;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--mo-border);
}

.mo-faq__list { display: flex; flex-direction: column; }

.mo-faq__item {
  border-bottom: 1px solid var(--mo-border);
  transition: background-color var(--mo-dur-slow) var(--mo-ease);
}
.mo-faq__item:hover { background: var(--mo-tint); }   /* ink stays 16.27:1 */

/* The heading level is carried by an <h3> wrapper so the document outline is
   correct; the wrapper's own type is reset because the BUTTON inside carries
   the visual treatment. Pick the level, then apply the class - never pick a
   level for its size. */
.mo-faq__h { margin: 0; font: inherit; }

/* hex's FAQ item is a <div> with a click handler - not keyboard operable and
   not announced. Ours is a real <button aria-expanded> controlling a
   role="region". Deliberate divergence. */
.mo-faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.mo-faq__q:focus-visible {
  outline: var(--mo-focus-width) solid var(--mo-focus-color);
  outline-offset: -2px;              /* inset: the item is flush to the rule */
}

.mo-faq__q-text {
  font-family: var(--mo-font-sans);
  font-weight: 550;
  font-size: 18px;
  line-height: 24px;
  letter-spacing: -0.5px;            /* hex .FAQ__Question, verbatim */
  color: var(--mo-ink);              /* 17.18:1 */
}

.mo-faq__chevron {
  flex: none;
  width: 14px; height: 14px;
  color: var(--mo-ink-muted);        /* 5.41:1 */
  transform: rotate(-90deg);         /* closed */
  transition: transform var(--mo-dur) var(--mo-ease);
}
.mo-faq__item[data-open="true"] .mo-faq__chevron { transform: rotate(0deg); }

/* LEARNING NOTE - the accordion animation, and why grid instead of max-height.
   The classic trick animates max-height from 0 to a guessed large value. It is
   always wrong: guess too small and long answers clip, guess too large and the
   easing curve runs mostly through empty space, so the panel appears to snap
   then crawl. Animating grid-template-rows from 0fr to 1fr interpolates
   against the content's OWN measured height, so there is no guess, no clipping
   and a correct curve at any length. The two requirements are that the inner
   element sets overflow:hidden and min-height:0 - without min-height:0 a grid
   item refuses to shrink below its content and the collapse silently does
   nothing. */
.mo-faq__a {
  display: grid;
  transition: grid-template-rows .24s var(--mo-ease);
}

/* TWO THINGS ARE SCOPED UNDER .mo-js HERE, AND BOTH ARE CORRECTNESS.

   1. THE COLLAPSE ITSELF. The buttons are inert without js/mo.js, so an
      unscoped `grid-template-rows: 0fr` leaves four of the five answers at
      zero height and unopenable forever. Scoped, a page with no working JS
      renders every answer expanded - the same degradation the @media print
      block below already chose.

   2. `visibility`. Clipping a box to zero height does NOT remove it from the
      accessibility tree. This stylesheet proves that against itself: .mo-sr-only
      (see section 4) hides content by exactly this technique precisely SO THAT
      a screen reader still announces it. Without the visibility rule, NVDA and
      VoiceOver read all five answers as ordinary page text while every button
      reports aria-expanded="false" - the interface states the opposite of what
      the user is hearing (WCAG 4.1.2). `visibility` is one of the few
      properties that prunes the subtree AND animates usefully: delaying it by
      the row transition's own .24s lets the closing animation finish before
      the content disappears, and dropping the delay on open makes it appear
      immediately. */
.mo-js .mo-faq__a { grid-template-rows: 0fr; }
.mo-js .mo-faq__item[data-open="true"] .mo-faq__a { grid-template-rows: 1fr; }

.mo-faq__a-inner { overflow: hidden; min-height: 0; }
.mo-js .mo-faq__a-inner { visibility: hidden; transition: visibility 0s .24s; }
.mo-js .mo-faq__item[data-open="true"] .mo-faq__a-inner {
  visibility: visible;
  transition-delay: 0s;
}
.mo-faq__a-inner > p {
  padding: 0 20px 20px;
  font-size: var(--mo-step-0);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink-muted);        /* 5.41:1 */
}
.mo-faq__a-inner a { color: var(--mo-accent-deep); text-decoration: underline; text-underline-offset: 3px; }


/* ==========================================================================
   15. CONTACT AND FORM
   ========================================================================== */

.mo-contact {
  padding-block: var(--mo-section-pad);
  background: var(--mo-tint);
  scroll-margin-top: calc(var(--mo-nav-h) + 20px);
}

.mo-contact__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.mo-contact__aside {
  background: var(--mo-surface);
  border: 1px solid var(--mo-border);
  border-radius: var(--mo-r-lg);
  padding: 28px;
  box-shadow: var(--mo-glass-shadow);
}
.mo-contact__aside-title {
  font-family: var(--mo-font-sans);
  font-weight: 600;
  font-stretch: 100%;
  font-size: 20px;
  line-height: var(--mo-lh-tight);
  letter-spacing: -0.015em;
  color: var(--mo-ink);
  margin-bottom: 8px;
}
.mo-contact__direct-item {
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: 12px;
  padding-block: 12px;
  border-bottom: 1px solid var(--mo-border);
  /* Long email addresses must never widen the page at 320px / 200% zoom. */
  overflow-wrap: anywhere;
}
.mo-contact__direct-item:last-child { border-bottom: 0; }
.mo-contact__direct-item svg { width: 20px; height: 20px; margin-top: 2px; color: var(--mo-accent-deep); }
.mo-contact__direct-item > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mo-contact__direct-label { color: var(--mo-ink-muted); font-size: 10px; }
.mo-contact__direct-item a {
  color: var(--mo-accent-deep);      /* 6.41:1 on white */
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--mo-dur) var(--mo-ease);
}
.mo-contact__direct-item a:hover { color: var(--mo-ink); }
.mo-contact__aside-note {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--mo-border);
  font-size: var(--mo-step--2);
  line-height: 1.5;
  color: var(--mo-ink-muted);        /* 5.65:1 on white */
}

.mo-form { display: flex; flex-direction: column; gap: 20px; }

.mo-form__row { display: grid; grid-template-columns: 1fr; gap: 20px; }

.mo-field { display: flex; flex-direction: column; gap: 6px; }

.mo-label {
  font-family: var(--mo-font-sans);
  font-weight: 550;
  font-size: var(--mo-step--1);
  line-height: 1.3;
  color: var(--mo-ink);              /* 16.27:1 on --mo-tint */
}
.mo-req { color: var(--mo-danger); }  /* 6.54:1 - and a visually-hidden
                                         " (required)" follows it in the markup,
                                         so the asterisk is never the only cue */

.mo-input,
.mo-select,
.mo-textarea {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  background: var(--mo-surface);
  color: var(--mo-ink);              /* 17.92:1 on white */
  /* 3.48:1 on white - meets WCAG 1.4.11 for a control boundary. hex's own
     #dbd7da input border is 1.4:1 and would fail. Deliberate divergence. */
  border: 1px solid var(--mo-border-strong);
  border-radius: var(--mo-r-sm);
  font-family: var(--mo-font-sans);
  font-weight: 400;
  font-size: var(--mo-step-0);
  line-height: 1.4;
  transition: border-color var(--mo-dur) var(--mo-ease),
              box-shadow var(--mo-dur) var(--mo-ease);
}
.mo-textarea { min-height: 140px; resize: vertical; }

.mo-input::placeholder,
.mo-textarea::placeholder { color: #67766e; }   /* 4.77:1 on --mo-surface #ffffff.
     Placeholder text is rendered text and SC 1.4.3 has no exemption for hints;
     the previous #6b7b73 measured 4.46:1, i.e. a recorded failure. It still
     reads as secondary against the 17.92:1 input text, so the hierarchy holds.
     Here the placeholder carries the expected phone FORMAT, which mo.js:322
     then enforces - losing it costs real information, not just polish. */

.mo-input:hover,
.mo-select:hover,
.mo-textarea:hover { border-color: #6f8078; }   /* 4.17:1 */

.mo-input:focus-visible,
.mo-select:focus-visible,
.mo-textarea:focus-visible {
  border-color: var(--mo-accent-deep);
  outline: var(--mo-focus-width) solid var(--mo-focus-color);
  outline-offset: var(--mo-focus-offset);
}

.mo-input[aria-invalid="true"],
.mo-select[aria-invalid="true"],
.mo-textarea[aria-invalid="true"] { border-color: var(--mo-danger); }

.mo-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" stroke="%235a6b63" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m3 5.5 4 4 4-4"/></svg>');
  background-repeat: no-repeat;
  background-position: right 14px center;
}

.mo-hint { font-size: var(--mo-step--2); line-height: 1.5; color: var(--mo-ink-muted); }

.mo-error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: var(--mo-step--2);
  line-height: 1.5;
  color: var(--mo-danger);           /* 6.54:1 on white */
}
.mo-error[hidden] { display: none; }
.mo-error::before { content: '\26A0'; flex: none; }   /* warning sign glyph */

/* Colour is never the only signal here: the status text itself says what
   happened, and the live region announces it.

   LEARNING NOTE - why the empty state is NOT display:none, and not [hidden].
   This element is the form's aria-live region. A screen reader registers live
   regions from what is present in the accessibility tree; an element that is
   display:none or [hidden] is not in that tree at all, so unhiding it and
   writing text in the same frame is a well-known way to get no announcement.
   The region therefore stays rendered at all times and only its TEXT changes.
   When empty it collapses to zero height, and the negative top margin cancels
   the parent flex gap so an empty status leaves no hole in the layout. */
.mo-form__status {
  padding: 12px 14px;
  border-radius: var(--mo-r-sm);
  border-left: 3px solid var(--mo-border-strong);
  background: var(--mo-surface);
  color: var(--mo-ink);
  font-size: var(--mo-step-0);
  line-height: var(--mo-lh-body);
}
.mo-form__status:empty {
  padding: 0;
  border: 0;
  background: none;
  margin-top: -20px;      /* cancels .mo-form's 20px gap while empty */
}
.mo-form__status--ok    { background: var(--mo-tint-strong);      border-left-color: var(--mo-accent-deep); }
.mo-form__status--error { background: rgba(179, 38, 30, 0.07);    border-left-color: var(--mo-danger); }

.mo-form__actions { display: flex; gap: 15px; align-items: center; flex-wrap: wrap; }
.mo-form__actions .mo-hint { flex: 1 1 200px; margin: 0; }

/* The honeypot wrapper. AntiSpam::getHoneypotFields() ships its own
   .ohnohoney rules (opacity:0, 0x0, z-index:-1, pointer-events:none, all
   !important) - this wrapper only takes the fields out of flow so they cannot
   affect layout. Do NOT add display:none or visibility:hidden here: some bots
   skip fields hidden that way, and the trap stops catching anything. */
.mo-form__hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

@media (min-width: 600px) {
  .mo-form__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .mo-contact__grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
    column-gap: var(--mo-col-gap);
    align-items: start;
  }
}


/* ==========================================================================
   16. FOOTER
   Stays LIGHT. hex's footer is light, the plan locks a light theme, and the
   dark treatment is reserved for the OzyOps panel alone.
   ========================================================================== */

.mo-footer {
  background: var(--mo-bg);
  border-top: 1px solid var(--mo-border);
  padding-block: 50px;               /* hex exact */
}

.mo-footer__inner {
  max-width: var(--mo-max-width);
  margin-inline: auto;
  padding-inline: var(--mo-gutter);
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.mo-footer__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 15px; }
.mo-footer__logo { width: 24px; height: 24px; object-fit: contain; }
.mo-footer__entity { font-weight: 600; color: var(--mo-ink); }
.mo-footer__tagline {
  font-size: var(--mo-step--1);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink-muted);        /* 5.41:1 */
  max-width: 34ch;
}

.mo-footer__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px;
}
.mo-footer__col { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.mo-footer__col-title {
  font-family: var(--mo-font-mono);
  font-size: 12px;
  font-weight: 500;                  /* hex uses 700; only 400/500 Plex Mono are
                                        self-hosted and 700 would be fake-bolded */
  text-transform: uppercase;
  letter-spacing: 0.7px;             /* hex exact */
  line-height: 1.4;
  color: var(--mo-ink);
}
.mo-footer__link,
.mo-footer__plain {
  font-size: var(--mo-step--1);
  color: var(--mo-ink-muted);        /* 5.41:1 - AA */
  text-decoration: none;
  padding-block: 6px;                /* keeps the effective touch target ~40px */
  overflow-wrap: anywhere;
}
.mo-footer__link { transition: color var(--mo-dur) var(--mo-ease); }
.mo-footer__link:hover,
.mo-footer__link:focus-visible {
  color: var(--mo-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.mo-footer__ozy {
  grid-column: 1 / -1;
  margin-top: 8px;
  padding: 16px 18px;
  border: 1px solid var(--mo-border);
  border-left: 3px solid var(--mo-accent);   /* decorative; the sentence carries
                                                the meaning */
  border-radius: var(--mo-r-sm);
  background: var(--mo-surface);
  font-size: var(--mo-step--1);
  line-height: var(--mo-lh-body);
  color: var(--mo-ink);              /* 17.92:1 on white */
}
.mo-footer__ozy a {
  color: var(--mo-accent-deep);      /* 6.41:1 on white */
  text-decoration: underline;
  text-underline-offset: 3px;
}

.mo-footer__disclaimer {
  grid-column: 1 / -1;
  font-size: var(--mo-step--2);
  line-height: 1.5;
  color: var(--mo-ink-muted);
  max-width: 90ch;
}

.mo-footer__divider {
  grid-column: 1 / -1;
  height: 1px;
  border: 0;
  background: var(--mo-border);
  margin-block: 8px;                 /* hex exact */
}

.mo-footer__bottom {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 20px;
  row-gap: 14px;                     /* hex exact */
}
.mo-footer__legal { display: flex; flex-wrap: wrap; gap: 20px; }
.mo-footer__legal a,
.mo-footer__copyright {
  font-size: var(--mo-step--2);
  color: var(--mo-ink-muted);        /* 5.41:1 */
}
.mo-footer__legal a {
  text-decoration: none;
  padding-block: 6px;
  transition: color var(--mo-dur) var(--mo-ease);
}
.mo-footer__legal a:hover,
.mo-footer__legal a:focus-visible {
  color: var(--mo-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (min-width: 600px) {
  .mo-footer__bottom { justify-content: space-between; }
}
@media (min-width: 768px) {
  .mo-footer__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 60px; }
}
@media (min-width: 900px) {
  .mo-footer__inner {
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    column-gap: var(--mo-col-gap);
  }
}


/* ==========================================================================
   17. REDUCED MOTION
   --------------------------------------------------------------------------
   Note the shape of this block: the blanket rule catches anything missed, and
   the named rules that follow restore correct END STATES rather than leaving
   elements frozen mid-transition. The accordion and the drawer still open and
   close - they just do it instantly.
   REDUCED MOTION MUST NEVER MEAN REDUCED FUNCTION.

   JUSTIFYING THE !important FLAGS. Every !important in this stylesheet lives
   in this block or in the print block below, and nowhere else. Both are the
   legitimate case for it: a user-preference override and a print override each
   have to beat every component rule regardless of specificity, and cannot know
   in advance what that specificity will be. If you ever need one in a
   component rule, fix the specificity instead.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto; }

  .mo-js .mo-reveal,
  .mo-js .mo-reveal--in { opacity: 1 !important; transform: none !important; }

  .mo-btn__corners { opacity: 1; }
  .mo-btn--secondary:hover .mo-btn__corner::before { transform: none !important; }
  .mo-btn--primary:hover .mo-btn__circles { opacity: 1 !important; }

  .mo-visual:hover .mo-visual__surface { transform: none !important; }
  .mo-visual:hover .mo-visual__tab { transform: none !important; }

  .mo-faq__a { transition: none !important; }
  .mo-faq__chevron { transition: none !important; }
  .mo-nav { transition: none !important; }
}


/* ==========================================================================
   18. PRINT
   A printed copy should be a readable document: no glass, no dark panel
   burning a cartridge, no nav, no decorative diagrams, and URLs spelled out
   after the links that carry them.
   ========================================================================== */

@media print {
  html, body { background: #fff; color: #000; }

  .mo-nav,
  .mo-nav__sentinel,
  .mo-skip-link,
  .mo-hero__actions,
  .mo-panel__actions,
  .mo-form__actions,
  .mo-visual,
  .mo-proof__accents,
  .mo-btn { display: none !important; }

  /* The reveal base is opacity:0. Without this, a print from a page where the
     observer never fired would come out blank. */
  .mo-js .mo-reveal { opacity: 1 !important; transform: none !important; }

  /* Every answer prints, whether or not it happens to be open on screen. */
  .mo-faq__a { grid-template-rows: 1fr !important; }
  /* visibility, not just overflow: the collapsed panel is now visibility:hidden
     so that a screen reader does not read answers the buttons call collapsed.
     Without this line a printout would silently drop four of the five. */
  .mo-faq__a-inner { overflow: visible !important; visibility: visible !important; }
  .mo-faq__chevron { display: none; }

  .mo-panel {
    background: #fff !important;
    color: #000;
    border: 1px solid #000;
    box-shadow: none;
    padding: 16px;
  }
  .mo-panel::before, .mo-panel::after { display: none; }
  .mo-panel__title, .mo-panel__body, .mo-panel__item, .mo-panel__eyebrow { color: #000 !important; }

  .mo-section, .mo-faq, .mo-contact, .mo-proof, .mo-footer, .mo-hero {
    background: #fff !important;
    padding-block: 12pt;
  }
  .mo-contact__aside, .mo-footer__ozy { box-shadow: none; border: 1px solid #999; }

  a[href^="http"]::after,
  a[href^="mailto"]::after { content: " (" attr(href) ")"; font-size: 9pt; word-break: break-all; }

  .mo-feature, .mo-panel__inner, .mo-contact__grid, .mo-footer__inner { display: block; }
  .mo-faq__item, .mo-feature__copy { break-inside: avoid; }
}
