/* ===================================================================
   blindfoldhq.com

   The site borrows the app's own vocabulary so the download feels like
   a continuation rather than a jump: Fluent 2 colour and radii, the
   Segoe UI Variable ramp, the closed-eye mark, and the radial night
   gradient from the app icon.

   Dark only, on purpose. The product is nocturnal and the visitor is
   usually alone in a dim room; a light theme would be the wrong voice
   and would fight the Store badge, which ships dark.
   =================================================================== */

:root {
  /* --- ground: the app icon's own gradient --- */
  --night-0: #182742;
  --night-1: #0d1424;
  --night-2: #0a0f1c;

  /* --- surfaces, Fluent dark --- */
  --card: rgba(255, 255, 255, 0.045);
  --card-hover: rgba(255, 255, 255, 0.075);
  --stroke: rgba(255, 255, 255, 0.08);
  --stroke-strong: rgba(255, 255, 255, 0.14);
  --divider: rgba(255, 255, 255, 0.07);

  /* --- text --- */
  --text: #ffffff;
  --text-2: rgba(255, 255, 255, 0.76);
  --text-3: rgba(255, 255, 255, 0.5);
  --text-4: rgba(255, 255, 255, 0.34);

  /* --- accent + system, straight from fluent.css --- */
  --accent: #60cdff;
  --accent-hover: #7fd8ff;
  --accent-tint: rgba(96, 205, 255, 0.12);
  --on-accent: #06121c;
  --critical: #ff99a4;
  --critical-tint: rgba(255, 153, 164, 0.12);
  --success: #6ccb5f;
  --caution: #fce100;

  /* --- shape + motion --- */
  --r-control: 4px;
  --r-card: 8px;
  --r-big: 14px;
  --ease-out: cubic-bezier(0, 0, 0, 1);
  --fast: 150ms;
  --normal: 250ms;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-lift: 0 24px 60px rgba(0, 0, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.4);

  --wrap: 1120px;
  --nav-h: 64px;

  color-scheme: dark;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100%;
  font-family: "Segoe UI Variable Text", "Segoe UI Variable", "Segoe UI",
    -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-2);
  background: var(--night-2);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The icon's radial, stretched over the top of the page: bright where
   the eye is, falling away to near-black by the fold. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(
      110% 70% at 50% -10%,
      var(--night-0) 0%,
      var(--night-1) 55%,
      var(--night-2) 100%
    );
}

h1,
h2,
h3 {
  font-family: "Segoe UI Variable Display", "Segoe UI Variable", "Segoe UI",
    -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  color: var(--text);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.25rem, 1.4rem + 3.4vw, 3.9rem);
  letter-spacing: -0.03em;
}

h2 {
  font-size: clamp(1.65rem, 1.2rem + 1.9vw, 2.6rem);
}

h3 {
  font-size: 1.125rem;
  line-height: 1.35;
}

a {
  color: var(--accent);
  text-decoration: none;
}

strong,
b {
  color: var(--text);
  font-weight: 600;
}

em {
  font-style: normal;
}

img,
svg {
  display: block;
  max-width: 100%;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 24px;
}

.wrap.narrow {
  max-width: 760px;
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  left: 16px;
  top: 16px;
  z-index: 99;
  padding: 10px 16px;
  border-radius: var(--r-control);
  background: var(--accent);
  color: var(--on-accent);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-control);
}

/* ===================================================================
   Nav
   =================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background var(--normal) var(--ease-out),
    border-color var(--normal) var(--ease-out);
}

.nav.stuck {
  background: rgba(10, 15, 28, 0.82);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-bottom-color: var(--divider);
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: var(--r-card);
  background: linear-gradient(160deg, #1b2c4a, #0b1120);
  box-shadow: inset 0 0 0 1px var(--stroke);
}

.brand-mark svg,
.mock-brand svg,
.last-mark svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 5;
  stroke-linecap: round;
}

.nav-links {
  display: flex;
  gap: 26px;
  margin-left: auto;
  font-size: 0.9375rem;
}

.nav-links a {
  color: var(--text-3);
  transition: color var(--fast) var(--ease-out);
}

.nav-links a:hover {
  color: var(--text);
}

/* Hidden until the hero's badge is gone, so the page never shows two
   competing calls to action at once. */
