/* UC Integrator public site.
   Palette taken from the operations console so the product looks like one system:
   white surfaces, deep purple accent, dark slate text, 12px radii, hairline borders.
   Mobile-first: base styles are the phone layout, media queries add the larger ones.
   No CDN, no webfonts, no third-party anything. */

:root {
  --bg:#ffffff; --canvas:#f4f5fa; --deep:#0a1628; --deep-2:#0f2744;
  --accent:#0f2744; --accent-600:#163550;
  --text:#1f2430; --muted:#6b7280; --line:#e8eaf1; --card:#ffffff;
  --ok:#16a34a; --warn:#b45309; --radius:12px;
  --maxw:1080px;
}
* { box-sizing:border-box; }
html,body { margin:0; }
body {
  font:16px/1.6 system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg); color:var(--text); -webkit-text-size-adjust:100%;
}
img { max-width:100%; }
a { color:var(--accent-600); }
.wrap { max-width:var(--maxw); margin:0 auto; padding:0 20px; }
.muted { color:var(--muted); }
.center { text-align:center; }

/* ---------- header ---------- */
.site-head {
  position:sticky; top:0; z-index:20; background:#fff;
  border-bottom:1px solid var(--line);
}
.head-inner { display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:12px 20px; max-width:var(--maxw); margin:0 auto; }
.brand { display:flex; align-items:center; gap:11px; text-decoration:none; color:inherit; }
/* The eMathrix mark, on the navy tile it needs. The supplied artwork is WHITE on
   transparency, so on this white header it would be invisible on its own — the tile is
   not decoration, it is what makes the logo legible, and it is how the mark is presented
   on emathrix.com itself. */
