/* ========================================
   VPN DETECTION — PRODUCT PAGE
   ======================================== */

/* ---- Hero ---- */

/* Hero diagram — absolute background */

/* Hero category strip — between header and footer (matches geo layout) */

/* Hero footer — full-width stats bar */

/* ========================================
   SIGNAL CARDS — 7 detection signals
   ======================================== */
.vpn-signals {
  padding: var(--space-5xl) 0;
  position: relative;
  z-index: 1;
}

/* the signals in the datasets form: seven tabs across, the list of points under the text, the drawing filling the picture cell */
.vpn-signals .ds-x-uk-bar { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.vpn-signals .ds-x-uk-text .signal-details { margin-top: var(--space-md); }
.vpn-signals .ds-x-uk-pic .signal-diagram { width: 100%; max-width: 520px; }
@media (max-width: 899px) { .vpn-signals .ds-x-uk-bar { grid-template-columns: none; } }

/* Signal detail list */
.signal-details {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.signal-detail {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.5;
}

.signal-detail-marker {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  color: var(--text-primary);
  flex-shrink: 0;
  width: 1rem;
  text-align: center;
}

/* Signal diagram container */
.signal-diagram {
  position: relative;
}

.signal-diagram svg {
  width: 100%;
  height: auto;
  color: var(--text-primary);
  filter: url(#vpn-ink);        /* strokes drawn at a fifth to a half of the ink come up to half to full */
}
/* the drawings' hairlines and tones lifted and their labels enlarged (3.5 to 8 units, 4 to 10px on the page, now 6 to 10 units) on a halo of the page colour */
.signal-diagram svg [opacity="0.03"] { opacity: 0.08; }
.signal-diagram svg [opacity="0.12"] { opacity: 0.3; }
.signal-diagram svg [opacity="0.15"] { opacity: 0.35; }
.signal-diagram svg [opacity="0.2"] { opacity: 0.5; }
.signal-diagram svg [opacity="0.25"] { opacity: 0.55; }
.signal-diagram svg [opacity="0.3"] { opacity: 0.6; }
.signal-diagram svg [opacity="0.35"] { opacity: 0.65; }
.signal-diagram svg [opacity="0.4"] { opacity: 0.7; }
.signal-diagram svg [opacity="0.45"] { opacity: 0.75; }
.signal-diagram svg [opacity="0.5"] { opacity: 0.8; }
.signal-diagram svg [opacity="0.55"] { opacity: 0.85; }
.signal-diagram svg [opacity="0.6"] { opacity: 0.9; }
.signal-diagram svg [opacity="0.65"] { opacity: 0.95; }
.signal-diagram svg [opacity="0.7"] { opacity: 1; }
.signal-diagram svg [stroke-width="0.3"] { stroke-width: 0.7; }
.signal-diagram svg [stroke-width="0.4"] { stroke-width: 0.9; }
.signal-diagram svg [stroke-width="0.5"] { stroke-width: 1; }
.signal-diagram svg [stroke-width="0.6"] { stroke-width: 1.1; }
.signal-diagram svg [stroke-width="0.7"] { stroke-width: 1.25; }
.signal-diagram svg [stroke-width="0.8"] { stroke-width: 1.4; }
.signal-diagram svg [stroke-width="1"] { stroke-width: 1.6; }
.signal-diagram svg [stroke-width="1.2"] { stroke-width: 1.8; }
.signal-diagram svg text { font-size: 7.5px; opacity: 1; paint-order: stroke; stroke: var(--bg-primary); stroke-width: 2.5px; stroke-linejoin: round; }
.signal-diagram svg g[font-size="3.5"] text, .signal-diagram svg text[font-size="3.5"] { font-size: 6px; }
.signal-diagram svg g[font-size="4"] text, .signal-diagram svg text[font-size="4"] { font-size: 6.5px; }
.signal-diagram svg g[font-size="4.5"] text, .signal-diagram svg text[font-size="4.5"] { font-size: 7px; }
.signal-diagram svg g[font-size="5"] text, .signal-diagram svg text[font-size="5"] { font-size: 7.5px; }
.signal-diagram svg g[font-size="5.5"] text, .signal-diagram svg text[font-size="5.5"] { font-size: 8px; }
.signal-diagram svg g[font-size="6"] text, .signal-diagram svg text[font-size="6"] { font-size: 8.5px; }
.signal-diagram svg g[font-size="8"] text, .signal-diagram svg text[font-size="8"] { font-size: 10px; }
.signal-diagram svg text[opacity="0.2"], .signal-diagram svg text[opacity="0.25"], .signal-diagram svg text[opacity="0.3"] { opacity: 0.75; }
.signal-diagram svg text[opacity="0.35"], .signal-diagram svg text[opacity="0.4"], .signal-diagram svg text[opacity="0.45"] { opacity: 0.85; }

/* ========================================
   ACCURACY METRICS SECTION
   ======================================== */
.vpn-accuracy {
  padding: var(--space-5xl) 0;
  position: relative;
  z-index: 1;
}

.vpn-accuracy-header {
  text-align: center;
  margin-bottom: var(--space-3xl);
}

.vpn-accuracy-header h2 {
  margin-top: var(--space-lg);
  font-size: clamp(1.8rem, 3.5vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.vpn-accuracy-header p {
  margin-top: var(--space-md);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
  font-size: var(--text-lg);
  color: var(--text-secondary);
}

/* Accuracy grid */
.accuracy-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border: 1px solid var(--border);
  margin-bottom: var(--space-3xl);
}

.accuracy-card {
  padding: var(--space-2xl) var(--space-xl);
  text-align: center;
  border-right: 1px solid var(--border);
  position: relative;
}

.accuracy-card:last-child {
  border-right: none;
}

.accuracy-value {
  font-family: var(--font-mono);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
  letter-spacing: -0.03em;
}

.accuracy-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-top: var(--space-sm);
}

.accuracy-sub {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-top: var(--space-sm);
  line-height: 1.4;
}

/* Confusion matrix diagram */

/* ========================================
   PROVIDERS COVERED
   ======================================== */
.vpn-providers {
  padding: var(--space-5xl) 0;
  background: var(--bg-secondary);
  position: relative;
  z-index: 1;
}
/* the coverage band as the inset panel with corner brackets, like the geolocation page's accuracy band (his ask, 2026-10-16) */
.vpn-providers.hud { --hud: color-mix(in srgb, var(--text-primary) 55%, transparent); --hin: 10px; margin: 12px; border-radius: 6px; padding: var(--space-5xl) 0; overflow: visible; }


.vpn-providers-header {
  text-align: center;
  margin-bottom: var(--space-3xl);
}

.vpn-providers-header h2 {
  margin-top: var(--space-lg);
  font-size: clamp(1.8rem, 3.5vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.vpn-providers-header p {
  margin-top: var(--space-md);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
  font-size: var(--text-lg);
  color: var(--text-secondary);
}

/* Provider grid */
.provider-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0;
  border: 1px solid var(--border);
}

.provider-item {
  padding: var(--space-lg) var(--space-md);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--text-secondary);
  transition: background 150ms ease;
}

.provider-item:hover {
  background: color-mix(in srgb, var(--text-primary) 3%, transparent);
}

.provider-dot {
  width: 6px;
  height: 6px;
  border: 1px solid var(--text-primary);
  flex-shrink: 0;
}

/* ========================================
   API RESPONSE SECTION
   ======================================== */

/* API response mockup */

/* Field annotations next to API response */

/* ========================================
   USE CASES SECTION
   ======================================== */

.usecase-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border: 1px solid var(--border);
}

.usecase-card {
  padding: var(--space-2xl);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transition: background 200ms ease;
}

.usecase-card:nth-child(3n) {
  border-right: none;
}

.usecase-card:nth-last-child(-n+3) {
  border-bottom: none;
}

.usecase-card:hover {
  background: color-mix(in srgb, var(--text-primary) 3%, transparent);
}

.usecase-number {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  color: var(--text-muted);
  letter-spacing: 0.05em;
  margin-bottom: var(--space-md);
}

.usecase-card h4 {
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: var(--space-sm);
  line-height: 1.25;
}

.usecase-card p {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.65;
}

/* ========================================
   RESPONSIVE
   ======================================== */
@media (max-width: 1023px) {

            .signal-diagram {
    max-width: 500px;
  }

  .accuracy-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .accuracy-card:nth-child(2) {
    border-right: none;
  }

  .accuracy-card:nth-child(1),
  .accuracy-card:nth-child(2) {
    border-bottom: 1px solid var(--border);
  }

  

  .usecase-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .usecase-card:nth-child(3n) {
    border-right: 1px solid var(--border);
  }

  .usecase-card:nth-child(2n) {
    border-right: none;
  }

  .usecase-card:nth-last-child(-n+3) {
    border-bottom: 1px solid var(--border);
  }

  .usecase-card:nth-last-child(-n+2) {
    border-bottom: none;
  }
}

@media (max-width: 767px) {
  

  

  

  

  

  

  

  .accuracy-grid {
    grid-template-columns: 1fr;
  }

  .accuracy-card {
    border-right: none;
    border-bottom: 1px solid var(--border);
  }

  .accuracy-card:last-child {
    border-bottom: none;
  }

  .usecase-grid {
    grid-template-columns: 1fr;
  }

  .usecase-card {
    border-right: none !important;
    border-bottom: 1px solid var(--border) !important;
  }

  .usecase-card:last-child {
    border-bottom: none !important;
  }

}

/* ---- The hero card's strip: not a map but a panel (decided 2026-10-08 over the map and seventeen other takes) —
   the is_vpn flag in a red pill with how it was found, the provider (planned, tagged) with its network, the
   vpn_score bar with its 90 tick, and a line saying the rest is inferred. On white, in the page's ink; the
   verdict's colour is a red. The markup comes from scripts/product-hero.py. ---- */
.geo-card { --strip-ink: var(--text-primary); --strip-paper: var(--bg-secondary); --strip-dim: var(--text-muted); --strip-flag: #e5484d; --strip-ok: #30a46c; }
:root:is([data-theme="dark"]) .geo-card { --strip-paper: rgba(255, 255, 255, .12); --strip-flag: #ff6b6b; --strip-ok: #3dd68c; }
:root[data-card="8"] .geo-card-wrap .geo-card-map--panel { background: #fff; }
:root:is([data-theme="dark"])[data-card="8"] .geo-card-wrap .geo-card-map--panel { background: var(--bg-secondary); }
.geo-strip { position: absolute; inset: 0; display: grid; grid-template-rows: auto auto auto; row-gap: 15px; align-content: center; padding: 14px 24px; font-family: var(--font-mono); color: var(--strip-ink); }
.gs-k { color: var(--strip-dim); letter-spacing: .02em; }
.gs-combo-top { position: relative; display: grid; grid-template-columns: 1fr 1fr; column-gap: 24px; margin: 0 -24px; padding: 0 24px 14px; border-bottom: 1px solid var(--border); }   /* a hairline between the readouts and the bar, edge to edge of the panel (asked 2026-10-08) */
.gs-combo-top::before { content: ''; position: absolute; left: 50%; top: -200px; bottom: 0; width: 1px; background: var(--border); }   /* and one between is_vpn and the provider, from the panel's top down to that line (asked 2026-10-08); the strip clips it */
.geo-strip--combo { overflow: hidden; }
.gs-readout { display: grid; row-gap: 5px; font-size: .62rem; }
.gs-readout .gs-val { display: flex; align-items: center; gap: .45rem; font-size: 1.15rem; font-weight: 600; color: var(--strip-ink); letter-spacing: -.01em; }
.gs-logo { width: 18px; height: 18px; border-radius: 4px; flex: none; }   /* the provider's mark, from logo.dev like the ASN page's */
.gs-flag { display: inline-flex; justify-self: start; align-items: center; gap: .4rem; padding: .34rem .62rem; border-radius: 6px; background: var(--strip-paper); }   /* the word in a chip with a red dot, the way set.space sets its chips (css/resources-set.css) */
.gs-flag i { width: 8px; height: 8px; border-radius: 50%; background: var(--strip-flag); flex: none; }
.gs-flag b { font-size: .72rem; font-weight: 600; line-height: 1; letter-spacing: .04em; color: var(--strip-ink); }
.gs-flag--false i { background: var(--strip-ok); }   /* green for false, red for true */
.gs-flag--row { padding: .22rem .5rem; vertical-align: middle; }   /* the chip in a card row, sized to the row (the verdict group's booleans, asked 2026-10-08) */
.gs-flag--row i { width: 7px; height: 7px; }
.gs-flag--row b { font-size: .66rem; }
.gs-evidence { font-size: .56rem; color: var(--strip-dim); letter-spacing: .02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gs-evidence b { color: var(--strip-ink); font-weight: 600; }   /* "observed", set like "inferred" below */
.gs-tag { display: inline-block; margin-left: .45rem; padding: .08rem .38rem .1rem; border: 1px solid var(--accent); border-radius: 2px; font-size: .48rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); vertical-align: middle; }   /* the provider is planned, not offered yet */
.gs-combo-bar { display: grid; grid-template-columns: 5.6rem minmax(0, 1fr) 2.2rem; column-gap: .75rem; align-items: center; font-size: .62rem; }
.gs-combo-bar b { text-align: right; font-size: .9rem; font-weight: 600; }
.gs-track { position: relative; height: 14px; background: var(--strip-paper); }
.gs-fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--strip-flag); }
.gs-tick { position: absolute; top: -6px; bottom: -6px; width: 1px; background: var(--strip-ink); }
.gs-tick::after { content: '90'; position: absolute; top: -12px; left: -5px; font-size: .5rem; letter-spacing: .02em; }
.gs-sub { display: flex; align-items: baseline; gap: .6rem; font-size: .58rem; color: var(--strip-dim); letter-spacing: .02em; white-space: nowrap; }   /* one line, starting where "observed" starts */
.gs-sub a { color: var(--accent); text-decoration: none; }
.gs-sub a:hover { text-decoration: underline; }
.gs-sub b { color: var(--strip-ink); font-weight: 600; }
/* ↑ the evidence line, the coming-soon tag, the score bar and the inferred line: cut by mistake when the switches were baked on 2026-10-09, restored from the last commit */ these thirteen rules were cut by mistake when the switches were baked on 2026-10-09 and restored from the last commit */
.geo-all-row:has(.gs-flag--row) { align-items: center; }
.gs-tags { display: inline-flex; gap: .4rem; margin-left: .7rem; margin-right: auto; }   /* tags by the address in the card's head, the threat card's chips (asked 2026-10-09) */
.gs-type { display: inline-block; padding: .2rem .5rem; border-radius: 6px; background: var(--strip-paper); font-family: var(--font-mono); font-size: .58rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--strip-ink); vertical-align: middle; }
/* THE SAMPLE SWITCHER (decided 2026-10-09 from ?samples=): Tor, Proxy, Private Relay, VPN at the top left outside the card, in the tools row beside the view toggle and in its look; the card becomes the sample chosen */
#geo-card { transition: opacity .2s; }
#geo-card.is-swapping { opacity: .55; }
.gs-samples { display: flex; gap: 1.1rem; margin-right: auto; font-family: var(--font-mono); }
.gs-samples button { margin: 0; padding: 0 0 .12rem; border: 0; border-bottom: 1px solid transparent; background: transparent; cursor: pointer; font: inherit; font-size: .66rem; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }
.gs-samples button:hover { color: var(--text-primary); }
.gs-samples button.is-on { color: var(--text-primary); border-bottom-color: var(--accent); cursor: default; }
.gs-samples button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- Phones (2026-10-15): the strip's two readouts stack, the panel grows for them, the sub-line wraps ---- */
@media (max-width: 767px) {
  .gs-combo-top { grid-template-columns: minmax(0, 1fr); row-gap: 12px; }
  .gs-combo-top::before { display: none; }
  .gs-readout { min-width: 0; }
  .gs-sub { white-space: normal; flex-wrap: wrap; }
  :root[data-card="8"] .geo-card-wrap { --map-h: 296px; }
}