.pill {
  flex: none;
  padding: 8px 18px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(-6px) scale(0.96);
  pointer-events: none;
  transition: opacity var(--normal) var(--ease-out),
    transform var(--normal) var(--ease-out),
    background var(--fast) var(--ease-out);
}

.pill.show {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.pill:hover {
  background: var(--accent-hover);
}

/* ===================================================================
   Shared section furniture
   =================================================================== */

.section {
  padding: clamp(72px, 9vw, 120px) 0;
}

.band {
  padding: clamp(72px, 9vw, 120px) 0;
  border-block: 1px solid var(--divider);
  background: rgba(255, 255, 255, 0.016);
}

.kicker {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

.lede {
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.6;
  color: var(--text-2);
  max-width: 56ch;
}

.lede.small {
  font-size: 1.0625rem;
}

.lede.center {
  margin-inline: auto;
}

.section > .wrap > h2,
.band > .wrap > h2 {
  margin-bottom: 44px;
  max-width: 20ch;
}

/* ===================================================================
   Hero
   =================================================================== */

.hero {
  padding: clamp(40px, 6vw, 76px) 0 clamp(64px, 8vw, 104px);
}

/* minmax(0, 1fr) rather than a bare 1fr, here and in every other grid on
   the page: the demo rows carry `white-space: nowrap` executable paths, and
   an auto-sized track takes their full min-content width and pushes the
   whole layout past the viewport on a phone. Capping the track lets the
   ellipsis do its job instead. */
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(48px, 6vw, 64px);
  align-items: center;
}

@media (min-width: 940px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
    gap: 56px;
  }
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 5px 14px 5px 11px;
  margin-bottom: 26px;
  font-size: 0.8125rem;
  color: var(--text-2);
  background: var(--card);
  border: 1px solid var(--stroke);
  border-radius: 999px;
}

.eyebrow .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
  animation: breathe 2.6s var(--ease-out) infinite;
}

@keyframes breathe {
  50% {
    opacity: 0.35;
  }
}

.hero-copy h1 {
  margin-bottom: 22px;
}

.hero-copy .lede {
  margin-bottom: 34px;
}

/* --- the call to action --- */
.cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 28px;
}

/* The Microsoft badge is used unaltered — scaled proportionally only,
   never recoloured, relettered or padded with our own chrome. */
.badge-link {
  display: inline-block;
  border-radius: 6px;
  transition: transform var(--fast) var(--ease-out),
    filter var(--fast) var(--ease-out);
}

.badge-link img {
  width: 204px;
  height: auto;
}

.badge-link.big img {
  width: 224px;
}

.badge-link:hover {
  transform: translateY(-2px);
  filter: brightness(1.08)
    drop-shadow(0 10px 24px rgba(96, 205, 255, 0.22));
}

.badge-link:active {
  transform: translateY(0);
}

.cta-note {
  font-size: 0.8125rem;
  color: var(--text-4);
}

.trust {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  list-style: none;
  font-size: 0.8125rem;
  color: var(--text-3);
}

.trust li {
  position: relative;
  padding-left: 19px;
}

/* A small check, drawn rather than loaded. */
.trust li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0.52em;
  width: 9px;
  height: 5px;
  border-left: 1.6px solid var(--accent);
  border-bottom: 1.6px solid var(--accent);
  transform: rotate(-45deg);
}

/* ===================================================================
   Hero demo — the dashboard and its alert, rebuilt with the app's own
   tokens and put on a nine-second loop: idle, something opens the
   camera, alert, back to idle.
   =================================================================== */

.hero-demo {
  position: relative;
  isolation: isolate;
  /* Room under the window for the alert to hang into, so the bubble never
     covers the list row it is announcing. */
  padding-bottom: 156px;
}

.glow {
  position: absolute;
  inset: -14% -8% 4%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    50% 50% at 50% 45%,
    rgba(96, 205, 255, 0.16),
    transparent 70%
  );
  filter: blur(30px);
}

