/* Additions for the VPN suite, layered on /tools/tool.css. Light theme only,
   same tokens, same type scale. Nothing here restyles the shared header. */

/* A clean verdict needs a green tag; tool.css only ships the warning colours. */
.tag-ok { color: #047857; background: #ecfdf5; border: 1px solid #a7f3d0; }

/* Confidence sits next to a verdict and must read as secondary to it. */
.conf { font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; border-radius: 6px; padding: 2px 7px; white-space: nowrap; border: 1px solid var(--border); }
.conf-high { color: #0f766e; background: #f0fdfa; border-color: #99f6e4; }
.conf-medium { color: #a16207; background: #fefce8; border-color: #fde68a; }
.conf-low { color: var(--muted); background: #f3f5f7; }

/* Result cards, used by the leak test, exit-IP and fingerprint pages. */
.cards { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 720px) { .cards.two { grid-template-columns: 1fr 1fr; } .cards.three { grid-template-columns: repeat(3, 1fr); } }
.card { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--border-2); border-radius: 14px; padding: 14px 16px; }
.card.pass { border-left-color: var(--accent); }
.card.warn { border-left-color: #d97706; }
.card.risk { border-left-color: var(--kev); }
.card h3 { margin: 0 0 6px; font-family: var(--display); font-size: 14px; letter-spacing: -0.01em; color: #0b1220; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card p { margin: 0; font-size: 12.5px; color: var(--muted); overflow-wrap: anywhere; }

/* Definition rows: label on the left, value on the right, wrapping freely. */
.kv { display: grid; grid-template-columns: minmax(96px, 26%) 1fr; gap: 4px 14px; font-size: 12.5px; margin-top: 8px; }
.kv dt { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .1em; padding-top: 3px; }
.kv dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 480px) { .kv { grid-template-columns: 1fr; gap: 1px 0; } .kv dd { margin-bottom: 7px; } }

/* Monospace output blocks: generated configs, firewall rules, key material. */
.out { font-family: var(--mono); font-size: 12px; line-height: 1.6; background: #0b1220; color: #d7e3ee; border-radius: 12px; padding: 14px 16px; overflow-x: auto; white-space: pre; margin: 0; }
.out .c { color: #7c8fa5; }
.out .k { color: #6ee7b7; }

/* A compact sparkline strip for the censorship daily series. */
.spark { display: flex; align-items: flex-end; gap: 1px; height: 34px; }
.spark i { flex: 1 1 auto; min-width: 1px; background: var(--accent-2); border-radius: 1px 1px 0 0; display: block; }
.spark i.bad { background: var(--kev); }

/* Score dial used by the censorship and leak pages. */
.score { display: inline-flex; align-items: baseline; gap: 3px; font-family: var(--display); font-weight: 800; letter-spacing: -0.03em; }
.score b { font-size: 30px; line-height: 1; }
.score span { font-size: 12px; color: var(--muted); }

/* Suite index grid, mirroring /tools/. */
.suite { display: grid; grid-template-columns: 1fr; gap: 13px; }
@media (min-width: 700px) { .suite { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .suite { grid-template-columns: 1fr 1fr 1fr; } }
.suite a { display: flex; flex-direction: column; gap: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 17px; text-decoration: none; color: inherit; transition: transform .25s cubic-bezier(.2,.7,.2,1.1), border-color .25s, box-shadow .25s; }
.suite a:hover { transform: translateY(-4px); border-color: rgba(5,150,105,0.5); box-shadow: 0 16px 30px -20px rgba(5,150,105,0.4); }
.suite h3 { margin: 0; font-family: var(--display); font-size: 15.5px; color: #0b1220; }
.suite p { margin: 0; font-size: 12.5px; color: var(--muted); overflow-wrap: anywhere; }
.suite .ico { font-size: 22px; }

/* Section headings between tiers on the index. */
.tierhead { margin: 30px 0 12px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.tierhead h2 { margin: 0; font-family: var(--display); font-size: 17px; color: #0b1220; letter-spacing: -0.015em; }
.tierhead p { margin: 0; font-size: 12px; color: var(--muted); }

/* A short standing caveat, used wherever a result is easy to over-read. */
.caveat { font-size: 11.5px; color: var(--muted); background: var(--surface-2); border: 1px solid var(--border); border-radius: 11px; padding: 10px 13px; margin-top: 13px; overflow-wrap: anywhere; }
.caveat b { color: var(--text); }

/* Cross-links to the other tools in the suite, on every tool page. */
.also { margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--border); }
.also h4 { margin: 0 0 9px; font-size: 10px; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); font-weight: 700; }
.also div { display: flex; flex-wrap: wrap; gap: 7px; }
.also a { font-size: 12px; color: var(--text); background: var(--surface); border: 1px solid var(--border-2); border-radius: 999px; padding: 5px 11px; text-decoration: none; transition: all .15s; }
.also a:hover { border-color: var(--accent); color: var(--accent); }

/* ==========================================================================
   APP SHELL
   The suite reads as one application with twelve screens rather than twelve
   documents. Three moves do most of that work: a tool rail that switches
   screens, a control bar that stays reachable, and prose folded into
   disclosures so the tool is what you see first.
   ========================================================================== */

/* --- Tool rail -----------------------------------------------------------
   Horizontally scrolling tabs directly under the site nav, so every screen is
   one tap away. Sticks below the 80px of brand strip plus nav. */
.railwrap {
  position: sticky; top: 80px; z-index: 99;
  background: rgba(255,255,255,0.94); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  margin: 0 0 14px;
}
.rail {
  display: flex; gap: 4px; align-items: center;
  max-width: 980px; margin: 0 auto; padding: 7px 12px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.rail::-webkit-scrollbar { display: none; }
.rail a {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; color: var(--muted); text-decoration: none;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 7px 12px; white-space: nowrap;
  transition: color .15s, background .15s, border-color .15s;
}
.rail a:hover { color: var(--text); border-color: var(--border-2); }
.rail a.on { color: #fff; background: var(--accent); border-color: var(--accent); }
.rail a .i { font-size: 13px; line-height: 1; }
/* The rail is the mobile navigation, so it must not vanish on small screens. */
@media (max-width: 640px) { .railwrap { top: 80px; } .rail { padding: 6px 10px; } }

/* --- App header ----------------------------------------------------------
   Replaces the tall centred hero on tool screens. One line, left aligned,
   with the live badge inline. */
.apphead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 2px 0 12px; }
.apphead h1 {
  margin: 0; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.25rem, 4.4vw, 1.6rem); line-height: 1.1;
  letter-spacing: -0.025em; color: #0b1220;
}
.apphead h1 .a { color: var(--accent); }
.apphead .sub { font-size: 12px; color: var(--muted); flex: 1 1 220px; overflow-wrap: anywhere; }
/* tool.css scopes the live badge to .hero .live, and the hero is gone from
   these screens, so the badge and its pulsing dot are restated here. Without
   this the badge renders as bare inline text and the dot has no size at all. */
.apphead .live {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  font-size: 10px; text-transform: uppercase; letter-spacing: .16em;
  color: var(--accent); border: 1px solid rgba(5,150,105,0.3);
  border-radius: 999px; padding: 3px 11px; white-space: nowrap;
}
.apphead .live .dot {
  width: 7px; height: 7px; border-radius: 50%; background: #22c55e;
  box-shadow: 0 0 0 3px rgba(34,197,94,0.16); flex: 0 0 auto;
  animation: pulse 2s ease-in-out infinite;
}

/* --- Control bar ---------------------------------------------------------
   The controls a screen is driven by. Sticks under the rail so a result can be
   re-run without scrolling back up, which is the single biggest difference
   between a tool and a page.

   tool.css already claims .bar for a 26px progress meter (height: 26px,
   overflow: hidden, plus absolutely positioned > span and > b children). This
   sheet loads after it and takes the name over, so every one of those
   properties has to be undone by hand. Leaving height and overflow alone
   clamps the whole control bar to 26px and clips the controls out of sight. */
.bar {
  height: auto; overflow: visible;
  position: sticky; top: 128px; z-index: 98;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 11px 13px; margin: 0 0 14px;
  display: flex; flex-wrap: wrap; gap: 9px; align-items: flex-end;
  box-shadow: 0 6px 20px -18px rgba(15,23,42,0.5);
}
.bar > .grow { flex: 1 1 200px; min-width: 0; }
.bar label.fld { min-width: 0; }
.bar label.fld input[type=text], .bar label.fld select { width: 100%; min-width: 0; }
.bar .go { flex: 0 0 auto; }
/* Undo the two absolutely positioned children of the progress meter, so a
   plain <span> or <b> placed in a control bar lays out as itself. */
.bar > span, .bar > b { position: static; inset: auto; transform: none; background: none; }

@media (max-width: 640px) {
  /* Stacked and full width on a phone: thumbs, not cursors. */
  .bar { position: static; padding: 12px; gap: 10px; }
  .bar > * { flex: 1 1 100%; }
  .bar .go { width: 100%; padding: 13px 16px; font-size: 13px; }
  .bar label.fld { width: 100%; }
  input[type=text], select, textarea { font-size: 16px; } /* stops iOS zooming on focus */
}

/* --- Segmented control ---------------------------------------------------
   For screens with more than one view. Behaves like app tabs. */
.seg { display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 11px; padding: 3px; overflow-x: auto; scrollbar-width: none; }
.seg::-webkit-scrollbar { display: none; }
.seg button {
  flex: 1 1 auto; font-family: var(--mono); font-size: 12px; font-weight: 600;
  color: var(--muted); background: transparent; border: none; border-radius: 8px;
  padding: 8px 12px; cursor: pointer; white-space: nowrap; min-height: 38px;
  transition: color .15s, background .15s;
}
.seg button:hover { color: var(--text); }
.seg button[aria-selected="true"] { color: var(--text); background: var(--surface); box-shadow: 0 1px 2px rgba(15,23,42,0.07); }
.tabpanel[hidden] { display: none; }

/* --- Disclosures ---------------------------------------------------------
   Where the long explanation goes. Present, findable, and closed by default so
   it never sits between the user and the answer. */
details.note {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; margin-top: 11px; overflow: hidden;
}
details.note > summary {
  cursor: pointer; list-style: none; padding: 11px 14px;
  font-size: 12px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: 8px; min-height: 42px;
}
details.note > summary::-webkit-details-marker { display: none; }
details.note > summary::after {
  content: "+"; margin-left: auto; color: var(--muted);
  font-size: 15px; line-height: 1; transition: transform .2s;
}
details.note[open] > summary::after { content: "\2212"; }
details.note > summary:hover { background: var(--surface-2); }
details.note .body { padding: 0 14px 13px; font-size: 12.5px; color: var(--muted); line-height: 1.62; }
details.note .body p { margin: 0 0 9px; overflow-wrap: anywhere; }
details.note .body p:last-child { margin-bottom: 0; }
details.note .body b { color: var(--text); }

/* --- Empty and result states --------------------------------------------- */
.screen { min-height: 160px; }
.hint { text-align: center; color: var(--dim); font-size: 12.5px; padding: 30px 18px; }

/* --- Metric tiles --------------------------------------------------------
   The dense readout an app leads with, before any explanation. */
.tiles { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 9px; }
@media (min-width: 640px) { .tiles { grid-template-columns: repeat(4, minmax(0,1fr)); } .tiles.t3 { grid-template-columns: repeat(3, minmax(0,1fr)); } }
/* A tile has three parts and they must not read as one paragraph: the label is
   chrome, the value is what the tool measured, the caption is context. Colour
   alone was carrying that, which is thin. The value now sits on its own tinted
   panel with a state rail down the left of the tile, so a result reads as
   output rather than as a large heading. */
.tile {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border-2);
  border-radius: 13px; padding: 12px 13px; min-width: 0;
}
.tile .lab { font-size: 9.5px; text-transform: uppercase; letter-spacing: .11em; color: var(--muted); font-weight: 700; }
.tile .val {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.05rem, 5.2vw, 1.45rem); letter-spacing: -0.02em;
  color: #0b1220; line-height: 1.18; overflow-wrap: anywhere;
  margin-top: 6px; padding: 7px 9px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 9px;
}
.tile .sub { font-size: 11px; color: var(--muted); margin-top: 6px; overflow-wrap: anywhere; }

/* State reads on the rail and the panel, so it survives being glanced at. */
.tile.pass { border-left-color: var(--accent); }
.tile.warn { border-left-color: #d97706; }
.tile.risk { border-left-color: var(--kev); }
.tile.pass .val { color: var(--accent); background: #ecfdf5; border-color: #a7f3d0; }
.tile.warn .val { color: #b45309; background: #fffbeb; border-color: #fde68a; }
.tile.risk .val { color: var(--kev); background: #fef2f2; border-color: #fecaca; }

/* An identifier is read character by character, so it goes monospace and drops
   the display weight. A 39 character IPv6 address at 1.45rem display bold wraps
   into three ragged lines and stops looking like an address at all. */
.readout {
  display: block; font-family: var(--mono); font-weight: 700;
  font-size: clamp(0.82rem, 3.6vw, 1rem); letter-spacing: -0.01em;
  line-height: 1.35; overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}

/* Tighter page frame on phones: the tool should fill the screen. */
@media (max-width: 640px) {
  .wrap { padding: 14px 11px 56px; }
  .panel { padding: 13px; border-radius: 14px; }
  .card { padding: 12px 13px; }
}

/* --- Icons ---------------------------------------------------------------
   Inline SVG, sized in ems so an icon tracks the text beside it, and coloured
   by currentColor so it takes the accent on an active tab with no extra rule.
   This replaced an emoji icon set: emoji fall back to tofu on Linux boxes with
   no emoji font, and flag emoji never render on Windows Chrome at all. */
.ic { width: 1.15em; height: 1.15em; flex: none; vertical-align: -0.2em; }
.ic-lg { width: 22px; height: 22px; vertical-align: middle; }
.rail a .ic { width: 15px; height: 15px; }
.suite a .ic-lg { color: var(--accent); }

/* Country code badge. Replaces the flag emoji, which Windows Chrome renders as
   two bare letters and a Linux box with no emoji font renders as tofu. */
.cc {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 18px; padding: 0 5px;
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  color: var(--muted); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 4px;
  font-variant-numeric: tabular-nums; vertical-align: 1px;
}


/* --- Sticky offsets ------------------------------------------------------
   Values are measured and published by vpn.js (see syncSticky). The fallbacks
   are the common case: 40px brand strip + 40px nav = 80, plus a 48px rail. */
.railwrap { top: var(--rail-top, 80px); }
.bar { top: var(--bar-top, 128px); }
/* tool.css pins a table header with position:sticky and top:82px. That cannot
   work here: every wide table in this suite sits inside an overflow-x:auto
   wrapper so it can scroll sideways, and a sticky element resolves against its
   nearest scroll container rather than the viewport. The header therefore came
   to rest 82px down inside its own scroll box, floating over row two, instead
   of pinning under the site header.

   Pinning it correctly would mean giving up the horizontal scroll wrapper, and
   that wrapper is what keeps a seven-column table off the page's own scrollbar.
   The wrapper is worth more than the pinned header, so the header stays put. */
.wrap thead th { position: static; }

/* The reverse link block. Same chrome as .also, with the accent border that
   marks it as leaving the tool for the writing. */
.guides a { border-color: rgba(5,150,105,0.35); }
.guides a:hover { background: #ecfdf5; }
