/* =====================================================================
   Valiente Consulting — vc.css
   Design system, 2026 rebuild.

   Principles
   - Self-hosted fonts. No third-party CDN, no visitor IP leaked to Google.
   - Content is visible without JavaScript. Motion is an enhancement only.
   - Inline SVG icons. No 2.9 MB icon font for fourteen glyphs.
   - Compact vertical rhythm. Whitespace is deliberate, never accidental.
   ===================================================================== */

/* ---------- Fonts (self-hosted, variable, latin subset) ---------- */
@font-face {
  font-family: "Inter Tight";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-tight-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  /* Ink — carried forward from the original navy, deepened for contrast */
  --ink-950: #050d15;
  --ink-900: #08131f;
  --ink-850: #0b1a29;
  --ink-800: #0f2334;
  --ink-700: #16324a;

  /* Accent — the electric blue from the original palette, tuned for AA */
  --accent: #4da3ff;
  --accent-bright: #7ac0ff;
  --accent-deep: #1e6fd9;

  /* Light surfaces */
  --paper: #ffffff;
  --paper-tint: #f4f7fa;
  --paper-line: #e3eaf1;

  /* Text */
  --on-dark: #e8f0f7;
  --on-dark-mute: #93a9bf;
  --on-light: #0b1a29;
  --on-light-mute: #566a7e;

  --line-dark: rgba(255, 255, 255, 0.09);
  --line-dark-strong: rgba(255, 255, 255, 0.16);

  --font-display: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --maxw: 1180px;
  --gutter: clamp(20px, 4vw, 40px);
  --section-y: clamp(56px, 7vw, 92px);

  --r-sm: 8px;
  --r: 12px;
  --r-lg: 18px;

  --nav-h: 74px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--on-light);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.028em;
  margin: 0;
  text-wrap: balance;
}
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
.section { padding: var(--section-y) 0; }
.section.tint { background: var(--paper-tint); }
.section.dark { background: var(--ink-900); color: var(--on-dark); }
.section.dark h2, .section.dark h3 { color: #fff; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--accent); color: var(--ink-950); padding: 12px 20px;
  font-weight: 600; border-radius: 0 0 var(--r-sm) 0;
}
.skip:focus { left: 0; }

/* ---------- Type helpers ---------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-deep);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.eyebrow::before {
  content: ""; width: 22px; height: 1px; background: currentColor; opacity: 0.6;
}
.dark .eyebrow, .hero .eyebrow { color: var(--accent); }

.h-xl { font-size: clamp(2.4rem, 5.6vw, 4rem); }
.h-lg { font-size: clamp(1.9rem, 3.6vw, 2.7rem); }
.h-md { font-size: clamp(1.25rem, 2vw, 1.45rem); }

.lead {
  font-size: clamp(1.05rem, 1.5vw, 1.2rem);
  line-height: 1.6;
  color: var(--on-light-mute);
}
.dark .lead { color: var(--on-dark-mute); }

.section-head { max-width: 720px; margin-bottom: 44px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head.center .eyebrow::before { display: none; }
.section-head p { margin-top: 16px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-body);
  font-weight: 550; font-size: 0.95rem; letter-spacing: -0.005em;
  padding: 12px 22px; border-radius: var(--r-sm);
  border: 1px solid transparent; cursor: pointer;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease),
              color 0.18s var(--ease), transform 0.18s var(--ease);
  white-space: nowrap;
}
.btn svg { width: 16px; height: 16px; min-width: 16px; flex: none; }
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--accent); color: var(--ink-950); }
.btn-primary:hover { background: var(--accent-bright); }
.btn-ghost { border-color: var(--line-dark-strong); color: var(--on-dark); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-outline { border-color: var(--paper-line); color: var(--on-light); background: var(--paper); }
.btn-outline:hover { border-color: var(--accent-deep); color: var(--accent-deep); }
.btn-lg { padding: 15px 28px; font-size: 1rem; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 7px;
  font-weight: 550; font-size: 0.94rem; color: var(--accent-deep);
}
/* Every icon below pins flex: none.

   An inline SVG's min-content width is zero, so as a flex item with the default flex-shrink: 1 it
   can be squeezed to nothing while keeping its height - and the gap beside it stays, which pushes
   the label off centre. That is what "the Login text sits slightly right" was: a 14px lock drawn
   at 0px, with its 8px gap still in front of it. The property is ignored outside a flex container,
   so it costs nothing on the icons that sit in grids. */
.link-arrow svg { width: 15px; height: 15px; transition: transform 0.18s var(--ease); min-width: 15px; flex: none; }
.link-arrow:hover svg { transform: translateX(3px); }

/* ---------- Header ---------- */
.nav {
  position: sticky; top: 0; z-index: 100;
  height: var(--nav-h);
  background: rgba(8, 19, 31, 0.86);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--line-dark);
}
.nav > .container { height: 100%; display: flex; align-items: center; gap: 26px; }
.nav-logo { flex: none; display: flex; align-items: center; }
.nav-logo img { height: 38px; width: auto; }