.win {
  border-radius: var(--r-big);
  border: 1px solid var(--stroke-strong);
  background: #202020;
  box-shadow: var(--shadow-lift);
  overflow: hidden;
  font-size: 14px;
}

.win-bar {
  display: flex;
  align-items: center;
  height: 34px;
  padding-left: 14px;
  background: #1c1c1c;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.win-title {
  font-size: 12px;
  color: var(--text-3);
}

.win-buttons {
  display: flex;
  gap: 18px;
  margin-left: auto;
  padding-right: 16px;
}

.win-buttons i {
  width: 10px;
  height: 1px;
  background: var(--text-4);
}

.win-buttons i:nth-child(2) {
  height: 8px;
  background: none;
  border: 1px solid var(--text-4);
}

.win-buttons i:nth-child(3) {
  transform: rotate(45deg);
  box-shadow: 0 0 0 0 transparent;
  position: relative;
}

.win-buttons i:nth-child(3)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--text-4);
  transform: rotate(90deg);
}

/* The window is a navigation rail over one scrolling column — the shape
   the app itself uses, so the Store screenshots land as a place the
   visitor has already been. */
.win-body {
  display: flex;
  align-items: stretch;
}

.mock-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex: none;
  width: 62px;
  padding: 10px 0 8px;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(255, 255, 255, 0.025);
}

.mock-brand {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-bottom: 10px;
  border-radius: var(--r-card);
  background: var(--accent-tint);
}

.mock-brand svg {
  width: 22px;
  height: 22px;
}

.mock-item {
  display: grid;
  justify-items: center;
  gap: 2px;
  position: relative;
  width: 54px;
  padding: 7px 2px 6px;
  border-radius: var(--r-card);
  color: var(--text-3);
}

.mock-item.on {
  color: var(--accent);
  background: var(--accent-tint);
}

/* Fluent's selection indicator: a short accent bar down the leading edge. */
.mock-item.on::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 50%;
  width: 3px;
  height: 18px;
  margin-top: -9px;
  border-radius: 999px;
  background: var(--accent);
}

.mock-item svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mock-item em {
  font-size: 10px;
  line-height: 13px;
  color: inherit;
}

.mock-gap {
  flex: 1;
  min-height: 24px;
}

.mock-page {
  flex: 1;
  min-width: 0;
  padding: 16px 18px 20px;
}

.mock-title {
  font-size: 19px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--text);
  font-family: "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  margin-bottom: 14px;
}

.status-text em,
.row-text em,
.toast-text em {
  display: block;
  font-size: 12px;
  line-height: 1.35;
  color: var(--text-3);
}

/* Anything alarming stays outside the fold in the app, so it does here
   too: an app wearing someone else's name must not need a click. */
.row-text em.alarm,
.toast-text em.alarm {
  color: var(--critical);
  white-space: normal;
}

/* --- status card: two faces, cross-faded on the loop --- */
.status {
  position: relative;
  margin-bottom: 20px;
}

.status-face {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 16px;
  border-radius: var(--r-card);
  border: 1px solid var(--stroke);
  background: var(--card);
}

.status-face.is-live {
  position: absolute;
  inset: 0;
  border-color: rgba(255, 153, 164, 0.42);
  background: var(--critical-tint);
}

.status-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 50%;
  color: var(--text-3);
  background: rgba(255, 255, 255, 0.06);
}

.is-live .status-icon {
  color: var(--critical);
  background: rgba(255, 153, 164, 0.16);
}

.status-icon svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.status-text b {
  font-size: 16px;
  font-family: "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
}

.is-live .status-text b {
  color: var(--critical);
}

.group-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}

/* --- list ---
   Empty state and populated list are stacked on top of each other and
   cross-faded, so the loop swaps one for the other without the window
   changing height under the reader. The populated list is the one left in
   flow, because it is the taller of the two and its height is whatever
   the rows inside it turn out to need. */
.rows {
  position: relative;
}

.row-empty {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  padding: 14px 16px;
  font-size: 13px;
  color: var(--text-3);
  border-radius: var(--r-card);
  border: 1px solid var(--stroke);
  background: var(--card);
}