.brand-mark {
  display:grid; place-items:center; width:40px; height:40px; border-radius:11px;
  background:linear-gradient(135deg,var(--accent),#2d5a8a);
  flex:0 0 auto; padding:6px;
}
.brand-mark img { display:block; width:100%; height:100%; object-fit:contain; }
.brand .brand-name { display:block; font-size:16px; font-weight:700; line-height:1.15; }
.brand .by { font-size:11px; color:var(--muted); }
.head-nav { display:flex; align-items:center; gap:8px; }
.head-nav a.navlink { display:none; }

/* ---------- buttons ---------- */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:46px; padding:0 20px; border-radius:10px;
  text-decoration:none; cursor:pointer; border:1px solid transparent; font:inherit;
  font-weight:600;
}
.btn-primary { background:var(--accent); color:#fff; }
.btn-primary:hover { background:var(--accent-600); }
.btn-ghost { background:#fff; color:var(--accent-600); border-color:var(--line); }
.btn-ghost:hover { border-color:var(--accent); }
.btn-block { width:100%; }

/* ---------- hero ---------- */
/* The radial gradient stays: it is what the hero looks like if the poster itself
   fails, so the section is never a bare white box. */
.hero { position:relative; isolation:isolate; overflow:hidden; padding:56px 0 46px; background:
  radial-gradient(1100px 380px at 50% -170px, #eef2f7 0%, #ffffff 70%); }
.hero .wrap { position:relative; z-index:1; }

/* Poster still. Painted as a background rather than poster= so it survives every case
   in which the video does not: refused, errored, reduced motion, or simply not yet
   loaded. The PHONE poster is the default because this file is mobile-first, and it is
   framed like the phone encode — a landscape still under a portrait video would jump
   the moment playback started. */
.hero-media {
  position:absolute; inset:0; z-index:0; overflow:hidden;
  background:url("/static/media/hero-poster-sm.ff90e917d5.jpg") center center/cover no-repeat;
}
/* Scrim over the footage. The panel below does the contrast work; this only softens
   the panel edge so it does not sit on the video as a hard cut-out. */
.hero-media::after {
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(255,255,255,.62), rgba(255,255,255,.34));
}
/* The phone encode is near-square and already framed on the handset, so centre is
   correct here. The desktop rule below biases upward instead, because cover crops a
   1280x754 source hard at wide aspect ratios and dead centre would cut the tracking
   number off the top. */
.hero-video {
  width:100%; height:100%; object-fit:cover; object-position:center center; display:block;
  opacity:0; transition:opacity .5s ease;
}
/* Only ever revealed once the video is actually playing, so a stalled or failed load
   shows the poster rather than a black rectangle. */
.hero-video.is-on { opacity:1; }

/* Readability. A solid panel, not a scrim: contrast then does not depend on what the
   footage happens to be doing. Worst case (black frame) the text composites against
   #f0f0f0 — 13.6:1 for the headline, 8.7:1 for the lede. Buttons are unchanged from
   their appearance on plain white. */
.hero-panel {
  background:rgba(255,255,255,.94);
  border:1px solid rgba(255,255,255,.7);
  border-radius:var(--radius);
  box-shadow:0 12px 40px rgba(31,36,48,.10);
  padding:28px 22px 30px;
}
.hero h1 { font-size:34px; line-height:1.15; margin:0 0 18px; letter-spacing:-.03em;
  max-width:14ch; }
.hero .lede { font-size:18px; color:#3d4351; margin:0 0 26px; max-width:46ch; }
.hero .cta { display:flex; flex-direction:column; gap:10px; }

/* A phone now gets its own encode rather than the poster alone — 640px wide, ~300KB
   instead of ~1MB. main.js still decides WHICH file is fetched, and fetches exactly one:
   CSS could hide a video but never stop the browser downloading it, so the choice has to
   be the absence of the other source, not display:none. */
@media (min-width:700px) {
  .hero { padding:88px 0 80px; }
  /* Desktop poster and desktop framing, to match the wide encode. */
  .hero-media { background-image:url("/static/media/hero-poster.344bfcb6dd.jpg");
    background-position:center 38%; }
  .hero-video { object-position:center 38%; }
  .hero-panel { padding:36px 34px 38px; max-width:520px; }

  /* The text stays left, aligned with every other section on the page. The footage is
     inset from the left instead, so the phone and the tracking number land in the space
     beside the panel rather than under it. Narrowing the box also eases the crop: at
     ~2.5:1 rather than the full-bleed ~4:1, cover keeps far more of the frame's height,
     which is what keeps the tracking number in shot. */
  .hero-media { left:32%; }
  /* Horizontal fade so the inset edge is not a visible vertical seam — the footage
     dissolves into the page's white rather than starting abruptly. */
  .hero-media::after {
    background:linear-gradient(90deg,
      #ffffff 0%, rgba(255,255,255,.72) 18%, rgba(255,255,255,.34) 46%,
      rgba(255,255,255,.30) 100%);
  }
}
.eyebrow {
  display:inline-block; font-size:12px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--accent-600); background:#eef2f7;
  padding:6px 12px; border-radius:999px; margin:0 0 16px;
}

/* ---------- sections ---------- */
section { padding:48px 0; }
section.alt { background:var(--canvas); border-block:1px solid var(--line); }
.sec-head { margin:0 0 26px; max-width:34ch; }
.sec-head h2 { font-size:25px; margin:0 0 8px; letter-spacing:-.02em; line-height:1.2; }
.sec-head p { margin:0; color:var(--muted); }

/* ---------- cards ---------- */
.grid { display:grid; gap:16px; }
.card {
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:22px;
}
.card h3 { margin:0 0 8px; font-size:17px; }
.card p { margin:0; color:#3d4351; max-width:42ch; }
.card .tag {
  display:inline-block; font-size:12px; font-weight:700; color:var(--accent-600);
  background:#eef2f7; padding:4px 10px; border-radius:999px; margin-bottom:10px;
}
.card.feature h3 { font-size:16px; }

/* numbered "what you supply" list */
.steps { list-style:none; margin:0; padding:0; display:grid; gap:12px; }
.steps li {
  background:#fff; border:1px solid var(--line); border-radius:var(--radius);
  padding:16px 16px 16px 56px; position:relative;
}
.steps li .n {
  position:absolute; left:16px; top:16px; width:26px; height:26px; border-radius:8px;
  background:var(--deep); color:#fff; display:grid; place-items:center;
  font-size:13px; font-weight:700;
}
.steps li strong { display:block; margin-bottom:3px; }
.steps li span { color:#3d4351; font-size:15px; }

.callout {
  border-left:4px solid var(--accent); background:#f8fafc; padding:14px 16px;
  border-radius:0 var(--radius) var(--radius) 0; margin-top:18px;
}
.callout p { margin:0; }

/* ---------- form ---------- */
.form-card { background:#fff; border:1px solid var(--line); border-radius:var(--radius);
  padding:20px; }
.field { margin-bottom:16px; }
.field label { display:block; font-weight:600; font-size:14px; margin-bottom:6px; }
.field .hint { display:block; font-weight:400; color:var(--muted); font-size:13px;
  margin-top:2px; }
.field input, .field select, .field textarea {
  width:100%; font:inherit; color:var(--text); background:#fff;
  border:1px solid var(--line); border-radius:10px; padding:11px 12px; min-height:46px;
}
.field textarea { min-height:120px; resize:vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline:none; border-color:var(--accent); box-shadow:0 0 0 3px #d6e0ec;
}
.field.err input, .field.err select { border-color:#dc2626; background:#fff7f7; }
.field .err-msg { display:none; color:#dc2626; font-size:13px; margin-top:5px; }
.field.err .err-msg { display:block; }
.req { color:var(--accent-600); }

/* Honeypot: visually hidden, still reachable by a naive bot. Not display:none —
   some bots skip those; this stays in the layout but off-screen.
   The [hidden] override is the whole point of the attribute in the markup: with this
   stylesheet loaded the field renders off-screen and the trap works; without it the
   attribute stands and a real visitor never sees a field that would misclassify them. */
.hp[hidden] { display:block; }
.hp { position:absolute !important; left:-9999px !important; width:1px; height:1px;
  overflow:hidden; }

.form-note { font-size:13px; color:var(--muted); margin:14px 0 0; }
.error-banner {
  display:none; background:#fef2f2; border:1px solid #fecaca; color:#991b1b;
  padding:11px 13px; border-radius:10px; margin-bottom:16px; font-size:14px;
}
.error-banner.show { display:block; }

/* ---------- contract page ---------- */
.doc { padding:32px 0 56px; }
.doc h1 { font-size:26px; margin:0 0 6px; }
.doc h2 { font-size:19px; margin:34px 0 10px; padding-top:18px;
  border-top:1px solid var(--line); }
.doc h3 { font-size:16px; margin:22px 0 8px; }
.doc p { color:#3d4351; }
.version-pill {
  display:inline-block; background:var(--deep); color:#fff; font-weight:700;
  font-size:12px; letter-spacing:.06em; padding:5px 12px; border-radius:999px;
}
.table-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch;
  border:1px solid var(--line); border-radius:var(--radius); margin:12px 0; }
table.spec { width:100%; border-collapse:collapse; min-width:640px; background:#fff; }
table.spec th, table.spec td {
  text-align:left; padding:10px 12px; border-bottom:1px solid var(--line);
  font-size:14px; vertical-align:top;
}
table.spec th { background:#f8fafc; color:var(--deep-2); font-weight:700;
  white-space:nowrap; }
table.spec tr:last-child td { border-bottom:none; }
table.spec code { font-size:13px; background:#f4f5fa; padding:2px 6px; border-radius:5px; }
.cite { color:var(--muted); font-size:13px; }
.pill-req { color:var(--accent-600); font-weight:700; font-size:12px; }
.pill-opt { color:var(--muted); font-size:12px; }

/* ---------- footer ---------- */
.site-foot { background:var(--deep); color:#b8cedf; padding:30px 0; margin-top:10px; }
.site-foot a { color:#fff; }
.site-foot .cols { display:grid; gap:18px; }
.site-foot h3 { color:#fff; font-size:14px; margin:0 0 8px; }
.site-foot p, .site-foot li { font-size:14px; margin:0 0 6px; }
.site-foot ul { list-style:none; padding:0; margin:0; }
.foot-legal { border-top:1px solid rgba(255,255,255,.15); margin-top:20px;
  padding-top:16px; font-size:13px; }

/* ---------- tablet ---------- */
/* CONSOLIDATED. There were two 640px blocks and two 960px blocks; the later ones
   silently overrode the earlier, so .hero h1 was declared 40px and then 46px and the
   first was dead code. One block per breakpoint, in source order, is the only way that
   stays true as this file grows. */
@media (min-width:640px) {
  .hero { padding:64px 0 52px; }
  .hero h1 { font-size:46px; }
  .hero .lede { font-size:20px; max-width:60ch; }
  .hero .cta { flex-direction:row; }
  section { padding:52px 0; }
  .sec-head h2 { font-size:30px; }
  .grid.two { grid-template-columns:repeat(2,1fr); }
  .grid.three { grid-template-columns:repeat(3,1fr); }
  .form-card { padding:28px; }
  .row2 { display:grid; grid-template-columns:1fr 1fr; gap:0 16px; }
  .site-foot .cols { grid-template-columns:2fr 1fr 1fr; }
  .proof { padding:28px 0; }
  .proof .n { font-size:44px; }
  .proof .l { font-size:13px; }
  .flow-sec { padding:44px 0 14px; }
  .dev-line { display:flex; align-items:baseline; gap:10px; }
  .dev-line strong { display:inline; margin:0; }
}

/* ---------- desktop ---------- */
@media (min-width:960px) {
  /* Inline links replace the drawer only once there is room for them. */
  .head-nav a.navlink {
    display:inline-flex; align-items:center; min-height:40px; padding:0 12px;
    text-decoration:none; color:var(--text); font-weight:600; font-size:15px;
    border-radius:8px;
  }
  .head-nav a.navlink:hover { background:var(--canvas); color:var(--accent-600); }
  .mnav { display:none; }
  .hero h1 { font-size:54px; max-width:15ch; }
  .grid.four { grid-template-columns:repeat(3,1fr); }
  .grid.three { gap:20px; }
}

@media (prefers-reduced-motion:reduce) {
  * { transition:none !important; animation:none !important; }
  /* Belt and braces: main.js already declines to load the video under reduced motion,
     so this only covers the case where the preference is turned on after load. */
  .hero-video { display:none !important; }
}


/* ================= PROOF STRIP ================= */
.proof-band { padding:0; background:var(--canvas); border-block:1px solid var(--line); }
/* auto-fit, not repeat(3,1fr): three fixed columns crowd badly at 320px, where each
   cell would get under 90px and "services we run for you" wraps to four lines. This
   wraps to two and then one as the screen narrows. */
.proof { list-style:none; margin:0; padding:22px 0; display:grid; gap:16px;
  grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); text-align:center; }
.proof li { display:flex; flex-direction:column; align-items:center; gap:2px; }
.proof .n { font-size:34px; font-weight:800; line-height:1; color:var(--accent-600);
  letter-spacing:-.03em; }
.proof .l { font-size:12px; color:var(--muted); max-width:14ch; line-height:1.3; }

/* ================= FLOW DIAGRAM =================
   Inline SVG, styled from here so no inline style attribute is needed and the CSP
   can forbid inline styles outright. */
.flow-sec { padding:34px 0 10px; }
.flow { width:100%; height:auto; display:block; }
/* Mobile-first: the stacked form is the default, so a phone never gets shrunken text.
   The horizontal form appears only when there is room for it (see the 600px query). */
.flow-v { max-width:340px; margin:0 auto; }
.flow-h { display:none; }
.fbox { fill:#fff; stroke:var(--line); stroke-width:1.5; }
.fbox-mid { fill:#f8fafc; stroke:var(--accent); stroke-width:2; }
.ftitle { font:600 15px system-ui,"Segoe UI",Roboto,sans-serif; fill:var(--text);
  text-anchor:middle; }
.ftitle-mid { fill:var(--deep); font-weight:700; }
.fsub { font:500 12px system-ui,"Segoe UI",Roboto,sans-serif; fill:var(--accent-600);
  text-anchor:middle; }
.fcap { font:400 12px system-ui,"Segoe UI",Roboto,sans-serif; fill:var(--muted);
  text-anchor:middle; }
.farrow { fill:none; stroke:var(--accent); stroke-width:2; stroke-linecap:round;
  stroke-linejoin:round; }

/* ================= LINE ICONS ================= */
.icon { width:26px; height:26px; display:block; margin:0 0 12px;
  fill:none; stroke:var(--accent); stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }

/* ================= SMALL UTILITIES (replace inline styles) ================= */
.note-line { margin:18px 0 0; color:var(--muted); font-size:14px; }
.mt-lg { margin-top:28px; }
.foot-legal.bare { border:0; margin:0; padding:0; }
.lede-sub { margin:-8px 0 18px; }

/* ================= DEVELOPER STRIP ================= */
.dev-strip { padding:26px 0; }
.dev-line { margin:0; padding:18px 20px; background:var(--canvas);
  border:1px solid var(--line); border-radius:var(--radius); font-size:15px; }
.dev-line strong { display:block; margin-bottom:2px; }
.dev-line a { font-weight:600; white-space:nowrap; }

/* One box beside another needs ~600px to stay legible; below that the stacked form
   wins. This breakpoint is about the diagram, not the page grid, so it is deliberately
   its own query rather than folded into the 640px one. */
@media (min-width:600px) {
  .flow-v { display:none; }
  .flow-h { display:block; }
}



/* ================= MOBILE NAV =================
   <details>, not a scripted drawer. It opens and closes with no JavaScript, is keyboard
   operable and screen-reader announced natively, and needs no inline style or handler —
   which matters here because the CSP forbids both. Below 960px this is the ONLY route to
   /contract and /privacy: the inline navlinks are display:none until there is room. */
.mnav { position:relative; }
.mnav-btn {
  list-style:none; cursor:pointer; display:inline-flex; align-items:center;
  min-height:46px; padding:0 14px; border:1px solid var(--line); border-radius:10px;
  background:#fff; color:var(--text); font-weight:600; font-size:15px;
}
/* Safari draws its own disclosure triangle unless this is removed. */
.mnav-btn::-webkit-details-marker { display:none; }
.mnav-btn::marker { content:""; }
.mnav[open] .mnav-btn { border-color:var(--accent); color:var(--accent-600); }
.mnav-panel {
  position:absolute; right:0; top:calc(100% + 8px); min-width:224px; z-index:30;
  background:#fff; border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:0 14px 34px rgba(31,36,48,.16); padding:8px; display:grid; gap:2px;
}
.mnav-panel a {
  display:block; padding:11px 12px; border-radius:8px; text-decoration:none;
  color:var(--text); font-weight:600; font-size:15px;
}
.mnav-panel a:hover { background:var(--canvas); color:var(--accent-600); }

/* ================= FOCUS =================
   :focus-visible rather than :focus, so a mouse click does not leave a ring behind but
   a keyboard user can always see where they are. The navy ring is 15:1 against the
   white surfaces it sits on. */
a:focus-visible,
.btn:focus-visible,
.brand:focus-visible,
.head-nav a.navlink:focus-visible,
.mnav-btn:focus-visible,
.mnav-panel a:focus-visible,
summary:focus-visible {
  outline:3px solid var(--accent);
  outline-offset:2px;
  border-radius:8px;
}
/* The primary button is now navy, so a navy ring on it would be near-invisible — under
   the old purple palette --deep was a genuinely different hue, and after the swap it is
   not. A LIGHT ring plus a white gap is what reads against a dark fill. */
.btn-primary:focus-visible {
  outline-color:#7da3cd;              /* --blue-300: 5.4:1 on the navy fill */
  box-shadow:0 0 0 2px #fff;
}

/* ── Hero: track a shipment ──────────────────────────────────────────────────
   The public entry point to the tracking page. Lives in the hero because it is
   the one thing a consignee ever comes here to do, and everything else on this
   page is addressed to truckers. Deliberately reuses .btn; only the input and
   the row need rules of their own. */
.hero-track { margin-top: 1.25rem; }
.hero-track > label {
  display: block;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  opacity: .75;
  margin-bottom: .4rem;
}
.hero-track-row { display: flex; gap: .5rem; flex-wrap: wrap; }
/* Matches .field input exactly. The first version of this styled a translucent white
   input for a DARK hero — but .hero-panel is rgba(255,255,255,.94), so it rendered
   white-on-white: no border, no box, and it read as a broken control rather than a
   field you can type in. Reuse the site's own input treatment instead of inventing a
   second one. */
.hero-track input {
  flex: 1 1 14rem;
  min-width: 0;                 /* or a long number forces the row wider than the panel */
  font: inherit;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 11px 12px;
  min-height: 46px;
}
.hero-track input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px #d6e0ec;
}
.hero-track .btn { min-height: 46px; }