.nav-menu {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: 4px;
  margin-left: auto;
}
.nav-link {
  display: block; padding: 8px 12px; border-radius: var(--r-sm);
  font-size: 0.9rem; font-weight: 480; color: var(--on-dark-mute);
  white-space: nowrap;
  transition: color 0.16s var(--ease), background 0.16s var(--ease);
}
.nav-link:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }
.nav-link.active { color: #fff; }
.nav-link.active::after {
  content: ""; display: block; height: 2px; margin: 5px 12px -8px;
  background: var(--accent); border-radius: 2px;
}
.nav-cta {
  /* Both an <a> (the account chip, and the noscript fallback) and a <button> (the sign-in
     opener) wear this class, so the button's own styling has to be reset away. */
  background: none; font-family: inherit; cursor: pointer; text-align: left;
  margin-left: 12px; flex: none;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: var(--r-sm);
  border: 1px solid var(--line-dark-strong);
  font-size: 0.88rem; font-weight: 550; color: var(--on-dark);
  white-space: nowrap;
  transition: border-color 0.16s var(--ease), color 0.16s var(--ease);
}
.nav-cta:hover { border-color: var(--accent); color: var(--accent); }
/* Signed in: a live dot rather than a padlock, so the header states the session at a glance. */
.nav-account > .nav-cta { cursor: pointer; }
.nav-account-menu { right: 0; left: auto; min-width: 220px; }
.nav-account-who {
  padding: 8px 12px 10px; margin-bottom: 4px;
  border-bottom: 1px solid var(--line-dark);
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.06em;
  color: var(--on-dark-mute); word-break: break-all;
}
.nav-account-out strong { color: #ff8f7d !important; }

.nav-cta-dot {
  width: 7px; height: 7px; min-width: 7px; border-radius: 50%; background: #63c088;
  box-shadow: 0 0 0 3px rgba(99, 192, 136, 0.18); flex: none;
}
/* min-width as well as width: WebKit leaves a CSS-sized svg out of a flex item's minimum
   width, so when the menu row is squeezed the item shrinks by exactly the icon and the text
   spills right. Chromium counts the icon, which is why this only ever showed in Safari. */
.nav-cta svg { width: 14px; height: 14px; min-width: 14px; flex: none; }

/* Hovering any entry draws the same blue line round it. It was first made for one entry that
   wore it all the time; it reads better as the answer to "where is my pointer" on all of them.
   The border is there and transparent at rest, so nothing moves when it appears. Desktop only:
   on a phone the entries are rows with a rule under them, and there is no hover to answer. */
@media (min-width: 1101px) {
  .nav-menu .nav-link { border: 1px solid transparent; padding: 7px 11px; }
  .nav-menu .nav-link:hover,
  .nav-menu .nav-link:focus-visible,
  .nav-menu .has-dropdown.open > .nav-link {
    border-color: rgba(77, 163, 255, 0.55);
    background: linear-gradient(180deg, rgba(77, 163, 255, 0.12), rgba(77, 163, 255, 0.04));
    color: #fff;
  }
}
/* And the login item itself never shrinks: it is the one thing in the row that must stay intact. */
.nav-login { flex: none; }

/* Dropdown — CSS-only, works on hover and on keyboard focus */
.has-dropdown { position: relative; }
.has-dropdown > .nav-link { display: flex; align-items: center; gap: 5px; }
/* The line under the page you are on is a block under a link. Inside a menu's button, which is a
   flex row, it would be a third item beside the caret and push the next entry away, so there it
   is laid over the button's lower edge instead. */
.has-dropdown > .nav-link.active { position: relative; }
.has-dropdown > .nav-link.active::after { position: absolute; left: 12px; right: 12px; bottom: 0; margin: 0; }
.caret { width: 12px; height: 12px; opacity: 0.7; flex: none; }
.dropdown {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 10;
  min-width: 250px; list-style: none; margin: 0; padding: 7px;
  background: var(--ink-850); border: 1px solid var(--line-dark-strong);
  border-radius: var(--r); box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity 0.16s var(--ease), transform 0.16s var(--ease), visibility 0.16s;
}
.has-dropdown:hover > .dropdown,
.has-dropdown:focus-within > .dropdown,
.has-dropdown.open > .dropdown { opacity: 1; visibility: visible; transform: none; }
.dropdown a { display: block; padding: 9px 12px; border-radius: var(--r-sm); }
/* The suite's menu holds eleven entries, so it runs in two columns, with the overview across both. */
.dropdown-wide { min-width: 560px; display: grid; grid-template-columns: 1fr 1fr; column-gap: 4px; }
.dropdown-wide .dropdown-lead { grid-column: 1 / -1; border-bottom: 1px solid var(--line-dark); margin-bottom: 5px; padding-bottom: 5px; }
.dropdown a:hover { background: rgba(255, 255, 255, 0.06); }
.dropdown strong { display: block; font-size: 0.9rem; font-weight: 550; color: var(--on-dark); }
.dropdown small {
  display: block; font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.06em; color: var(--on-dark-mute); margin-top: 2px;
}

.nav-toggle {
  display: none; margin-left: auto;
  width: 40px; height: 40px; padding: 0;
  background: none; border: 1px solid var(--line-dark-strong);
  border-radius: var(--r-sm); cursor: pointer;
  align-items: center; justify-content: center;
}
.nav-toggle span {
  display: block; width: 17px; height: 1.5px; background: var(--on-dark);
  position: relative; transition: background 0.15s;
}
.nav-toggle span::before, .nav-toggle span::after {
  content: ""; position: absolute; left: 0; width: 17px; height: 1.5px;
  background: var(--on-dark); transition: transform 0.2s var(--ease);
}
.nav-toggle span::before { top: -5.5px; }
.nav-toggle span::after { top: 5.5px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: translateY(5.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after { transform: translateY(-5.5px) rotate(-45deg); }


/* ---------- Header sign-in ----------
   The Login button opens a panel rather than a page: the Cyber Defence Center hand-off,
   then this site's own credentials, with the authenticator field revealed only once the
   password has been accepted. */
.nav-login-panel {
  right: 0; left: auto;
  min-width: 340px; padding: 14px;
  cursor: default;
}
/* The products' sign-in pages: a heading that opens, and a row per product. */
.nav-apps {
  border: 1px solid var(--line-dark-strong); border-radius: var(--r-sm);
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease);
}
.nav-apps:hover, .nav-apps[open] { border-color: rgba(77, 163, 255, 0.55); }
.nav-apps > summary {
  display: flex; align-items: center; gap: 12px; list-style: none; cursor: pointer;
  padding: 12px 13px; border-radius: var(--r-sm);
  font-size: 0.9rem; font-weight: 550; color: var(--on-dark);
}
.nav-apps > summary::-webkit-details-marker { display: none; }
.nav-apps > summary:hover { background: rgba(77, 163, 255, 0.06); }
.nav-apps > summary span { flex: 1; min-width: 0; }
.nav-apps > summary .caret { display: block; width: 14px; height: 14px; min-width: 14px; flex: none; opacity: 0.8; transition: transform 0.16s var(--ease); }
.nav-apps[open] > summary .caret { transform: rotate(180deg); color: var(--accent); opacity: 1; }
.nav-apps-list { padding: 2px 6px 7px; display: grid; gap: 3px; }

/* The wheel. With more than three products the list stops growing: three rows show, the list
   turns under them and snaps so that one entry is always in the middle, and that one wears the
   blue line. Pure scroll-snap - it works with a wheel, a trackpad, a finger or the arrow keys,
   and with scripting off it is still a short scrolling list. The padding above and below is one
   row, which is what lets the first and the last entry reach the middle. */
.nav-apps-wheel {
  --row: 41px;
  display: block; height: calc(var(--row) * 3); padding: var(--row) 6px;
  overflow-y: auto; overscroll-behavior: contain;
  scroll-snap-type: y mandatory; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 30%, #000 70%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 30%, #000 70%, transparent 100%);
}
.nav-apps-wheel::-webkit-scrollbar { display: none; }
.nav-login-panel .nav-apps-wheel .nav-app {
  height: var(--row); padding-top: 0; padding-bottom: 0;
  scroll-snap-align: center;
  opacity: 0.5; transform: scale(0.94);
  transition: opacity 0.18s var(--ease), transform 0.18s var(--ease), border-color 0.16s var(--ease), background 0.16s var(--ease), color 0.16s var(--ease);
}
.nav-login-panel .nav-apps-wheel .nav-app.is-centre,
.nav-login-panel .nav-apps-wheel .nav-app:hover,
.nav-login-panel .nav-apps-wheel .nav-app:focus-visible { opacity: 1; transform: none; }
.nav-login-panel .nav-apps-wheel .nav-app.is-centre {
  border-color: rgba(77, 163, 255, 0.55); color: #fff;
  background: linear-gradient(180deg, rgba(77, 163, 255, 0.12), rgba(77, 163, 255, 0.04));
}
.nav-login-panel .nav-apps-wheel .nav-app.is-centre svg { color: var(--accent); }
/* Without scripting nothing is marked as the middle one, so nothing is dimmed either. */
.nav-apps-wheel:not(.is-live) .nav-app { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .nav-login-panel .nav-apps-wheel .nav-app { transition: none; transform: none; }
}
/* ".dropdown a" above sets every link in a dropdown to a block with its own padding and hover,
   and outranks a single class. These rows are written against the panel so that they win: left
   to the older rule, the arrow drops onto a line of its own under the name. */
.nav-login-panel .nav-app {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 9px; border-radius: 7px; border: 1px solid transparent;
  font-size: 0.88rem; color: var(--on-dark);
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease), color 0.16s var(--ease);
}
.nav-login-panel .nav-app span { flex: 1; min-width: 0; }
.nav-login-panel .nav-app svg { width: 13px; height: 13px; min-width: 13px; flex: none; color: var(--on-dark-mute); }
.nav-login-panel .nav-app:hover, .nav-login-panel .nav-app:focus-visible {
  border-color: rgba(77, 163, 255, 0.55); color: #fff;
  background: linear-gradient(180deg, rgba(77, 163, 255, 0.12), rgba(77, 163, 255, 0.04));
}
.nav-login-panel .nav-app:hover svg, .nav-login-panel .nav-app:focus-visible svg { color: var(--accent); }

.nav-login-rule {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 2px 12px;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: #6f8399;
}
.nav-login-rule::before, .nav-login-rule::after {
  content: ""; flex: 1; height: 1px; background: var(--line-dark);
}

.nav-login-form { display: block; padding: 0 2px; }
.nav-login-label {
  display: block; margin: 0 0 5px;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--on-dark-mute);
}
.nav-login-form input {
  width: 100%; box-sizing: border-box; margin-bottom: 11px;
  padding: 10px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line-dark-strong);
  background: rgba(255, 255, 255, 0.04); color: var(--on-dark);
  font-family: var(--font-body); font-size: 0.92rem;
}
.nav-login-form input::placeholder { color: #5d708a; }
.nav-login-form input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(77, 163, 255, 0.18);
}