.row-stack {
  display: grid;
  gap: 8px;
}

.row {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 12px 14px;
  border-radius: var(--r-card);
  border: 1px solid var(--stroke);
  background: var(--card);
}

/* The collapsed row's expander arrow. Rows in the app open on click to
   add the executable, the PID, the device and the publisher. */
.chev {
  flex: none;
  width: 7px;
  height: 7px;
  margin-right: 3px;
  border-right: 1.6px solid var(--text-4);
  border-bottom: 1.6px solid var(--text-4);
  transform: rotate(45deg);
}

.row-text {
  flex: 1;
  min-width: 0;
}

.row-text b,
.toast-text b {
  display: block;
  font-size: 14px;
  line-height: 1.4;
}

.row-text em,
.toast-text em {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row-btn {
  flex: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  padding: 5px 13px;
  border-radius: var(--r-control);
  border: 1px solid var(--stroke);
  background: rgba(255, 255, 255, 0.06);
}

/* --- the app monogram, same rule as the app: stable tint per app --- */
.avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 50%;
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--tint, 205) 80% 76%);
  background: hsl(var(--tint, 205) 80% 76% / 0.14);
  box-shadow: inset 0 0 0 1px hsl(var(--tint, 205) 80% 76% / 0.2);
}

.avatar-dead {
  color: var(--text-4);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 1px var(--stroke);
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 7px;
  padding: 0 8px;
  font-size: 11px;
  line-height: 17px;
  font-weight: 600;
  border-radius: 999px;
  vertical-align: 1px;
}

.tag-live {
  color: var(--critical);
  background: var(--critical-tint);
}

/* The signature verdicts, in the app's own three tones: what verified,
   what didn't, and what we could not or need not judge. */
.tag-ok {
  color: var(--success);
  background: rgba(108, 203, 95, 0.14);
}

.tag-warn {
  color: var(--caution);
  background: rgba(252, 225, 0, 0.12);
}

.tag-muted {
  color: var(--text-3);
  background: rgba(255, 255, 255, 0.07);
}

.tag-alarm {
  color: var(--critical);
  background: var(--critical-tint);
}

.tag .pip {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: breathe 2s var(--ease-out) infinite;
}

/* --- the alert bubble ---
   Hung off the window's bottom-right corner rather than laid over it: on a
   real desktop the toast is a separate always-on-top window sitting in the
   corner of the work area, and overlapping the list would hide the very row
   the section is trying to show. */
.toast {
  position: absolute;
  right: -30px;
  bottom: 0;
  width: 306px;
  max-width: 88%;
  padding: 13px 14px 14px;
  border-radius: var(--r-card);
  border: 1px solid var(--stroke-strong);
  background: rgba(32, 32, 32, 0.94);
  backdrop-filter: blur(24px) saturate(140%);
  -webkit-backdrop-filter: blur(24px) saturate(140%);
  box-shadow: var(--shadow-lift);
}

.toast-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 10px;
  font-size: 11px;
  color: var(--text-3);
}

.toast-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.toast-body {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 12px;
}

.toast-text {
  min-width: 0;
}

.toast-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.tbtn {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  padding: 5px 14px;
  border-radius: var(--r-control);
  border: 1px solid var(--stroke);
  background: rgba(255, 255, 255, 0.06);
}

.tbtn-accent {
  color: var(--on-accent);
  background: var(--accent);
  border-color: transparent;
}

/* --- the loop ---------------------------------------------------------
   Base styles hold the "live" state, so a browser that refuses the
   animation (reduced motion) still shows the most informative frame
   rather than an empty dashboard. */
.status-face.is-idle {
  opacity: 0;
}

.status-face.is-live,
.row,
.toast {
  opacity: 1;
}

.row-empty {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .status-face.is-idle {
    animation: face-idle 9s var(--ease-out) infinite;
  }
  .status-face.is-live {
    animation: face-live 9s var(--ease-out) infinite;
  }
  .row-empty {
    animation: face-idle 9s var(--ease-out) infinite;
  }
  /* The two rows land a beat apart — the camera first, then the thing on
     the microphone the alert is about. Shifted keyframes rather than an
     animation-delay, so both still leave inside the same nine seconds. */
  .row-stack .row {
    animation: row-in 9s var(--ease-out) infinite;
  }
  .row-stack .row:nth-child(2) {
    animation-name: row-in-late;
  }
  .toast {
    animation: toast-in 9s var(--ease-out) infinite;
  }
}

@keyframes face-idle {
  0%,
  22% {
    opacity: 1;
  }
  28%,
  92% {
    opacity: 0;
  }
  98%,
  100% {
    opacity: 1;
  }
}

@keyframes face-live {
  0%,
  22% {
    opacity: 0;
  }
  28%,
  92% {
    opacity: 1;
  }
  98%,
  100% {
    opacity: 0;
  }
}

@keyframes row-in {
  0%,
  22% {
    opacity: 0;
    transform: translateY(8px);
  }
  30%,
  92% {
    opacity: 1;
    transform: none;
  }
  98%,
  100% {
    opacity: 0;
    transform: translateY(8px);
  }
}

@keyframes row-in-late {
  0%,
  27% {
    opacity: 0;
    transform: translateY(8px);
  }
  35%,
  92% {
    opacity: 1;
    transform: none;
  }
  98%,
  100% {
    opacity: 0;
    transform: translateY(8px);
  }
}

@keyframes toast-in {
  0%,
  31% {
    opacity: 0;
    transform: translateX(26px);
  }
  39%,
  72% {
    opacity: 1;
    transform: none;
  }
  80%,
  100% {
    opacity: 0;
    transform: translateX(26px);
  }
}

/* ===================================================================
   Facts strip
   =================================================================== */

/* The cases strip has a kicker but no heading under it, so it needs the
   breathing room the heading would otherwise have provided. */
.band > .wrap > .kicker {
  margin-bottom: 34px;
}

.facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 30px;
}

@media (min-width: 800px) {
  .facts {
    grid-template-columns: repeat(3, 1fr);
    gap: 44px;
  }
}

.fact-no {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin-bottom: 12px;
}

.fact h3 {
  margin-bottom: 10px;
}

.fact h3 em {
  color: var(--accent);
  font-style: italic;
}

.fact p {
  font-size: 0.9375rem;
  color: var(--text-3);
}

/* ===================================================================
   Cards
   =================================================================== */

.cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}

@media (min-width: 800px) {
  .cards {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Four beats read as a square rather than as a row of three with an
     orphan under it. */
  .cards.four {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.card {
  padding: 28px 26px 30px;
  border-radius: var(--r-big);
  border: 1px solid var(--stroke);
  background: var(--card);
  box-shadow: var(--shadow-card);
  transition: border-color var(--normal) var(--ease-out),
    background var(--normal) var(--ease-out),
    transform var(--normal) var(--ease-out);
}

.card:hover {
  border-color: var(--stroke-strong);
  background: var(--card-hover);
  transform: translateY(-3px);
}

.card-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 20px;
  border-radius: 12px;
  color: var(--accent);
  background: var(--accent-tint);
  box-shadow: inset 0 0 0 1px rgba(96, 205, 255, 0.18);
}

.card-icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.card h3 {
  margin-bottom: 10px;
}

.card h3 em {
  color: var(--accent);
  font-style: italic;
}

.card p {
  font-size: 0.9375rem;
  color: var(--text-3);
}

.card p em {
  color: var(--text);
  font-style: italic;
}

/* ===================================================================
   Split — the svchost comparison
   =================================================================== */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 44px;
  align-items: center;
}

@media (min-width: 940px) {
  .split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 64px;
  }

  /* Consecutive splits alternate sides, so three of them in a row don't
     read as one long left-hand column. On a phone the copy always comes
     first, whichever side it sits on here. */
  .split.flip .split-visual {
    order: -1;
  }
}

.split-copy h2 {
  margin: 0 0 22px;
}

.split-copy .lede + .lede {
  margin-top: 16px;
}

.mono {
  font-family: "Cascadia Code", "Consolas", ui-monospace, monospace;
  font-size: 0.86em;
  color: var(--text-4);
}