/* Two steps: the credentials, then the authenticator code. Each is a pane that collapses to
   nothing when it is not the current one, so the panel grows and shrinks to fit rather than
   leaving an answered box above the one being asked for.
   Only .js sets this up: with no scripting every pane stays open and the form asks for
   everything at once, which is what the plain POST to /Account/Login expects. */
.js .nav-step {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height 0.30s var(--ease), opacity 0.20s var(--ease);
}
.js .nav-step.is-current { max-height: 260px; opacity: 1; }


.nav-login-error {
  display: none; margin: 0 0 10px;
  font-size: 0.82rem; line-height: 1.45; color: #ff8f7d;
}
.nav-login-submit { width: 100%; justify-content: center; margin-top: 2px; }
.nav-login-submit:disabled { opacity: 0.7; cursor: default; transform: none; }

@media (prefers-reduced-motion: reduce) { .js .nav-step { transition: none; } }

@media (max-width: 900px) {
  /* In the mobile sheet the panel is already inline, so it needs no width of its own. */
  .nav-login-panel { min-width: 0; padding: 4px 0 12px; }
  .nav-login-cdc { border-color: var(--line-dark); }
}

/* ---------- Hero ---------- */
.hero {
  position: relative; overflow: hidden;
  background: var(--ink-950); color: var(--on-dark);
  padding: clamp(72px, 11vw, 132px) 0 clamp(56px, 8vw, 96px);
}
.hero-bg { position: absolute; inset: 0; z-index: 0; }
.hero-bg img { width: 100%; height: 100%; object-fit: cover; opacity: 0.3; }
.hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(90% 70% at 12% 0%, rgba(77, 163, 255, 0.16), transparent 60%),
    linear-gradient(180deg, rgba(5, 13, 21, 0.72) 0%, rgba(5, 13, 21, 0.9) 62%, var(--ink-950) 100%);
}
.hero-inner { position: relative; z-index: 1; max-width: 860px; }

.hero-badge {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent);
  border: 1px solid rgba(77, 163, 255, 0.3);
  background: rgba(77, 163, 255, 0.07);
  padding: 7px 14px; border-radius: 100px; margin-bottom: 26px;
}
.hero-badge .dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 4px rgba(77, 163, 255, 0.16);
}
.hero h1 { color: #fff; margin-bottom: 22px; }
/* *Asterisks* in any heading take the accent gradient - see Security/Accent.cs. On a light band
   the brighter end would wash out, so there it runs to the deep blue instead. */
.grad {
  background: linear-gradient(96deg, var(--accent) 8%, var(--accent-bright) 92%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.section:not(.dark):not(.suite) h2 .grad { background-image: linear-gradient(96deg, var(--accent-deep) 8%, var(--accent) 92%); }
.hero-sub { font-size: clamp(1.05rem, 1.6vw, 1.22rem); line-height: 1.6; color: var(--on-dark-mute); max-width: 640px; margin-bottom: 32px; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; }

/* Framework rail under the hero */
.rail {
  position: relative; z-index: 1;
  border-top: 1px solid var(--line-dark);
  margin-top: clamp(48px, 6vw, 76px); padding-top: 22px;
}
.rail-label {
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: #6f8399; margin-bottom: 14px;
}
.rail-items { display: flex; flex-wrap: wrap; gap: 8px 26px; }
.rail-items span {
  font-family: var(--font-mono); font-size: 0.82rem; font-weight: 500;
  color: var(--on-dark-mute); letter-spacing: 0.01em;
}

/* ---------- Split ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 68px); align-items: center; }
.split.reverse > *:first-child { order: 2; }
.split-narrow { grid-template-columns: 1.05fr 0.95fr; align-items: start; }
.split-narrow > *:first-child { position: sticky; top: calc(var(--nav-h) + 32px); }
@media (max-width: 900px) { .split-narrow > *:first-child { position: static; } }

/* ---------- Capability cards ---------- */
.grid { display: grid; gap: 20px; }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
.cols-3 { grid-template-columns: repeat(3, 1fr); }
.cols-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: var(--paper); border: 1px solid var(--paper-line);
  border-radius: var(--r); padding: 26px 24px 28px;
  display: flex; flex-direction: column;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
.card:hover {
  border-color: rgba(77, 163, 255, 0.5);
  box-shadow: 0 10px 34px rgba(11, 26, 41, 0.09);
  transform: translateY(-2px);
}
.card-icon {
  width: 40px; height: 40px; border-radius: 10px; margin-bottom: 18px;
  display: grid; place-items: center; flex: none;
  background: linear-gradient(150deg, rgba(77, 163, 255, 0.15), rgba(30, 111, 217, 0.09));
  color: var(--accent-deep);
}
.card-icon svg { width: 20px; height: 20px; min-width: 20px; flex: none; }
.card h3 { font-size: 1.08rem; margin-bottom: 9px; text-wrap: pretty; }
.card p { font-size: 0.94rem; line-height: 1.6; color: var(--on-light-mute); }
.card .link-arrow { margin-top: auto; padding-top: 16px; }

/* ---------- Stats ---------- */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line-dark); border-radius: var(--r-lg); overflow: hidden;
}
.stat { padding: 30px 26px; border-right: 1px solid var(--line-dark); }
.stat:last-child { border-right: 0; }
.stat .num {
  font-family: var(--font-display); font-size: clamp(2rem, 3.4vw, 2.7rem);
  font-weight: 650; letter-spacing: -0.04em; color: #fff; line-height: 1;
  margin-bottom: 8px;
}
.stat .num em { font-style: normal; color: var(--accent); }
.stat .lbl {
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--on-dark-mute); line-height: 1.5;
}

/* ---------- Numbered steps ---------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--paper-line); border-radius: var(--r); overflow: hidden; }
.step { background: var(--paper); padding: 28px 26px 30px; }
.step .n {
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.12em; color: var(--accent-deep); margin-bottom: 14px;
}
.step h3 { font-size: 1.05rem; margin-bottom: 8px; }
.step p { font-size: 0.93rem; color: var(--on-light-mute); line-height: 1.6; }

/* ---------- Person ---------- */
.person { display: grid; grid-template-columns: auto 1fr; gap: clamp(24px, 4vw, 44px); align-items: start; }
.person-photo {
  width: 132px; height: 132px; border-radius: var(--r); overflow: hidden; flex: none;
  border: 1px solid var(--line-dark);
}
.person-photo img { width: 100%; height: 100%; object-fit: cover; }
.person blockquote {
  margin: 0 0 20px; font-family: var(--font-display); font-weight: 450;
  font-size: clamp(1.2rem, 2.2vw, 1.6rem); line-height: 1.4; letter-spacing: -0.02em;
  color: #fff; text-wrap: balance;
}
.person .who { font-size: 0.92rem; color: var(--on-dark-mute); }
.person .who strong { color: var(--on-dark); font-weight: 600; display: block; }