.split-visual {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.compare {
  padding: 16px 18px 14px;
  border-radius: var(--r-big);
  border: 1px solid var(--stroke);
  background: var(--card);
}

.compare-good {
  border-color: rgba(96, 205, 255, 0.28);
  background: linear-gradient(
    160deg,
    rgba(96, 205, 255, 0.07),
    rgba(255, 255, 255, 0.03)
  );
}

.compare-label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-4);
  margin-bottom: 12px;
}

.compare-good .compare-label {
  color: var(--accent);
}

.compare-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
}

.compare-row + .compare-row {
  border-top: 1px solid var(--divider);
}

.compare-bad .row-text b {
  color: var(--text-3);
}

.compare-foot {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
  font-size: 0.8125rem;
  color: var(--text-4);
}

/* ===================================================================
   Identification — the four things a row can say about who signed a
   program, in the app's own words and the app's own tones.
   =================================================================== */

.verdicts,
.day {
  padding: 16px 18px 14px;
  border-radius: var(--r-big);
  border: 1px solid var(--stroke);
  background: var(--card);
}

.verdict {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 11px 0;
}

.verdict + .verdict {
  border-top: 1px solid var(--divider);
}

.verdict .tag {
  margin-left: 0;
  margin-top: 1px;
  flex: none;
}

.verdict-text {
  min-width: 0;
}

.verdict-text b {
  display: block;
  font-size: 14px;
  line-height: 1.4;
}

.verdict-text em {
  display: block;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-3);
}

.verdict-alarm .verdict-text b {
  color: var(--critical);
}

/* ===================================================================
   History — a day of the log, totalled the way the app totals it.
   =================================================================== */

.day-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--divider);
}

.day-head b {
  font-size: 0.9375rem;
}

.day-total {
  font-size: 0.8125rem;
  color: var(--text-4);
}

/* Session rows carry two or three facts and no ellipsis to hide behind,
   so they wrap rather than truncate. */
.day .row-text em {
  white-space: normal;
}

/* ===================================================================
   Discretion
   =================================================================== */

.quiet {
  max-width: 760px;
}

.quiet h2 {
  margin-bottom: 18px;
}

.quiet-list {
  list-style: none;
  margin-top: 34px;
  border-top: 1px solid var(--divider);
}

.quiet-list li {
  padding: 20px 0 20px 34px;
  position: relative;
  border-bottom: 1px solid var(--divider);
  font-size: 0.9375rem;
  color: var(--text-3);
}

.quiet-list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 1.62em;
  width: 10px;
  height: 6px;
  border-left: 1.8px solid var(--accent);
  border-bottom: 1.8px solid var(--accent);
  transform: rotate(-45deg);
}

.quiet-list b {
  display: block;
  font-size: 1rem;
  margin-bottom: 2px;
}

.quiet-list em {
  font-style: italic;
  color: var(--text-2);
}

/* ===================================================================
   Closers
   =================================================================== */

.band-cta {
  background: radial-gradient(
    70% 130% at 50% 0%,
    rgba(96, 205, 255, 0.09),
    transparent 70%
  );
}

.closer {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The centred closers set their own measure with a <br>, so they opt out
   of the 20ch cap the left-aligned section headings use. Needs to match the
   specificity of `.band > .wrap > h2` to beat it. */
.wrap.closer h2 {
  max-width: none;
  margin-bottom: 28px;
}

.closer .lede {
  margin-bottom: 30px;
}

.closer .cta-note {
  margin-top: 14px;
}

/* The FAQ above already ends on a full section pad, so this one starts
   tighter than it ends. */
.last {
  padding: clamp(56px, 6vw, 88px) 0 clamp(80px, 10vw, 120px);
}

.last-mark {
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  margin-bottom: 26px;
  border-radius: 18px;
  background: linear-gradient(160deg, #1b2c4a, #0b1120);
  box-shadow: inset 0 0 0 1px var(--stroke-strong),
    0 16px 40px rgba(96, 205, 255, 0.12);
}

.last-mark svg {
  width: 38px;
  height: 38px;
}

/* ===================================================================
   FAQ
   =================================================================== */

.faq {
  border-top: 1px solid var(--divider);
}

.faq details {
  border-bottom: 1px solid var(--divider);
}

/* Block, not flex: a flex summary makes every text node its own item, so
   `gap` opens a hole either side of an inline <em> inside the question. */
.faq summary {
  display: block;
  position: relative;
  padding: 20px 44px 20px 4px;
  cursor: pointer;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--text);
  list-style: none;
  transition: color var(--fast) var(--ease-out);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "";
  position: absolute;
  right: 10px;
  top: 27px;
  width: 9px;
  height: 9px;
  border-right: 1.8px solid var(--text-3);
  border-bottom: 1.8px solid var(--text-3);
  transform: rotate(45deg);
  transition: transform var(--normal) var(--ease-out);
}

.faq details[open] summary::after {
  transform: translateY(4px) rotate(-135deg);
}

.faq summary:hover {
  color: var(--accent);
}

.faq summary em {
  font-style: italic;
  color: var(--accent);
}

.faq details p {
  padding: 0 40px 22px 4px;
  font-size: 0.9375rem;
  color: var(--text-3);
  max-width: 66ch;
}

.faq details[open] p {
  animation: fade-up var(--normal) var(--ease-out) both;
}

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* ===================================================================
   Legal pages
   =================================================================== */

.legal h1 {
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
  margin-bottom: 20px;
}

.legal .lede {
  margin-bottom: 12px;
}

.section > .wrap.legal > h2 {
  max-width: none;
  font-size: 1.25rem;
  margin: 38px 0 10px;
}

.legal p {
  font-size: 0.9375rem;
  color: var(--text-3);
}

.legal p + p {
  margin-top: 12px;
}

.legal .mono {
  color: var(--text-2);
  word-break: break-all;
}

.legal em {
  font-style: italic;
  color: var(--text-2);
}

.legal-date {
  margin-top: 44px;
  padding-top: 20px;
  border-top: 1px solid var(--divider);
  font-size: 0.8125rem !important;
  color: var(--text-4) !important;
}

/* ===================================================================
   Footer
   =================================================================== */

.foot {
  padding: 34px 0 40px;
  border-top: 1px solid var(--divider);
  font-size: 0.8125rem;
  color: var(--text-4);
}

.foot-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 26px;
  align-items: center;
  justify-content: space-between;
}

.foot-links {
  display: flex;
  gap: 20px;
  align-items: center;
}

.foot-links a {
  color: var(--text-3);
}

.foot-links a:hover {
  color: var(--accent);
}

/* ===================================================================
   Mobile sticky CTA — a phone can't install a Windows app, so this is
   deliberately quiet copy that still keeps the funnel open (the Store
   listing opens fine in a mobile browser, and they can send it to
   themselves).
   =================================================================== */

.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  display: none;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: rgba(10, 15, 28, 0.9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-top: 1px solid var(--divider);
  transform: translateY(110%);
  transition: transform var(--normal) var(--ease-out);
}

.sticky-cta.show {
  transform: none;
}

.sticky-cta a {
  display: block;
  padding: 13px;
  text-align: center;
  font-weight: 600;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: var(--r-control);
}

@media (max-width: 720px) {
  .sticky-cta {
    display: block;
  }
  body {
    padding-bottom: 76px;
  }
  .nav-links {
    display: none;
  }
  .pill {
    margin-left: auto;
  }
  .hero-demo {
    padding-bottom: 0;
  }
  .toast {
    position: static;
    width: auto;
    max-width: none;
    margin-top: 16px;
  }
  .mock-page {
    padding: 14px 14px 18px;
  }
}

/* Narrow phones: the mock is the only thing on the page that can't
   reflow, so the rail gives up its labels to leave the rows readable.
   The app's own rail keeps them — it is never this narrow. */
@media (max-width: 560px) {
  .mock-rail {
    width: 46px;
  }
  .mock-item {
    width: 40px;
    padding: 9px 2px;
  }
  .mock-item em {
    display: none;
  }
}

/* ===================================================================
   Scroll reveal — opt-in, and only where motion is welcome.
   =================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
  }

  .js .reveal.in {
    opacity: 1;
    transform: none;
  }
}