/* ---------- CTA band ---------- */
.cta-band {
  background: linear-gradient(135deg, var(--ink-800) 0%, var(--ink-700) 55%, #1c4a72 100%);
  border-radius: var(--r-lg); padding: clamp(38px, 5vw, 60px);
  display: grid; grid-template-columns: 1fr auto; gap: 30px; align-items: center;
}
.cta-band h2 { color: #fff; font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin-bottom: 10px; }
.cta-band p { color: var(--on-dark-mute); font-size: 1rem; max-width: 520px; }

/* ---------- Footer ---------- */
.footer { background: var(--ink-950); color: var(--on-dark-mute); padding: 60px 0 28px; font-size: 0.92rem; }
.footer-top { display: grid; grid-template-columns: 1.8fr 1fr 1.1fr 0.8fr 1.2fr; gap: 36px; padding-bottom: 40px; }
.footer h4 {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase; color: #7f93a8;
  margin-bottom: 16px;
}
.footer a { display: block; padding: 5px 0; color: var(--on-dark-mute); transition: color 0.15s; }
.footer a:hover { color: var(--accent); }
.f-logo { height: 32px; width: auto; margin-bottom: 16px; }
.f-about { max-width: 320px; line-height: 1.65; }
.f-social { display: flex; gap: 10px; margin-top: 18px; }
.f-social a {
  width: 36px; height: 36px; border: 1px solid var(--line-dark); border-radius: 9px;
  display: grid; place-items: center; padding: 0;
}
.f-social a:hover { border-color: var(--accent); }
.f-social svg { width: 16px; height: 16px; min-width: 16px; flex: none; }
.footer-bottom {
  border-top: 1px solid var(--line-dark); padding-top: 22px;
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between;
  font-size: 0.82rem; color: #6b7f94;
}
.footer-bottom .fw { font-family: var(--font-mono); letter-spacing: 0.04em; }

/* =====================================================================
   Page-level components — the parts the sub-pages are built from.
   Same rules as the rest of the system: no icon font, no JS dependency,
   visible before the stylesheet finishes doing anything clever.
   ===================================================================== */

/* ---------- Sub-page hero ---------- */
.page-hero {
  position: relative; overflow: hidden;
  background: var(--ink-950); color: var(--on-dark);
  padding: clamp(46px, 6vw, 74px) 0 clamp(40px, 5vw, 62px);
  border-bottom: 1px solid var(--line-dark);
}
.page-hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(80% 110% at 100% 0%, rgba(77, 163, 255, 0.15), transparent 62%),
    linear-gradient(180deg, var(--ink-900) 0%, var(--ink-950) 100%);
}
.page-hero > .container { position: relative; z-index: 1; }
.page-hero h1 { color: #fff; font-size: clamp(2rem, 4.4vw, 3.05rem); margin-bottom: 16px; max-width: 20ch; }
.page-hero .lead { color: var(--on-dark-mute); max-width: 660px; }
.page-hero .art {
  position: absolute; right: -2%; bottom: -12%; z-index: 0;
  width: min(38%, 420px); opacity: 0.5;
  /* Fades out on every side so the artwork dissolves into the hero rather
     than sitting in a visible box. */
  -webkit-mask-image: radial-gradient(closest-side at 58% 46%, #000 38%, transparent 100%);
  mask-image: radial-gradient(closest-side at 58% 46%, #000 38%, transparent 100%);
  pointer-events: none;
}

.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 9px;
  font-family: var(--font-mono); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #6f8399; margin-bottom: 20px;
}
.breadcrumb a { color: var(--on-dark-mute); transition: color 0.15s var(--ease); }
.breadcrumb a:hover { color: var(--accent); }
.breadcrumb .sep { opacity: 0.45; }
.breadcrumb .here { color: var(--on-dark); }

/* ---------- Narrow reading column ---------- */
.container.narrow { max-width: 820px; }

/* ---------- Tick lists ---------- */
.ticks { list-style: none; margin: 16px 0 0; padding: 0; }
.ticks li {
  position: relative; padding-left: 25px; margin-bottom: 9px;
  font-size: 0.93rem; line-height: 1.55; color: var(--on-light-mute);
}
.ticks li:last-child { margin-bottom: 0; }
.ticks li::before {
  content: ""; position: absolute; left: 3px; top: 0.42em;
  width: 6px; height: 10px; border: solid var(--accent-deep);
  border-width: 0 1.8px 1.8px 0; transform: rotate(42deg);
}
.dark .ticks li { color: var(--on-dark-mute); }
.dark .ticks li::before { border-color: var(--accent); }

/* ---------- Chips ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  font-family: var(--font-mono); font-size: 0.76rem; font-weight: 500;
  letter-spacing: 0.04em; padding: 8px 15px; border-radius: 100px;
  border: 1px solid var(--paper-line); background: var(--paper);
  color: var(--on-light-mute);
}
.dark .chip {
  border-color: var(--line-dark-strong); background: rgba(255, 255, 255, 0.03);
  color: var(--on-dark-mute);
}

/* ---------- Image gallery tiles ---------- */
.gallery { display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px; }
.gtile {
  position: relative; margin: 0; grid-column: span 2;
  border-radius: var(--r); overflow: hidden; background: var(--ink-900);
  aspect-ratio: 4 / 3;
}
.gallery .gtile:nth-child(n + 4) { grid-column: span 3; }
.gtile img {
  width: 100%; height: 100%; object-fit: cover; opacity: 0.85;
  transition: transform 0.5s var(--ease), opacity 0.3s var(--ease);
}
.gtile:hover img { transform: scale(1.035); opacity: 1; }
.gtile figcaption {
  position: absolute; inset: auto 0 0 0; padding: 46px 22px 20px;
  background: linear-gradient(180deg, transparent, rgba(5, 13, 21, 0.9) 58%);
  color: #fff;
}
.gtile b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 1.02rem; letter-spacing: -0.02em; margin-bottom: 3px;
}
.gtile span {
  display: block; font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--on-dark-mute);
}

/* ---------- Tool cards ---------- */
.tool-card {
  position: relative; background: var(--paper); border: 1px solid var(--paper-line);
  border-radius: var(--r); padding: 26px 24px 24px;
  display: flex; flex-direction: column;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
a.tool-card:hover {
  border-color: rgba(77, 163, 255, 0.5);
  box-shadow: 0 10px 34px rgba(11, 26, 41, 0.09);
  transform: translateY(-2px);
}
.t-icon {
  width: 40px; height: 40px; border-radius: 10px; margin-bottom: 18px;
  display: grid; place-items: center; flex: none;
  background: linear-gradient(150deg, rgba(77, 163, 255, 0.15), rgba(30, 111, 217, 0.09));
  color: var(--accent-deep);
}
.t-icon svg { width: 20px; height: 20px; min-width: 20px; flex: none; }
.tool-card h3 { font-size: 1.05rem; margin-bottom: 9px; }
.tool-card p { font-size: 0.93rem; line-height: 1.6; color: var(--on-light-mute); }
.t-link {
  display: inline-flex; align-items: center; gap: 7px; margin-top: auto; padding-top: 16px;
  font-weight: 550; font-size: 0.92rem; color: var(--accent-deep);
}
.t-link svg { width: 15px; height: 15px; transition: transform 0.18s var(--ease); min-width: 15px; flex: none; }
a.tool-card:hover .t-link svg { transform: translateX(3px); }

.tool-card.soon { background: var(--paper-tint); border-style: dashed; }
.tool-card.soon .t-icon { background: rgba(86, 106, 126, 0.1); color: var(--on-light-mute); }
.tool-card.soon h3 { color: var(--on-light-mute); }
.tool-card.soon .t-link { color: var(--on-light-mute); }
.badge-soon {
  position: absolute; top: 16px; right: 16px;
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--on-light-mute); border: 1px solid var(--paper-line);
  background: var(--paper); padding: 4px 9px; border-radius: 100px;
}

/* ---------- Contact ---------- */
.contact-grid {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(28px, 4vw, 56px); align-items: start;
}
.contact-list { margin-top: 26px; display: grid; gap: 12px; }
.contact-item {
  display: flex; align-items: center; gap: 15px;
  padding: 16px 18px; border: 1px solid var(--paper-line);
  border-radius: var(--r); background: var(--paper);
  transition: border-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.contact-item:hover { border-color: rgba(77, 163, 255, 0.55); transform: translateY(-1px); }
.ci-ic {
  width: 42px; height: 42px; border-radius: 11px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(150deg, rgba(77, 163, 255, 0.15), rgba(30, 111, 217, 0.09));
  color: var(--accent-deep);
}
.ci-ic svg { width: 19px; height: 19px; min-width: 19px; flex: none; }
.ci-t b { display: block; font-weight: 600; font-size: 0.98rem; }
.ci-t span { display: block; font-size: 0.88rem; color: var(--on-light-mute); }

.founder-card {
  background: var(--ink-900); color: var(--on-dark-mute);
  border: 1px solid var(--line-dark); border-radius: var(--r-lg);
  padding: 30px 28px 32px;
}
.founder-card img {
  width: 96px; height: 96px; border-radius: var(--r); object-fit: cover;
  margin-bottom: 20px; border: 1px solid var(--line-dark);
}
.founder-card h3 { color: #fff; font-size: 1.25rem; margin-bottom: 4px; }
.founder-card .role {
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 16px;
}
.founder-card p { font-size: 0.94rem; line-height: 1.65; }
.founder-card .btn { margin-top: 22px; }

/* ---------- Media cards (briefings) ---------- */
.card.flush { padding: 0; overflow: hidden; }
.card-media { aspect-ratio: 800 / 420; overflow: hidden; background: var(--ink-850); }
.card-media img { width: 100%; height: 100%; object-fit: cover; }
.card-body { padding: 22px 24px 26px; display: flex; flex-direction: column; flex: 1; }

.tag {
  display: inline-block; font-family: var(--font-mono); font-size: 0.64rem;
  font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 100px; border: 1px solid currentColor;
}
.tag-news { color: var(--accent-deep); }
.tag-critical { color: #b3372a; }
.tag-high { color: #a8600f; }
.tag-medium { color: #7d6413; }
.meta {
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em;
  color: var(--on-light-mute);
}
/* On the dark hero the light-surface tag colours fall below AA, so lift them. */
.page-hero .tag-news, .dark .tag-news { color: var(--accent); }
.page-hero .tag-critical, .dark .tag-critical { color: #ff8f7d; }
.page-hero .tag-high, .dark .tag-high { color: #f5b26b; }
.page-hero .tag-medium, .dark .tag-medium { color: #e8cf7a; }
.dark .meta, .page-hero .meta { color: var(--on-dark-mute); }
.card-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }

/* ---------- Long-form article body ---------- */
.prose { font-size: 1.05rem; line-height: 1.75; }
.prose > *:first-child { margin-top: 0; }
.prose h2 { font-size: clamp(1.35rem, 2.4vw, 1.65rem); margin: 38px 0 12px; }
.prose h3 { font-size: 1.15rem; margin: 28px 0 8px; }
.prose p, .prose ul, .prose ol { color: #35485c; margin-bottom: 1.15em; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin-bottom: 0.45em; }
.prose a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.prose strong { color: var(--on-light); font-weight: 600; }
.prose blockquote {
  margin: 26px 0; padding: 4px 0 4px 20px;
  border-left: 3px solid var(--accent); color: var(--on-light-mute);
}
.prose code {
  font-family: var(--font-mono); font-size: 0.88em;
  background: var(--paper-tint); border: 1px solid var(--paper-line);
  padding: 1px 6px; border-radius: 5px;
}
.prose pre {
  background: var(--ink-900); color: var(--on-dark); border-radius: var(--r);
  padding: 18px 20px; overflow-x: auto; font-size: 0.88rem; line-height: 1.6;
}
.prose pre code { background: none; border: 0; padding: 0; color: inherit; }
.prose img { border-radius: var(--r); margin: 26px 0; }
.prose hr { border: 0; border-top: 1px solid var(--paper-line); margin: 34px 0; }
.prose table { width: 100%; border-collapse: collapse; font-size: 0.94rem; margin-bottom: 1.3em; }
.prose th, .prose td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--paper-line); }
.prose th { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--on-light-mute); }

.article-foot {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: 42px; padding-top: 26px; border-top: 1px solid var(--paper-line);
}

/* ---------- Split media ---------- */
.split-media { border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line-dark); }
.split-media img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Notice ---------- */
.notice {
  border: 1px solid var(--paper-line); border-left: 3px solid var(--accent);
  background: var(--paper-tint); border-radius: var(--r-sm);
  padding: 16px 20px; font-size: 0.94rem; color: var(--on-light-mute);
}

/* ---------- Responsive (page-level components) ---------- */
@media (max-width: 900px) {
  .page-hero .art { display: none; }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .gtile, .gallery .gtile:nth-child(n + 4) { grid-column: span 1; }
  .contact-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .gallery { grid-template-columns: 1fr; }
  .page-hero h1 { max-width: none; }
}


/* ---------- Tool locks and the tool overlay ---------- */
.t-lock {
  display: inline-flex; vertical-align: baseline; margin-left: 6px;
  color: var(--on-light-mute);
}
.t-lock svg { width: 13px; height: 13px; min-width: 13px; flex: none; }
.t-lock-open { color: var(--accent-deep); }
.t-lock-click { cursor: pointer; }
.tool-card.locked:hover .t-lock-click { color: var(--accent-deep); }
.tool-card.locked { cursor: pointer; }

/* A tool the visitor may not open: legible, obviously unavailable, still describes itself
   so the catalogue is useful even where access is not granted. */
.tool-card.locked { background: var(--paper-tint); border-style: dashed; }
.tool-card.locked h3, .tool-card.locked .t-link { color: var(--on-light-mute); }
.tool-card.locked .t-icon { background: rgba(86, 106, 126, 0.1); color: var(--on-light-mute); }
.tool-card.locked:hover { border-color: var(--paper-line); box-shadow: none; transform: none; }

/* The overlay. A tool opens inside the site rather than navigating away from it, so the
   visitor keeps the header, the context and the back-out. Without JavaScript the card is a
   plain link and the tool opens as an ordinary page - nothing is lost. */
.tool-overlay {
  position: fixed; inset: 0; z-index: 500;
  display: flex; flex-direction: column;
  background: rgba(5, 13, 21, 0.72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s var(--ease);
}
.tool-overlay.open { opacity: 1; pointer-events: auto; }
.tool-overlay-bar {
  flex: none; height: 56px; display: flex; align-items: center; gap: 14px;
  padding: 0 clamp(14px, 3vw, 26px);
  background: var(--ink-900); border-bottom: 1px solid var(--line-dark); color: var(--on-dark);
}
.tool-overlay-title {
  font-family: var(--font-display); font-weight: 600; font-size: 1.02rem;
  letter-spacing: -0.02em; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tool-overlay-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.tool-overlay-actions a, .tool-overlay-actions button {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: var(--r-sm);
  border: 1px solid var(--line-dark-strong); background: none;
  font-family: var(--font-body); font-size: 0.86rem; font-weight: 500;
  color: var(--on-dark); cursor: pointer;
  transition: border-color 0.15s var(--ease), color 0.15s var(--ease);
}
.tool-overlay-actions a:hover, .tool-overlay-actions button:hover { border-color: var(--accent); color: var(--accent); }
.tool-overlay-frame { flex: 1; width: 100%; border: 0; background: var(--paper); }
body.tool-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) { .tool-overlay { transition: none; } }

/* ---------- Motion (progressive enhancement only) ----------
   .reveal is only hidden when JS has confirmed it can reveal it again.
   Without JS, or with reduced motion, everything renders fully visible. */
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.in {
  opacity: 1; transform: none;
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
.js .reveal.d2.in { transition-delay: 0.07s; }
.js .reveal.d3.in { transition-delay: 0.14s; }
.js .reveal.d4.in { transition-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .reveal.in { opacity: 1; transform: none; transition: none; }
  .btn:hover, .card:hover { transform: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1080px) {
  .cols-4 { grid-template-columns: repeat(2, 1fr); }
  .footer-top { grid-template-columns: 1fr 1fr 1fr; }
  .footer-top > div:first-child { grid-column: 1 / -1; }
}
@media (max-width: 1100px) {
  .nav-toggle { display: inline-flex; }
  .nav > .container { gap: 14px; }
  .nav-menu {
    position: fixed; inset: var(--nav-h) 0 auto; flex-direction: column;
    align-items: stretch; gap: 0; padding: 12px var(--gutter) 22px;
    background: var(--ink-900); border-bottom: 1px solid var(--line-dark);
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
    /* The menu is taller than a phone. Without this it is a fixed block whose lower half -
       the Login button, and the sign-in form under it - is simply off the bottom of the
       screen with no way to reach it. dvh first, because the address bar on iOS eats into
       vh and the last item is exactly what gets eaten. */
    max-height: calc(100vh - var(--nav-h));
    max-height: calc(100dvh - var(--nav-h));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  .nav-menu.open { opacity: 1; transform: none; pointer-events: auto; }
  .nav-link { padding: 13px 4px; font-size: 1rem; border-bottom: 1px solid var(--line-dark); }
  .nav-link.active::after { display: none; }
  .nav-link.active { color: var(--accent); }
  .nav-cta { margin: 16px 0 0; justify-content: center; padding: 13px; }
  .dropdown {
    position: static; opacity: 1; visibility: visible; transform: none;
    background: none; border: 0; box-shadow: none;
    padding: 4px 0 10px 14px; min-width: 0;
    border-bottom: 1px solid var(--line-dark);
  }

  /* The sign-in panel is the exception: laid out flat it is most of the menu's height, and
     on a touch screen there is no hover to reveal it with. Closed until the button is
     pressed - which also gives that button something to do on a phone. */
  .nav-login > .dropdown { display: none; }
  .nav-login.open > .dropdown { display: block; }
  /* And so is the suite's list: eleven entries laid flat would push everything under them off
     the screen. Closed until its name is pressed, one column, and the caret stays to say so. */
  .nav-suite > .dropdown { display: none; }
  .nav-suite.open > .dropdown { display: block; }
  .nav-suite .dropdown-lead { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
  .nav-login.open > .nav-cta { border-color: var(--accent); }
  .caret { display: none; }
  .nav-suite .caret { display: block; margin-left: auto; }
  .nav-suite.open .caret { transform: rotate(180deg); }
  .split, .split-narrow { grid-template-columns: 1fr; }
  .split.reverse > *:first-child { order: 0; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat:nth-child(2) { border-right: 0; }
  .stat:nth-child(-n+2) { border-bottom: 1px solid var(--line-dark); }
  .steps { grid-template-columns: 1fr; }
  .cta-band { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  body { font-size: 16px; }
  .cols-4, .cols-3, .cols-2 { grid-template-columns: 1fr; }
  .person { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr 1fr; }
  .footer-top > div:first-child { grid-column: 1 / -1; }
}

/* ---------- Print ---------- */
@media print {
  .nav, .hero-bg, .cta-band, .footer { background: none !important; color: #000 !important; }
  .js .reveal { opacity: 1 !important; transform: none !important; }
}

/* The way out of the sign-in panel for somebody who cannot get in. */
.nav-login-forgot {
  display: block; margin-top: 12px; text-align: center;
  font-size: 0.82rem; color: var(--on-dark-mute);
}
.nav-login-forgot:hover { color: var(--accent); }

/* Sign out is a form, so the button inside it has to look like the links around it. */
.nav-account-outform { margin: 0; }
button.nav-account-out {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; padding: 9px 12px; border-radius: var(--r-sm);
  font: inherit; color: inherit; cursor: pointer;
}
button.nav-account-out:hover { background: rgba(255, 255, 255, 0.06); }

/* The Tools trigger is a button so that it opens its menu instead of navigating, and it must sit
   exactly like the links beside it.
   This declares only what .nav-link does not, so the two never fight: .nav-link owns display,
   padding, radius, size, weight and colour; this strips the chrome a button brings of its own.
   Both earlier attempts were wrong in opposite directions - as button.nav-link it outranked
   .nav-link and the item lost its padding and colour; wrapped in :where() it fell to zero
   specificity, where it can be beaten by any bare `button` rule and by nothing at all, which is
   how it ends up looking like an unstyled form control. */
button.nav-link {
    background: none;
    border: 0;
    margin: 0;
    font-family: inherit;
    line-height: inherit;
    text-align: left;
    cursor: pointer;
}

/* A Portable card carries the facts you want before running something you downloaded. */

/* ---------- Portable cards ----------
   Fixed height and clamped text, so a row of them is a row rather than a staircase. The height is
   the tallest a card needs, not the tallest one present: a card that grows to fit its own summary
   makes every neighbour look broken. */
.portable-card {
  height: 340px;
  overflow: hidden;
}
.portable-card:hover {
  border-color: rgba(77, 163, 255, 0.5);
  box-shadow: 0 10px 34px rgba(11, 26, 41, 0.09);
}

/* The corner mark. Contained rather than cropped, so a wide logo and a square icon both sit
   correctly without either being distorted. It shares the top of the card with the icon tile on
   the left and clears the title below, which starts under both. */
.t-mark {
  position: absolute; top: 16px; right: 18px;
  width: 112px; height: 112px; object-fit: contain; object-position: top right;
  border-radius: 8px;
}
/* Not greyed out on a planned card: the dashed border and tinted background already say that,
   and a desaturated logo reads as a picture that failed to load rather than a tool not yet out. */
.portable-card.soon .t-mark { opacity: .8; }

/* Two lines of title, three of summary, and then it stops - with an ellipsis rather than a
   sentence cut mid-word. */
.portable-card h3 {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.6em;
  /* The image now reaches down beside the title rather than stopping above it. Absolute
     positioning means text does not flow around it, so the title is given the room instead -
     without this a long name runs underneath the picture. */
  padding-right: 124px;
}
.portable-card .t-summary {
  /* pre-line so a summary written over several lines keeps them - the text is a description
     somebody laid out, not a paragraph to be reflowed. Runs of spaces still collapse. */
  white-space: pre-line;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* A planned card carries no filename, size or checksum line, so it has room for more of the
   description rather than the empty band that space became. */
.portable-card.soon .t-summary { -webkit-line-clamp: 6; }

.t-actions {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: auto; padding-top: 16px;
}
.t-actions .t-link { margin-top: 0; padding-top: 0; }

/* The status a card wears while it has no build behind it - "Coming soon" by default, or
   whatever that card says of itself. The same pill the badge used to be, but sitting in the
   action row at the foot rather than pinned to the top corner, which is the image's now. */
.t-status {
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--on-light-mute); border: 1px solid var(--paper-line);
  background: var(--paper); padding: 4px 9px; border-radius: 100px;
}

/* A card with a build for each system names them under the summary; the tile above still hands
   out the one for the visitor's own system. */
.t-builds { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; }
.t-build {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 0.82rem; font-weight: 600; color: var(--accent-deep); white-space: nowrap;
}
.t-build svg { width: 13px; height: 13px; min-width: 13px; flex: none; }
.t-build small { font-weight: 400; color: var(--on-light-mute); }
.t-build:hover { text-decoration: underline; text-underline-offset: 2px; }
.t-hash-for { margin: 10px 0 4px; font-size: 0.8rem; color: var(--on-light-mute); }

.t-terms-open {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: 0.82rem; color: var(--on-light-mute);
  text-decoration: underline; text-underline-offset: 2px; white-space: nowrap;
}
.t-terms-open:hover { color: var(--accent-deep); }

/* The terms cover their own card and nothing else - they belong to this tool, not to the page. */
.t-terms {
  /* -1px, not 0: inset resolves against the padding box, so inset:0 leaves the card's own 1px
     border showing round the outside and the panel is visibly 2px short of covering it. */
  position: absolute; inset: -1px; z-index: 3;
  display: flex; flex-direction: column;
  padding: 22px 22px 18px;
  background: var(--paper); border: 1px solid var(--paper-line); border-radius: var(--r);
}
.t-terms[hidden] { display: none; }
/* min-height: 0 is what lets a flex child shrink below its content and scroll; without it the
   body grows to fit the text and the panel quietly clips the end of a long usage note. */
.t-terms-body { overflow-y: auto; flex: 1; min-height: 0; padding-right: 4px; }
.t-terms h4 {
  margin: 0 0 3px; font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--on-light-mute); font-family: var(--font-mono); font-weight: 500;
}
.t-terms p { margin: 0 0 14px; font-size: 0.86rem; line-height: 1.55; white-space: pre-line; }
.t-hash-row { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; }
.t-hash {
  flex: 1; min-width: 0; font-family: var(--font-mono); font-size: 0.72rem; line-height: 1.4;
  word-break: break-all; color: var(--on-light);
}
.t-hash-row .btn { flex: none; }
.t-terms .t-hash-note { font-size: 0.78rem; color: var(--on-light-mute); }

/* An ordinary card is one link, and the overlay script needs it to stay one. The wrapper gives
   the Licence & Info button and its panel somewhere to live beside the link rather than in it. */
.t-cardwrap { position: relative; display: flex; }
.t-cardwrap > .tool-card { flex: 1; width: 100%; }
.t-cardwrap > .tool-card:not(.soon) { padding-bottom: 24px; }
.t-terms-float { position: absolute; right: 24px; bottom: 26px; z-index: 2; }
.t-terms p:last-child { margin-bottom: 0; }
.t-terms-close {
  margin-top: 14px; align-self: flex-start;
  background: none; border: 1px solid var(--paper-line); border-radius: 8px;
  padding: 7px 14px; cursor: pointer; font: inherit; font-size: 0.84rem; color: var(--on-light);
}
.t-terms-close:hover { border-color: var(--accent-deep); color: var(--accent-deep); }

@media (max-width: 760px) {
  /* One per row, so a fixed height only wastes space. */
  .portable-card { height: auto; min-height: 300px; }
}

/* The tile is the download control on a Portable card, so it has to look like one. */
a.t-icon-link {
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), transform 0.18s var(--ease);
}
a.t-icon-link:hover {
  background: linear-gradient(150deg, rgba(77, 163, 255, 0.30), rgba(30, 111, 217, 0.18));
  transform: translateY(-1px);
}
a.t-icon-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }


/* ==========================================================================
   The product suite band
   One hub and the products around it, drawn as what they are: a system. The
   hub sits above, a rule runs down and across, and each product hangs off it.
   On the dark band, with the accent behind it, because it is the one section
   of the page that is meant to be seen first.
   ========================================================================== */
.section.suite {
  position: relative; overflow: hidden; color: var(--on-dark);
  background:
    radial-gradient(900px 420px at 50% -8%, rgba(77, 163, 255, 0.2), transparent 70%),
    linear-gradient(180deg, var(--ink-900), var(--ink-950));
  border-top: 1px solid var(--line-dark); border-bottom: 1px solid var(--line-dark);
}
.suite-head { max-width: 860px; margin: 0 auto 40px; text-align: center; }
.suite-head .hero-badge { margin-bottom: 20px; }
.suite-head h2 { color: #fff; margin-bottom: 16px; }
.suite-head .lead { color: var(--on-dark-mute); margin: 0 auto; }

.suite-map { display: flex; flex-direction: column; align-items: center; }
.suite-hub, .suite-spoke {
  display: flex; flex-direction: column; gap: 6px; text-decoration: none;
  border: 1px solid var(--line-dark-strong); border-radius: var(--r);
  background: rgba(255, 255, 255, 0.035); color: var(--on-dark-mute);
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease), transform 0.18s var(--ease);
}
.suite-hub:hover, .suite-spoke:hover { border-color: var(--accent); background: rgba(77, 163, 255, 0.08); transform: translateY(-2px); }
.suite-hub strong, .suite-spoke strong { color: #fff; font-family: var(--font-display); font-weight: 600; line-height: 1.25; }
.suite-hub span, .suite-spoke span { font-size: 0.92rem; line-height: 1.55; }

.suite-hub {
  width: min(100%, 560px); padding: 26px 28px; text-align: center; align-items: center;
  border-color: rgba(77, 163, 255, 0.5);
  background: linear-gradient(180deg, rgba(77, 163, 255, 0.14), rgba(77, 163, 255, 0.04));
  box-shadow: 0 0 0 6px rgba(77, 163, 255, 0.05), 0 24px 60px rgba(0, 0, 0, 0.35);
}
.suite-hub strong { font-size: 1.3rem; }
.suite-kicker {
  font-family: var(--font-mono); font-size: 0.64rem !important; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--accent);
}
.suite-icon {
  width: 42px; height: 42px; min-width: 42px; flex: none; border-radius: 11px;
  display: grid; place-items: center; margin-bottom: 6px;
  background: rgba(77, 163, 255, 0.14); color: var(--accent-bright);
}
.suite-icon svg { width: 21px; height: 21px; min-width: 21px; flex: none; }

/* The rule from the hub to the products: down, then across. */
.suite-wire { width: 1px; height: 34px; background: linear-gradient(180deg, rgba(77, 163, 255, 0.7), rgba(77, 163, 255, 0.35)); }
.suite-spokes {
  /* --n is how many products hang off the hub; the template sets it. The rule across the top
     runs from the middle of the first to the middle of the last, whatever their number. */
  --n: 4;
  position: relative; width: 100%;
  display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 16px; padding-top: 22px;
}
.suite-spokes::before {
  content: ""; position: absolute; top: 0; height: 1px;
  left: calc(50% / var(--n)); right: calc(50% / var(--n));
  background: rgba(77, 163, 255, 0.35);
}
.suite-spoke { position: relative; padding: 22px 18px; }
.suite-spoke::before {
  content: ""; position: absolute; top: -22px; left: 50%; width: 1px; height: 22px;
  background: rgba(77, 163, 255, 0.35);
}
.suite-spoke strong { font-size: 1.05rem; }

.suite-why {
  max-width: 860px; margin: 40px auto 0; text-align: center;
  font-size: 1.02rem; line-height: 1.7; color: var(--on-dark-mute);
}
.suite-why strong { color: #fff; font-weight: 550; }
.section.suite > .container > p { text-align: center; }

/* Below the width where they fit in one row the products wrap, and a rule drawn for one row
   would point at nothing. The line from the hub stays; the rest is left to the cards. */
@media (max-width: 1100px) {
  .suite-spokes { grid-template-columns: repeat(3, minmax(0, 1fr)); padding-top: 0; }
  .suite-spokes::before, .suite-spoke::before { display: none; }
  .suite-wire { height: 24px; }
}
@media (max-width: 760px) {
  .suite-spokes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .suite-spokes { grid-template-columns: 1fr; padding-top: 0; gap: 12px; }
  .suite-spokes::before, .suite-spoke::before { display: none; }
  .suite-wire { height: 18px; }
}

/* ==========================================================================
   The suite as a system
   The same band, drawn further: under the hub and its products, the gateway
   behind the first product, the tunnel to the gateway at the customer, and
   what stands behind that. The drawing is fixed and the words are an
   editor's (see SuiteRoles). Everything is placed on a four-column grid by
   its class, so the order in the markup can be the order it reads in on a
   phone, where the drawing gives way to a list.
   ========================================================================== */
.sysmap { position: relative; }
.sys-branch {
  --gap: 16px; --wire: rgba(77, 163, 255, 0.42);
  position: relative; width: 100%; margin-top: 34px;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 0;
}
.sys-branch > .suite-spoke { z-index: 1; }
.sys-branch > .suite-spoke::before { display: none; }
.sys-zone { border: 1px dashed rgba(147, 169, 191, 0.32); border-radius: 16px; background: rgba(255, 255, 255, 0.012); }
.sys-zone > span {
  display: block; padding: 12px 16px 0;
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500; line-height: 1; letter-spacing: 0.16em;
  text-transform: uppercase; color: #6f8399;
}
.sys-zone.soc { grid-column: 1; grid-row: 1; margin-bottom: -14px; }
.sys-zone.site { grid-column: 2 / span 3; grid-row: 1 / span 2; }
.sys-zone.ext { grid-column: 1; grid-row: 2; margin-top: 30px; padding-bottom: 14px; align-self: start; z-index: 1; }

.sys-secure { border-color: rgba(77, 163, 255, 0.42); background: linear-gradient(180deg, rgba(77, 163, 255, 0.10), rgba(77, 163, 255, 0.03)); }
.soc-secure { grid-column: 1; grid-row: 1; margin: 40px 14px 0; align-self: start; }
.siem-secure { grid-column: 3; grid-row: 1; margin: 40px 14px 0; }
.sys-ot { grid-column: 4; grid-row: 1; margin: 40px 14px 0; }
.sys-siem { grid-column: 3; grid-row: 2; margin: 30px 14px 14px; }
.sys-agents { grid-column: 4; grid-row: 2; margin: 30px 14px 14px; }

/* From the first product, in the row above, down to its gateway. 75px is the 34px between the
   rows, the 40px the card stands below the top of its frame, and the border. */
.sys-branch > .soc-secure::before { display: block; content: ""; position: absolute; left: 50%; top: -75px; width: 1px; height: 75px; background: var(--wire); }
/* Down from the customer's gateway to the system behind it. */
.sys-branch > .sys-siem::before { display: block; content: ""; position: absolute; left: 50%; top: -31px; width: 1px; height: 30px; background: var(--wire); }
/* A line with an arrowhead, from a card to the card on its left. */
.sys-into::after { content: ""; position: absolute; top: 50%; left: -45px; width: 44px; height: 0; border-top: 1px solid rgba(77, 163, 255, 0.75); }
.sys-into > .suite-icon::before {
  content: ""; position: absolute; top: 50%; left: -44px; width: 8px; height: 8px; margin-top: -4.5px;
  border-top: 1.5px solid var(--accent); border-right: 1.5px solid var(--accent); transform: rotate(-135deg);
}
.suite-spoke .sys-via, .sys-zone .sys-via {
  display: block; margin-top: 8px; font-style: normal;
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500; line-height: 1.3; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent);
}

.sys-tunnel { grid-column: 2; grid-row: 1; z-index: 1; align-self: center; margin: 40px -30px 0; display: flex; flex-direction: column; align-items: center; gap: 9px; }
.sys-tunnel span { font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500; line-height: 1; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); white-space: nowrap; }
.sys-tunnel i { position: relative; display: block; width: 100%; height: 0; border-top: 1px dashed rgba(77, 163, 255, 0.75); }
.sys-tunnel i::before, .sys-tunnel i::after { content: ""; position: absolute; top: -5px; width: 8px; height: 8px; border-top: 1.5px solid var(--accent); border-right: 1.5px solid var(--accent); }
.sys-tunnel i::before { left: 1px; transform: rotate(-135deg); }
.sys-tunnel i::after { right: 1px; transform: rotate(45deg); }
.sys-tunnel small { font-size: 0.78rem; color: var(--on-dark-mute); white-space: nowrap; }

/* Somebody else's services: plainer, smaller, grey where the suite's own are blue. */
.sys-mini { display: flex; gap: 12px; align-items: flex-start; margin: 12px 14px 0; padding: 14px; border: 1px solid var(--line-dark-strong); border-radius: var(--r); background: rgba(255, 255, 255, 0.03); }
.sys-mini .suite-icon { width: 34px; height: 34px; min-width: 34px; border-radius: 9px; margin: 0; background: rgba(147, 169, 191, 0.14); color: #c5d3e0; }
.sys-mini .suite-icon svg { width: 17px; height: 17px; min-width: 17px; }
.sys-mini strong { display: block; color: #fff; font-family: var(--font-display); font-weight: 600; font-size: 0.98rem; line-height: 1.25; }
.sys-mini div > span { display: block; margin-top: 3px; font-size: 0.84rem; line-height: 1.45; color: var(--on-dark-mute); }
.sys-zone .sys-direct { margin: 12px 16px 0; }

/* The line from those services round the outside of the drawing and into the first product.
   Where it starts and ends depends on the text above it, so vc.js measures and places it; until
   then, and wherever it cannot, the line of text in the frame says the same thing. */
.sys-bus { position: absolute; z-index: 1; border: 1px solid rgba(77, 163, 255, 0.75); border-right: 0; border-radius: 10px 0 0 10px; pointer-events: none; }
.sys-bus::after { content: ""; position: absolute; top: -5.5px; right: 0; width: 8px; height: 8px; border-top: 1.5px solid var(--accent); border-right: 1.5px solid var(--accent); transform: rotate(45deg); }
.sys-bus span { position: absolute; left: -9px; top: 50%; transform: translate(-50%, -50%) rotate(-90deg); white-space: nowrap; font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.sysmap.has-bus .sys-direct { display: none; }

/* Narrower than the drawing needs: a list, in reading order, with the frames as headings. */
@media (max-width: 1100px) {
  .sys-branch { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
  .sys-branch > .suite-spoke, .sys-zone.ext { margin: 0; align-self: stretch; }
  /* Four products read better two and two than three and one. */
  .sysmap .suite-spokes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sys-zone.soc, .sys-zone.site { border: 0; background: none; margin: 8px 0 -4px; }
  .sys-zone.soc > span, .sys-zone.site > span { padding: 0 2px; }
  .sys-branch > .soc-secure::before, .sys-branch > .sys-siem::before, .sys-into::after, .sys-into > .suite-icon::before { display: none; }
  .sys-tunnel { margin: 0; flex-direction: row; gap: 10px; justify-content: center; padding: 2px 0; }
  .sys-tunnel i { display: none; }
  .sys-bus { display: none; }
}
@media (max-width: 640px) {
  .sysmap .suite-spokes { grid-template-columns: 1fr; }
}
