/* =========================================================================
   Link Safety Checker - stylesheet
   Mobile-first. No frameworks, no external assets except the Google Font
   link in index.php (which degrades to the system stack).
   ========================================================================= */

:root {
  --bg:            #f4f7fb;
  --bg-soft:       #eaf0f8;
  --surface:       #ffffff;
  --surface-2:     #f7f9fc;
  --ink:           #0f1b2d;
  --ink-2:         #33465e;
  --muted:         #62748b;
  --muted-2:       #8496ab;
  --line:          #e2e9f2;
  --line-strong:   #c8d5e4;

  --brand:         #1a6ef5;
  --brand-dark:    #0b47a8;
  --brand-soft:    #e8f0ff;

  --good:          #12925f;
  --good-soft:     #e3f6ee;
  --warn:          #b87400;
  --warn-soft:     #fdf1dd;
  --bad:           #cf2f2f;
  --bad-soft:      #fdeaea;
  --demo:          #64748b;
  --demo-soft:     #eef1f5;

  /* ---- radius system: one step per surface size, nothing ad-hoc ----
     xs  pills inside cards      sm  rows, chips, small tiles
     md  inputs, buttons, cards  lg  hero cards, verdict, gate
     xl  the biggest surfaces    pill fully round                     */
  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* ---- elevation: three steps, all tinted with the ink colour so the
     shadows read as depth rather than as grey smudge ---- */
  --sh-1: 0 1px 2px rgba(15,27,45,.04), 0 2px 6px -2px rgba(15,27,45,.07);
  --sh-2: 0 2px 6px rgba(15,27,45,.05), 0 16px 34px -20px rgba(15,27,45,.30);
  --sh-3: 0 3px 10px rgba(15,27,45,.07), 0 30px 60px -28px rgba(15,27,45,.36);
  --sh-brand: 0 10px 24px -14px rgba(26,110,245,.95);

  /* one focus ring, used everywhere */
  --ring: 0 0 0 3px rgba(26,110,245,.38);
  --ring-col: rgba(26,110,245,.45);

  /* the sticky header's height — anchors offset themselves by it */
  --nav-h: 60px;

  /* Height reserved at the bottom of the page for Google's BOTTOM_ANCHOR ad.
     Google renders the anchor itself, fixed to the viewport bottom, at up to
     ~100px on phones. Reserving this much keeps the footer and the "Open
     link" button clear of it. Only applied when app.js has actually defined
     the anchor (html.has-anchor-ad). */
  --anchor-h: 100px;

  /* shared motion curve */
  --ease: cubic-bezier(.4, 0, .2, 1);

  --sans: "Inter", "Noto Sans Devanagari", system-ui, -apple-system, "Segoe UI",
          Roboto, "Nirmala UI", "Noto Sans", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;

  --wrap: 720px;
}

* { box-sizing: border-box; }

/* No blue flash on tap, anywhere. Every interactive element gets its own
   :active / :focus-visible treatment below instead — a brand-coloured ring,
   never the browser's default highlight box. */
* { -webkit-tap-highlight-color: transparent; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;          /* the nav anchors glide, not jump */
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* No flash of the wrong language: the inline <head> script adds .lang-pending
   before the first paint and app.js removes it the moment the dictionary has
   been applied (with a 1.5s dead-man's timer in the same inline script, so a
   JS failure can never leave the page blank). */
html.lang-pending body { visibility: hidden; }

/* Two very soft brand/green glows behind the top of the page. They are fixed
   and non-repeating, so they never add scroll height and never shift layout. */
body {
  margin: 0;
  /* NO top padding / margin here and none on the header: the nav bar must be
     the first visible pixel of the page. The page-top 300x250 lives below the
     header, so nothing reserves empty space above it. */
  padding-top: 0;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  background-color: var(--bg);
  background-image:
    radial-gradient(52rem 26rem at 50% -12rem, rgba(26,110,245,.13), transparent 70%),
    radial-gradient(36rem 20rem at 88% -6rem, rgba(18,146,95,.09), transparent 72%);
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 { margin: 0; line-height: 1.25; letter-spacing: -.015em; }
p { margin: 0; }
ol, ul { margin: 0; padding: 0; list-style: none; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 16px; }
.section { padding: 18px 0 26px; }
.mono { font-family: var(--mono); }
.small { font-size: 13px; }
.muted { color: var(--muted); }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.break { overflow-wrap: anywhere; word-break: break-word; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon {
  width: 20px; height: 20px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.icon--lg { width: 26px; height: 26px; }

/* ================================== ADS =================================
   Every ad container is a plain centered <div>, min 300x250, filled by
   Google Ad Manager (GPT) from app.js. Nothing here is sticky and nothing
   is ever wider than the viewport: the 300px box shrinks its own margins
   instead of pushing the page sideways.
   ======================================================================== */
.adslot {
  display: block;
  width: 300px;
  max-width: 100%;
  /* height is RESERVED before GPT answers, so filling the slot (or failing to)
     never pushes the page around: 250px is held from first paint. */
  min-height: 250px;
  height: auto;
  margin-top: 22px;
  margin-bottom: 22px;
  margin-left: auto;     /* centred whatever container it lands in */
  margin-right: auto;
  text-align: center;
  /* no border-radius and no `contain` here on purpose: the creative must never
     be clipped or isolated — the slot stays a plain, fully visible 300x250. */
  overflow: hidden;
}
/* GPT writes an inner div + iframe; centre both so the creative never sits
   left-aligned inside its 300px box. */
.adslot > iframe,
.adslot > div,
.adslot > div > iframe { margin-left: auto; margin-right: auto; display: block; }

/* Page-top in-content slot. It sits directly UNDER the header (see
   index.php) so the nav is the first visible thing; the small top padding is
   breathing room below the bar, never a gap above it. Not sticky. */
.adtop { padding: 12px 0 0; text-align: center; }
.adtop .adslot { margin-top: 0; margin-bottom: 6px; }

/* =================== GOOGLE BOTTOM ANCHOR: CLEARANCE ====================
   The anchor itself is drawn and positioned by Google (out-of-page format);
   there is deliberately NO custom fixed ad bar in this stylesheet, so the
   Google anchor is the ONLY sticky ad on the page — never a second one and
   never a top one. All we do here is reserve room at the bottom of the
   document so the fixed anchor cannot cover the footer or the "Open link"
   button. The class is added by app.js only when the anchor was actually
   defined (ADS_LIVE true + googletag.enums present), so placeholder mode
   never shows an empty gap.
   ======================================================================== */
html.has-anchor-ad body {
  padding-bottom: calc(var(--anchor-h) + env(safe-area-inset-bottom, 0px));
}
html.has-anchor-ad .footer { padding-bottom: 26px; }
/* the last actionable thing on the report gets its own margin too, so the
   anchor can never sit on top of the open/scan-again buttons */
html.has-anchor-ad .openrow { margin-bottom: 10px; }

/* Review mode only (ADS_LIVE = false in app.js). */
.adslot--ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 250px;
  border: 2px dashed var(--line-strong);
  border-radius: var(--r-md);
  background-image: repeating-linear-gradient(
      45deg, rgba(148,163,184,.10) 0 9px, rgba(148,163,184,.04) 9px 18px);
  background-color: var(--surface-2);
  user-select: none;
}
.adslot__label {
  font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.adslot__pos {
  font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
  color: var(--muted-2);
}

/* ===================== HOUSE AD (our own app promo) =====================
   Drawn by app.js into a 300x250 that Google Ad Manager returned EMPTY, so
   the box is a real card instead of a blank. It is first-party markup: no
   iframe, no third-party script, one local icon. Sized to sit exactly inside
   the reserved 300x250 so nothing on the page shifts when it appears.
   ======================================================================== */
.housead {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  box-sizing: border-box;
  width: 300px;
  height: 250px;
  max-width: 100%;
  margin: 0 auto;
  padding: 16px 14px 14px;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  background:
    radial-gradient(22rem 12rem at 50% -6rem, rgba(26,110,245,.10), transparent 70%),
    var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  overflow: hidden;
  -webkit-tap-highlight-color: rgba(26,110,245,.12);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.housead:hover { border-color: var(--line-strong); box-shadow: var(--sh-2); }
.housead:active { transform: translateY(1px); }
.housead:focus-visible { outline: none; box-shadow: var(--ring); }

/* the quiet corner label: this is a promo, not page chrome */
.housead__tag {
  position: absolute; top: 8px; right: 9px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  padding: 2px 6px;
  line-height: 1.2;
}

.housead__icon {
  width: 52px; height: 52px; flex: 0 0 auto;
  border-radius: 12px;                /* rounded app icon */
  border: 1px solid var(--line);
  background: var(--surface-2);
  object-fit: cover;
  margin-bottom: 5px;
}
.housead__name {
  font-size: 17px; font-weight: 700; line-height: 1.15; letter-spacing: -.01em;
  color: var(--ink);
}
/* Category + price, on ONE row. There is deliberately NO rating and no star
   here: the Play listing carries no ratingValue/ratingCount, so the card
   must not imply one. Do not re-add a rating row of any kind. */
.housead__sub {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 5px;
  font-size: 12px; line-height: 1.25; color: var(--muted);
}
.housead__dot { color: var(--muted-2); }
.housead__free { color: var(--good); font-weight: 600; }

/* The rotating headline: one angle out of five, picked per card, so two
   cards on the same page are not the same banner. Two lines at most. */
.housead__head {
  margin-top: 6px;
  font-size: 13.5px; font-weight: 700; line-height: 1.3; letter-spacing: -.005em;
  color: var(--ink);
  max-width: 262px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.housead__line {
  margin: 3px 0 0;
  /* 1.45 leading, not 1.35: Devanagari needs the extra room or the second
     line is clipped by the two-line clamp. */
  font-size: 11.5px; line-height: 1.45; color: var(--ink-2);
  max-width: 254px;
  /* one line of copy, two at most on the widest scripts */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.housead__cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  margin-top: 8px;
  min-height: 36px;                    /* comfortably tappable */
  padding: 8px 18px;
  border-radius: var(--r-pill);
  background: linear-gradient(165deg, #3b88ff, var(--brand));
  color: #fff; font-size: 13.5px; font-weight: 700; letter-spacing: .01em;
  box-shadow: var(--sh-brand);
}
.housead__play { width: 14px; height: 14px; flex: 0 0 auto; display: block; }

/* very short viewports / large system fonts: keep everything inside the box */
@media (max-height: 620px) {
  .housead__head { -webkit-line-clamp: 1; }
  .housead__line { -webkit-line-clamp: 2; }
}

/* ========================== HEADER / NAV BAR ============================
   Sticky, translucent bar. Left: brand + shield mark. Right: the anchor nav,
   the language toggle, and (below 760px) the menu button that the anchors
   collapse behind. The bar never grows taller than --nav-h, which is what
   every anchor target offsets itself by via scroll-margin-top.
   ======================================================================== */
.topbar {
  position: sticky; top: 0; z-index: 60;
  padding: 9px 0;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border-bottom: 1px solid var(--line);
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) {
  .topbar {
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
  }
}
/* solid fallback wherever color-mix is not understood */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .topbar { background: var(--bg); }
}
.topbar__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; min-height: 42px;
}
.topbar__right { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

.brand {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 16px; min-width: 0; flex: 0 1 auto;
  text-decoration: none; color: inherit;
  border-radius: var(--r-sm);
  transition: opacity .16s var(--ease);
}
.brand:hover { opacity: .86; }
.brand:active { transform: scale(.985); }
.brand__mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto; border-radius: 11px;
  background: linear-gradient(160deg, #5ba3ff, var(--brand));
  color: #fff; box-shadow: var(--sh-brand);
  position: relative;
}
.brand__mark::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  border: 1px solid rgba(255,255,255,.28); pointer-events: none;
}
.brand__mark .icon { width: 19px; height: 19px; stroke-width: 2; }
.brand__text {
  font-weight: 500; color: var(--ink-2); letter-spacing: -.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand__text strong { font-weight: 700; color: var(--ink); }
.brand__tag { color: var(--muted); font-weight: 500; }

/* ------------------------------- the nav -------------------------------- */
.nav { display: flex; align-items: center; gap: 2px; }
.nav__a {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 8px 11px; border-radius: var(--r-sm);
  font-size: 13.5px; font-weight: 600; line-height: 1.2;
  color: var(--muted); text-decoration: none; white-space: nowrap;
  transition: color .15s var(--ease), background .15s var(--ease);
}
.nav__a:hover { color: var(--ink); background: var(--surface-2); }
.nav__a:active { background: var(--bg-soft); }
.nav__a:focus-visible { outline: 3px solid var(--ring-col); outline-offset: 2px; }
.nav__a .icon { width: 14px; height: 14px; opacity: .7; }
.nav__a--ext { color: var(--brand-dark); }
.nav__a--ext:hover { color: var(--brand-dark); background: var(--brand-soft); }

/* menu button: three bars that become an X when the panel is open */
.navbtn {
  display: none;                 /* only below 760px */
  appearance: none; -webkit-appearance: none;
  width: 40px; height: 38px; padding: 0;
  align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  cursor: pointer;
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.navbtn:hover { background: var(--bg-soft); }
.navbtn:active { transform: scale(.96); }
.navbtn:focus-visible { outline: 3px solid var(--ring-col); outline-offset: 2px; }
.navbtn__bars { position: relative; display: block; width: 17px; height: 12px; }
.navbtn__bars i {
  position: absolute; left: 0; right: 0; height: 2px; border-radius: 2px;
  background: currentColor;
  transition: transform .2s var(--ease), opacity .15s var(--ease), top .2s var(--ease);
}
.navbtn__bars i:nth-child(1) { top: 0; }
.navbtn__bars i:nth-child(2) { top: 5px; }
.navbtn__bars i:nth-child(3) { top: 10px; }
.topbar.is-open .navbtn { background: var(--brand-soft); border-color: #cfe0ff; color: var(--brand-dark); }
.topbar.is-open .navbtn__bars i:nth-child(1) { top: 5px; transform: rotate(45deg); }
.topbar.is-open .navbtn__bars i:nth-child(2) { opacity: 0; }
.topbar.is-open .navbtn__bars i:nth-child(3) { top: 5px; transform: rotate(-45deg); }

.badge {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: .12em; padding: 4px 8px; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); color: var(--muted); background: var(--surface);
}

/* ---------------------------- language toggle ---------------------------
   Two pills. The active one is filled; switching is instant (no reload) and
   the choice is stored in the hs_lang cookie for a year. */
.langtog {
  display: inline-flex; flex: 0 0 auto; gap: 2px; padding: 3px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-pill); box-shadow: inset 0 1px 2px rgba(15,27,45,.04);
}
.langtog__b {
  appearance: none; -webkit-appearance: none;
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
  padding: 7px 12px; min-height: 32px; min-width: 42px;
  border: 0; border-radius: var(--r-pill); cursor: pointer;
  background: transparent; color: var(--muted);
  transition: background .16s var(--ease), color .16s var(--ease), transform .1s var(--ease);
}
.langtog__b:hover { color: var(--ink-2); }
.langtog__b:active { transform: scale(.96); }
.langtog__b.is-on,
.langtog__b[aria-pressed="true"] {
  background: var(--surface); color: var(--brand-dark);
  box-shadow: var(--sh-1); border: 1px solid var(--line);
  padding: 6px 11px;
}
.langtog__b:focus-visible {
  outline: 3px solid var(--ring-col); outline-offset: 1px;
}

/* ---------------------- nav on small screens ---------------------------
   Brand + language toggle never move. The three anchor links drop into a
   panel under the bar, opened by the menu button (app.js flips .is-open on
   the header and keeps aria-expanded in step). */
@media (max-width: 759px) {
  .navbtn { display: inline-flex; }
  .nav {
    position: absolute; top: calc(100% + 6px); right: 12px; left: 12px;
    z-index: 61;
    flex-direction: column; align-items: stretch; gap: 2px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-md);
    box-shadow: var(--sh-3);
    opacity: 0; visibility: hidden;
    transform: translateY(-6px) scale(.99); transform-origin: top right;
    pointer-events: none;
    transition: opacity .16s var(--ease), transform .16s var(--ease),
                visibility 0s linear .18s;
  }
  .topbar.is-open .nav {
    opacity: 1; visibility: visible; pointer-events: auto;
    transform: none; transition-delay: 0s;
  }
  .nav__a {
    justify-content: flex-start;
    padding: 12px 12px; font-size: 14.5px; border-radius: var(--r-sm);
    color: var(--ink-2);
  }
  .nav__a + .nav__a { border-top: 1px solid var(--line); border-radius: var(--r-sm); }
  .nav__a--ext { color: var(--brand-dark); }
}
/* the panel is positioned against the bar */
.topbar__in { position: relative; }

/* ================================= HERO ================================= */
.hero { text-align: center; padding: 14px 0 4px; }
.hero__art {
  display: flex; justify-content: center; margin-bottom: 4px;
  position: relative;
}
.hero__shield {
  width: 112px; height: 112px;
  filter: drop-shadow(0 18px 30px rgba(26,110,245,.22));
  animation: heroin .5s var(--ease) both;
}
@keyframes heroin {
  from { opacity: 0; transform: translateY(8px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

/* small capability chip above the headline */
.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  margin: 0 auto 12px;
  padding: 6px 13px 6px 10px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--sh-1);
  font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  letter-spacing: -.005em;
}
.hero__eyebrow .icon { width: 15px; height: 15px; color: var(--good); }

.hero__title {
  font-size: 31px; font-weight: 700; letter-spacing: -.032em;
  margin-bottom: 12px; text-wrap: balance;
}
.hero__sub {
  color: var(--muted); font-size: 15px; max-width: 470px;
  margin: 0 auto 22px; text-wrap: pretty;
}

/* ============================== SCAN BOX ================================ */
.scanbox { max-width: 490px; margin: 0 auto; text-align: left; }
.scanbox__row {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 4px 14px;
  box-shadow: var(--sh-2);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.scanbox__row:hover { border-color: #9fbbe0; }
.scanbox__row:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(26,110,245,.14), var(--sh-2);
}
.scanbox__icon { color: var(--muted-2); display: inline-flex; transition: color .18s var(--ease); }
.scanbox__row:focus-within .scanbox__icon { color: var(--brand); }
.scanbox__input {
  flex: 1 1 auto; min-width: 0;
  border: 0; outline: none; background: transparent;
  font: inherit; font-size: 15px; color: var(--ink);
  padding: 13px 0;
}
.scanbox__input::placeholder { color: var(--muted-2); }
.scanbox__err {
  margin-top: 9px; color: var(--bad); font-size: 13px; font-weight: 600;
  display: block; text-align: center;
}

/* ================================ BUTTONS =============================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-weight: 650; font-size: 15px;
  padding: 14px 22px; border-radius: var(--r-md);
  border: 1.5px solid transparent; cursor: pointer;
  text-decoration: none; line-height: 1.2; letter-spacing: -.005em;
  transition: transform .12s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease), border-color .18s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid var(--ring-col); outline-offset: 2px; }
.btn--block { width: 100%; margin-top: 13px; }
.btn--primary {
  background: linear-gradient(165deg, #3b88ff, var(--brand));
  color: #fff; box-shadow: var(--sh-brand);
}
.btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 30px -14px rgba(26,110,245,1);
}
.btn--primary:active { transform: translateY(1px); }
.btn--ghost {
  background: var(--surface); color: var(--ink-2); border-color: var(--line-strong);
  box-shadow: var(--sh-1);
}
.btn--ghost:hover { background: var(--surface-2); border-color: #9fbbe0; }
.btn--open {
  background: linear-gradient(165deg, #18ab6c, var(--good));
  color: #fff; box-shadow: 0 10px 24px -13px rgba(18,146,95,.95);
}
.btn--open:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 30px -14px rgba(18,146,95,1);
}
.btn--danger-open {
  background: var(--surface); color: var(--bad); border-color: var(--bad);
}
.btnrow { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.btnrow .btn { flex: 1 1 180px; }

/* ============================== CHECKLIST =============================== */
.checklist {
  display: grid; grid-template-columns: 1fr; gap: 9px;
  max-width: 490px; margin: 24px auto 0; text-align: left;
}
.checklist li {
  display: flex; align-items: center; gap: 11px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 12px 14px;
  font-size: 14px; font-weight: 500; color: var(--ink-2);
  box-shadow: var(--sh-1);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease),
              border-color .16s var(--ease);
}
.checklist li:hover {
  transform: translateY(-1px); box-shadow: var(--sh-2); border-color: var(--line-strong);
}
.checklist .icon { color: var(--brand); width: 18px; height: 18px; }

.honesty-note {
  display: flex; gap: 11px; align-items: flex-start; text-align: left;
  max-width: 490px; margin: 20px auto 0;
  background: var(--brand-soft); border: 1px solid #cfe0ff;
  border-radius: var(--r-md); padding: 14px 15px;
  font-size: 13px; line-height: 1.65; color: var(--ink-2);
}
.honesty-note .icon { color: var(--brand); margin-top: 2px; width: 18px; height: 18px; }

.trustrow {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px;
  max-width: 490px; margin: 6px auto 0;
}
.trustrow__item {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 12px 8px; text-align: center;
  box-shadow: var(--sh-1);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease);
}
.trustrow__item:hover { transform: translateY(-1px); box-shadow: var(--sh-2); }
.trustrow__item strong { display: block; font-size: 13px; letter-spacing: -.01em; }
.trustrow__item span { font-size: 11.5px; color: var(--muted); }

/* ================================ PILLS ================================= */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 9px; border-radius: var(--r-pill);
  border: 1px solid transparent; white-space: nowrap;
}
.pill--inline { text-transform: none; letter-spacing: 0; }
.pill--demo { background: var(--demo-soft); color: var(--demo); border-color: var(--line-strong); border-style: dashed; }
.pill--unknown { background: var(--warn-soft); color: var(--warn); border-color: #f3ddb6; border-style: dashed; }
.pill--good { background: var(--good-soft); color: var(--good); border-color: #bfe8d7; }
.pill--warn { background: var(--warn-soft); color: var(--warn); border-color: #f3ddb6; }
.pill--bad  { background: var(--bad-soft);  color: var(--bad);  border-color: #f6c9c9; }
.pill--info { background: var(--brand-soft); color: var(--brand-dark); border-color: #cfe0ff; }
.pill--neutral { background: var(--surface-2); color: var(--muted); border-color: var(--line); }

/* ================================ SCANNING ============================== */
.scanhead { text-align: center; padding: 10px 0 20px; max-width: 560px; }
.scanhead__spin {
  width: 46px; height: 46px; margin: 0 auto 14px;
  border-radius: 50%;
  border: 3px solid var(--brand-soft);
  border-top-color: var(--brand);
  animation: spin .85s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.scanhead__done {
  width: 46px; height: 46px; margin: 0 auto 14px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--good-soft); border: 1px solid #bfe8d7; color: var(--good);
  animation: fadein .25s ease both;
}
.scanhead__done .icon { width: 26px; height: 26px; stroke-width: 2.2; }
.scanhead__done[hidden] { display: none; }

.scanhead__title { font-size: 21px; font-weight: 700; }
.scanhead__url {
  font-size: 12.5px; color: var(--muted); margin-top: 6px;
  overflow-wrap: anywhere; word-break: break-word;
}
.scanhead__count { font-size: 12px; color: var(--muted); margin-top: 8px; font-weight: 600; }

.progress {
  height: 7px; border-radius: var(--r-pill);
  background: var(--bg-soft); overflow: hidden; margin-top: 14px;
  border: 1px solid var(--line);
}
.progress__bar {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, #4f9bff, var(--brand));
  border-radius: var(--r-pill);
  transition: width .5s cubic-bezier(.4,0,.2,1);
}

.stages { display: grid; gap: 10px; }
.stage {
  display: flex; gap: 13px; align-items: flex-start;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 15px;
  box-shadow: var(--sh-1);
  opacity: .46;
  transition: opacity .3s var(--ease), border-color .3s var(--ease),
              box-shadow .3s var(--ease), transform .3s var(--ease);
}
.stage[data-state="running"] {
  opacity: 1; border-color: #bcd6ff; box-shadow: var(--sh-2);
  transform: translateY(-1px);
}
.stage[data-state="done"]    { opacity: 1; }
.stage[data-state="failed"]  { opacity: 1; border-color: #f3c4c4; }

.stage__dot {
  width: 30px; height: 30px; flex: 0 0 auto; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--line);
  color: var(--muted); font-size: 13px; font-weight: 700;
  font-family: var(--mono);
}
.stage[data-state="running"] .stage__dot {
  background: var(--brand-soft); border-color: #bcd6ff; color: var(--brand);
}
.stage[data-state="running"] .stage__dot::after {
  content: ""; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid rgba(26,110,245,.28); border-top-color: var(--brand);
  animation: spin .8s linear infinite;
}
.stage[data-state="running"] .stage__num { display: none; }
.stage[data-state="done"] .stage__dot { background: var(--good-soft); border-color: #bfe8d7; color: var(--good); }
.stage[data-state="partial"] { opacity: 1; }
.stage[data-state="partial"] .stage__dot {
  background: var(--warn-soft); border-color: #f3ddb6; border-style: dashed; color: var(--warn);
}
.stage[data-state="partial"] .stage__num { display: none; }
.stage[data-state="alert"] { opacity: 1; border-color: #f6c9c9; }
.stage[data-state="alert"] .stage__dot {
  background: var(--bad-soft); border-color: #f6c9c9; color: var(--bad);
}
.stage[data-state="alert"] .stage__num { display: none; }
.stage[data-state="failed"] .stage__dot { background: var(--bad-soft); border-color: #f6c9c9; color: var(--bad); }

.stage__body { flex: 1 1 auto; min-width: 0; }
.stage__title { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.stage__sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.stage__log {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted-2);
  margin-top: 7px; display: grid; gap: 2px;
}
.stage__log span { animation: fadein .3s ease both; }
@keyframes fadein { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
.stage__result {
  margin-top: 9px; display: flex; flex-wrap: wrap; align-items: center; gap: 7px;
  font-size: 13px; color: var(--ink-2);
}
.stage__result .break { flex: 1 1 100%; font-size: 12px; color: var(--muted); font-family: var(--mono); }

/* ========================= PROCESSING STEP (ad gate) =====================
   Two of these run between the finished stages and the report. They advance
   on their own — there is no countdown number and no button — so everything
   here is decoration around a fully visible 300x250 slot.
   ======================================================================== */
.gate {
  margin-top: 16px;
  max-width: 560px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px 16px; text-align: center;
  box-shadow: var(--sh-2);
  animation: gatein .32s var(--ease) both;
}
@keyframes gatein {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.gate__kicker {
  display: inline-block;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 10px;
  padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--surface-2); border: 1px solid var(--line);
}
.gate__lead { font-size: 15px; font-weight: 600; color: var(--ink); margin: 0 0 12px; }
.gate__note { font-size: 12px; color: var(--muted-2); margin: 2px 0 0; }
.gate .adslot { margin: 0 auto 12px; }
.gate .btn { width: 100%; max-width: 340px; }

/* pulsing shield */
.gate__art {
  position: relative; width: 64px; height: 64px; margin: 2px auto 12px;
  display: flex; align-items: center; justify-content: center;
}
.gate__pulse {
  position: absolute; inset: 0; border-radius: 50%;
  background: var(--brand); opacity: .16;
  animation: gatepulse 1.8s ease-out infinite;
}
.gate__pulse::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--brand); opacity: .5;
  animation: gatering 1.8s ease-out infinite;
}
.gate__shield {
  position: relative; width: 30px; height: 30px;
  color: var(--brand); stroke-width: 1.8;
}
@keyframes gatepulse {
  0%   { transform: scale(.78); opacity: .10; }
  55%  { transform: scale(1);   opacity: .22; }
  100% { transform: scale(.78); opacity: .10; }
}
@keyframes gatering {
  0%   { transform: scale(.8); opacity: .55; }
  80%  { transform: scale(1.18); opacity: 0; }
  100% { transform: scale(1.18); opacity: 0; }
}

/* indeterminate shimmer — deliberately not a percentage, not a countdown */
.gate__shimmer {
  position: relative; height: 6px; width: 100%; max-width: 300px;
  margin: 0 auto 14px; border-radius: var(--r-pill);
  background: var(--bg-soft); border: 1px solid var(--line); overflow: hidden;
}
.gate__shimmerbar {
  position: absolute; top: 0; bottom: 0; left: 0; width: 42%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, rgba(26,110,245,0), #4f9bff, var(--brand), rgba(26,110,245,0));
  animation: gateshimmer 1.45s cubic-bezier(.45,0,.35,1) infinite;
}
@keyframes gateshimmer {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(340%); }
}
/* With motion reduced the global rule freezes the animations; keep the bar
   visible so the step never looks broken or stalled. */
@media (prefers-reduced-motion: reduce) {
  .gate__shimmerbar { width: 100%; transform: none; }
  .gate__pulse { opacity: .18; }
}

/* ================================ REPORT ================================ */
/* The verdict banner. A 4px accent rail across the top carries the tone, so
   green / amber / red reads at a glance even before the words are parsed. */
.verdict {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg); padding: 26px 18px 22px; text-align: center;
  border: 1.5px solid var(--line); background: var(--surface);
  box-shadow: var(--sh-3);
  max-width: 560px;
  animation: gatein .34s var(--ease) both;
}
.verdict::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: var(--line-strong);
}
.verdict__icon {
  width: 64px; height: 64px; margin: 0 auto 14px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
.verdict__icon::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 1px solid currentColor; opacity: .18;
}
.verdict__icon .icon { width: 32px; height: 32px; stroke-width: 2; }
.verdict__title { font-size: 25px; font-weight: 700; letter-spacing: -.028em; text-wrap: balance; }
.verdict__sub { font-size: 14px; margin-top: 8px; color: var(--muted); text-wrap: pretty; }
.verdict__url {
  margin-top: 14px; font-family: var(--mono); font-size: 12px;
  color: var(--muted); overflow-wrap: anywhere; word-break: break-word;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 10px 12px; text-align: left;
}

.verdict--safe   { border-color: #bfe8d7; background: linear-gradient(180deg, var(--good-soft), var(--surface) 62%); }
.verdict--safe::before { background: linear-gradient(90deg, #35c58c, var(--good)); }
.verdict--safe   .verdict__icon { background: var(--good); color: #fff; box-shadow: 0 12px 26px -14px rgba(18,146,95,.95); }
.verdict--safe   .verdict__title { color: #0c6c46; }

.verdict--caution{ border-color: #f3ddb6; background: linear-gradient(180deg, var(--warn-soft), var(--surface) 62%); }
.verdict--caution::before { background: linear-gradient(90deg, #e6b25a, var(--warn)); }
.verdict--caution .verdict__icon { background: var(--warn); color: #fff; box-shadow: 0 12px 26px -14px rgba(184,116,0,.95); }
.verdict--caution .verdict__title { color: #8a5800; }

.verdict--danger { border-color: #f6c9c9; background: linear-gradient(180deg, var(--bad-soft), var(--surface) 62%); }
.verdict--danger::before { background: linear-gradient(90deg, #f3706e, var(--bad)); }
.verdict--danger .verdict__icon { background: var(--bad); color: #fff; box-shadow: 0 12px 26px -14px rgba(207,47,47,.95); }
.verdict--danger .verdict__title { color: #9d1f1f; }

.verdict--demo::before,
.verdict--unknown::before { background: repeating-linear-gradient(90deg, var(--line-strong) 0 8px, transparent 8px 16px); }
.verdict--demo,
.verdict--unknown { border-color: var(--line-strong); border-style: dashed; background: linear-gradient(180deg, var(--demo-soft), var(--surface) 60%); }
.verdict--demo   .verdict__icon,
.verdict--unknown .verdict__icon { background: var(--demo); color: #fff; }
.verdict--demo   .verdict__title,
.verdict--unknown .verdict__title { color: #3d4b5c; }

/* ---- COULD NOT VERIFY --------------------------------------------------
   The scan never reached the destination, so the report is about a check
   that did not finish — not about a link that misbehaved. The state is
   therefore deliberately calm: a soft amber-neutral card with a solid rail
   and a slate icon. It is declared AFTER the caution and unknown skins and
   overrides both, so a could-not-verify report can never wear danger (or
   even full warning) colours. */
.verdict--cnv {
  border-color: #e7dcc2; border-style: solid;
  background: linear-gradient(180deg, var(--warn-soft), var(--surface) 66%);
}
.verdict--cnv::before { background: linear-gradient(90deg, var(--line-strong), #e6b25a); }
.verdict--cnv .verdict__icon {
  background: var(--demo); color: #fff;
  box-shadow: 0 12px 26px -14px rgba(100,116,139,.9);
}
.verdict--cnv .verdict__title { color: #6d5a24; }

/* The partial-scan panel in the same state: information, not an alarm. */
.panel--cnv { border-color: var(--line-strong); background: var(--demo-soft); }
.panel--cnv .panel__icon { background: var(--demo); color: #fff; }

/* ------------------------------ safety score ---------------------------- */
.score { max-width: 340px; margin: 14px auto 2px; text-align: center; }
.score__k {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.score__track {
  height: 9px; border-radius: var(--r-pill); overflow: hidden;
  background: var(--bg-soft); border: 1px solid var(--line);
}
.score__bar { display: block; height: 100%; border-radius: var(--r-pill); }
.score__bar--good { background: linear-gradient(90deg, #35c58c, var(--good)); }
.score__bar--warn { background: linear-gradient(90deg, #e6b25a, var(--warn)); }
.score__bar--bad  { background: linear-gradient(90deg, #f3706e, var(--bad)); }
.score__cap { font-size: 12px; color: var(--muted); margin-top: 6px; }

/* ----------------------- reputation signal checklist --------------------
   One friendly line per api.php reputation signal:
     good = green tick · info = grey · warn = amber · bad = red             */
/* ------------------- the reputation signal checklist -------------------
   One row per observable signal. Tone lives in the left icon chip and a soft
   tinted surface; the text itself stays high-contrast and readable. */
.signals { display: grid; gap: 8px; padding: 8px 0 4px; }
.signal {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface-2);
  font-size: 13.5px; line-height: 1.55; color: var(--ink-2);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.signal:hover { box-shadow: var(--sh-1); }
.signal__ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: 50%;
  border: 1px solid transparent;
}
.signal__ic .icon { width: 14px; height: 14px; stroke-width: 2.4; }
.signal__t { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }

.signal--good { background: var(--good-soft); border-color: #bfe8d7; }
.signal--good .signal__ic { background: var(--good); color: #fff; }
.signal--info { background: var(--surface-2); border-color: var(--line); }
.signal--info .signal__ic { background: var(--demo-soft); color: var(--muted); border-color: var(--line-strong); }
.signal--warn { background: var(--warn-soft); border-color: #f3ddb6; }
.signal--warn .signal__ic { background: var(--warn); color: #fff; }
.signal--bad  { background: var(--bad-soft); border-color: #f6c9c9; }
.signal--bad  .signal__ic { background: var(--bad); color: #fff; }
.signal--bad .signal__t { font-weight: 600; color: var(--ink); }

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
  margin: 14px auto 0; overflow: hidden; max-width: 560px;
  transition: box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.card:hover { box-shadow: var(--sh-2); border-color: var(--line-strong); }
.card__head {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 17px 13px; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--surface), var(--surface-2));
  flex-wrap: wrap;
}
.card__head .icon { color: var(--brand); }
.card__title { font-size: 15px; font-weight: 700; letter-spacing: -.01em; flex: 1 1 auto; }
.card__body { padding: 6px 16px 15px; }
.card--demo { border-style: dashed; border-color: var(--line-strong); }
.card--demo .card__head .icon { color: var(--muted); }

.kv {
  display: flex; gap: 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px dashed var(--line);
}
.kv:last-child { border-bottom: 0; }
.kv__k { flex: 0 0 38%; font-size: 12.5px; color: var(--muted); font-weight: 500; }
.kv__v {
  flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--ink);
  overflow-wrap: anywhere; word-break: break-word;
}
.kv__v.mono { font-size: 12.5px; }
.kv__v.is-empty { color: var(--muted-2); font-style: italic; }

/* demo (unconfigured) presentation: visibly greyed + never a pass */
.is-demo { color: var(--muted-2) !important; }
.demoblock {
  position: relative;
  filter: grayscale(1);
  opacity: .55;
  padding-bottom: 16px;   /* keeps the SAMPLE watermark clear of the content */
}
.demoblock::after {
  content: "SAMPLE"; position: absolute; inset: auto 2px 0 auto;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .18em;
  color: var(--muted-2); pointer-events: none;
}
.demo-note {
  display: flex; gap: 8px; align-items: flex-start;
  margin: 10px 0 2px; padding: 10px 11px;
  background: var(--demo-soft); border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm); font-size: 12.5px; color: var(--ink-2); line-height: 1.5;
}
.demo-note .icon { width: 16px; height: 16px; color: var(--muted); margin-top: 2px; }

/* big stat (VirusTotal) */
.stat {
  display: flex; align-items: baseline; justify-content: center; gap: 6px;
  padding: 12px 0 4px;
}
.stat__n { font-size: 40px; font-weight: 700; letter-spacing: -.04em; line-height: 1; }
.stat__d { font-size: 17px; color: var(--muted); font-weight: 600; }
.stat__cap { text-align: center; font-size: 12.5px; color: var(--muted); padding-bottom: 8px; }
.stat--good .stat__n { color: var(--good); }
.stat--bad  .stat__n { color: var(--bad); }
.stat--demo .stat__n { color: var(--muted-2); }

.engines { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 8px; }
.engine {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 9px 10px; text-align: center;
}
.engine__n { display: block; font-size: 17px; font-weight: 700; line-height: 1.2; }
.engine__k { font-size: 11px; color: var(--muted); letter-spacing: .03em; }
.engine--bad  .engine__n { color: var(--bad); }
.engine--warn .engine__n { color: var(--warn); }
.engine--good .engine__n { color: var(--good); }

/* the always-visible path summary: what you opened -> where it lands.
   Rendered on every report, including the ones where the last hop never
   loaded (there the second row is labelled "furthest point reached"). */
.rpath {
  display: block;
  margin: 2px 0 12px;
  padding: 12px 12px 10px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.rpath__row { display: block; }
.rpath__k {
  display: block;
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 3px;
}
.rpath__v {
  display: block; font-size: 12.5px; color: var(--ink);
  overflow-wrap: anywhere; word-break: break-word; line-height: 1.4;
}
.rpath__row--dest .rpath__v { font-weight: 600; }
.rpath__arrow {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 9px 0 8px;
  font-size: 12px; font-weight: 600; color: var(--brand-dark);
}
.rpath__arrow .icon { width: 16px; height: 16px; color: var(--brand); }

/* redirect chain */
.hops { position: relative; padding: 4px 0 0 0; }
.hop { display: flex; gap: 12px; padding: 0 0 14px; position: relative; }
.hop:last-child { padding-bottom: 2px; }
.hop::before {
  content: ""; position: absolute; left: 11px; top: 24px; bottom: 0;
  width: 2px; background: var(--line); border-radius: 2px;
}
.hop:last-child::before { display: none; }
.hop__dot {
  width: 24px; height: 24px; flex: 0 0 auto; border-radius: 50%;
  background: var(--brand-soft); color: var(--brand-dark);
  border: 1px solid #cfe0ff;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 11px; font-weight: 700; z-index: 1;
}
.hop--final .hop__dot { background: var(--good-soft); color: var(--good); border-color: #bfe8d7; }
.hop__body { flex: 1 1 auto; min-width: 0; }
.hop__url {
  font-family: var(--mono); font-size: 12px; color: var(--ink-2);
  overflow-wrap: anywhere; word-break: break-word;
}
.hop__meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 5px; }

.status {
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  padding: 3px 8px; border-radius: var(--r-pill); border: 1px solid transparent;
}
.status--2xx { background: var(--good-soft); color: var(--good); border-color: #bfe8d7; }
.status--3xx { background: var(--brand-soft); color: var(--brand-dark); border-color: #cfe0ff; }
.status--4xx { background: var(--warn-soft); color: var(--warn); border-color: #f3ddb6; }
.status--5xx { background: var(--bad-soft); color: var(--bad); border-color: #f6c9c9; }
.status--na  { background: var(--surface-2); color: var(--muted); border-color: var(--line); }

/* panels (errors / notices) */
.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 24px 18px; text-align: center;
  box-shadow: var(--sh-2);
  max-width: 560px;
}
.panel--error { border-color: #f6c9c9; background: linear-gradient(180deg, var(--bad-soft), var(--surface) 55%); }
.panel--warn  { border-color: #f3ddb6; background: var(--warn-soft); text-align: left; padding: 14px 16px; font-size: 14px; }
.panel__icon {
  width: 54px; height: 54px; margin: 0 auto 12px; border-radius: 50%;
  background: var(--bad); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.panel__icon .icon { width: 28px; height: 28px; }
.panel__title { font-size: 20px; font-weight: 700; }
.panel__text { font-size: 14px; color: var(--ink-2); margin-top: 8px; }
.panel__url, .panel__code {
  margin-top: 10px; font-size: 11.5px; color: var(--muted);
  overflow-wrap: anywhere; word-break: break-word;
}
.panel__code { color: var(--muted-2); letter-spacing: .06em; }

.reporthead { text-align: center; padding: 2px 0 12px; }
.reporthead__kicker {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}

.openrow { margin-top: 18px; }
.openrow .btn { width: 100%; }
.openrow__note { font-size: 12px; color: var(--muted); text-align: center; margin-top: 9px; }
.openrow__plain {
  font-family: var(--mono); font-size: 12px; color: var(--ink-2);
  background: var(--surface-2); border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm); padding: 11px 12px; margin-top: 8px;
  overflow-wrap: anywhere; word-break: break-word;
}

/* ============================ CONTENT / SEO ============================= */
.content { padding: 14px 0 30px; }
/* the nav anchors land here — clear the sticky bar */
#about, #faq { scroll-margin-top: calc(var(--nav-h) + 14px); }
.content__h {
  font-size: 21px; font-weight: 700; letter-spacing: -.022em;
  margin: 30px 0 12px; color: var(--ink);
  display: flex; align-items: center; gap: 10px;
}
/* a short brand rule before each section heading */
.content__h::before {
  content: ""; flex: 0 0 auto; width: 4px; height: 19px; border-radius: 3px;
  background: linear-gradient(180deg, #5ba3ff, var(--brand));
}
.content__h:first-child { margin-top: 8px; }
.content__p { font-size: 14.5px; color: var(--ink-2); margin-bottom: 14px; }

.steps { display: grid; gap: 10px; }
.steps__i {
  display: flex; gap: 13px; align-items: flex-start;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 14px 15px; box-shadow: var(--sh-1);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease),
              border-color .16s var(--ease);
}
.steps__i:hover {
  transform: translateY(-1px); box-shadow: var(--sh-2); border-color: var(--line-strong);
}
.steps__i .steps__n {
  width: 27px; height: 27px; flex: 0 0 auto; border-radius: 50%;
  display: inline-flex !important; align-items: center; justify-content: center;
  background: var(--brand-soft); color: var(--brand-dark);
  border: 1px solid #cfe0ff;
  font-family: var(--mono); font-size: 12px; font-weight: 700;
}
.steps__i > div { min-width: 0; }
.steps__i strong { display: block; font-size: 14.5px; font-weight: 600; color: var(--ink); }
.steps__i > div span {
  display: block; font-size: 13.5px; color: var(--muted); margin-top: 3px;
  overflow-wrap: anywhere;
}

.facts { display: grid; gap: 10px; }
.facts__i {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-sm); padding: 12px 14px;
  box-shadow: var(--sh-1);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease);
}
.facts__i:hover { transform: translateY(-1px); box-shadow: var(--sh-2); }
.facts__i strong { display: block; font-size: 14px; font-weight: 600; color: var(--ink); }
.facts__i span {
  display: block; font-size: 13.5px; color: var(--muted); margin-top: 2px;
  overflow-wrap: anywhere;
}
.facts__i em { font-style: normal; font-family: var(--mono); font-size: 12.5px; }

/* ------------------------------ FAQ accordion --------------------------
   Native <details>, so it still opens with JS off. The chevron sits in its
   own round chip and rotates; the answer fades in under it. */
.faq { display: grid; gap: 10px; }
.faq__i {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--sh-1); overflow: hidden;
}
.faq__q {
  list-style: none; cursor: pointer;
  padding: 15px 52px 15px 15px; position: relative;
  font-size: 14.5px; font-weight: 600; color: var(--ink); line-height: 1.5;
}
.faq__q::-webkit-details-marker { display: none; }
/* the chip */
.faq__q::before {
  content: ""; position: absolute; right: 13px; top: 50%;
  width: 26px; height: 26px; margin-top: -13px; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--line);
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
/* the chevron inside it */
.faq__q::after {
  content: ""; position: absolute; right: 22px; top: 50%;
  width: 8px; height: 8px; margin-top: -6px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg);
  transition: transform .22s var(--ease), border-color .18s var(--ease);
}
.faq__i[open] .faq__q::before { background: var(--brand-soft); border-color: #cfe0ff; }
.faq__i[open] .faq__q::after {
  transform: rotate(-135deg); margin-top: -2px;
  border-right-color: var(--brand); border-bottom-color: var(--brand);
}
.faq__q:focus-visible { outline: 3px solid var(--ring-col); outline-offset: -3px; }
.faq__a {
  padding: 0 15px 16px; font-size: 13.5px; line-height: 1.7;
  color: var(--ink-2); overflow-wrap: anywhere;
}
.faq__i[open] .faq__a { animation: fadein .26s var(--ease) both; }

.footer {
  padding: 26px 0 38px; text-align: center;
  border-top: 1px solid var(--line); margin-top: 10px;
}
.footer .small { max-width: 560px; margin: 0 auto; line-height: 1.7; }
.footer__copy { margin-top: 10px; color: var(--muted-2); }

/* ========================= INTERACTION STATES ===========================
   The tap highlight is off globally (see the top of this file), so every
   surface a finger can hit states itself: a soft press on :active and a
   brand-coloured ring on :focus-visible. Never the browser's blue box.
   ======================================================================== */
.btn, .langtog__b, .faq__q, summary, button, [role="button"] {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
.btn { -webkit-appearance: none; appearance: none; user-select: none; }
.btn:active { transform: translateY(1px) scale(.995); }
.btn--ghost:active { background: var(--bg-soft); }
.btn--primary:active { box-shadow: 0 6px 14px -10px rgba(26,110,245,.9); }
.btn--open:active { box-shadow: 0 6px 14px -10px rgba(18,146,95,.9); }
.btn--danger-open:active { background: var(--bad-soft); }
.btn:focus-visible,
.btn--open:focus-visible,
.btn--danger-open:focus-visible {
  outline: 3px solid rgba(26,110,245,.45); outline-offset: 2px;
}

/* input: the ring lives on the row, and the field itself never draws its own */
.scanbox__input:focus,
.scanbox__input:focus-visible { outline: none; box-shadow: none; }
.scanbox__row:active { border-color: var(--line-strong); }
.scanbox__row:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(26,110,245,.14);
}

/* cards + list surfaces: a gentle press, no blue flash */
.card, .stage, .checklist li, .trustrow__item, .steps__i, .facts__i, .signal {
  -webkit-tap-highlight-color: transparent;
}
.card:focus-visible, .stage:focus-visible {
  outline: 3px solid rgba(26,110,245,.35); outline-offset: 2px;
}

/* FAQ accordion */
.faq__i { transition: border-color .16s ease, box-shadow .16s ease; }
.faq__i[open] { border-color: var(--line-strong); }
.faq__q { -webkit-user-select: none; user-select: none; transition: background .14s ease; }
.faq__q:hover { background: var(--surface-2); }
.faq__q:active { background: var(--bg-soft); }
.faq__q:focus-visible {
  outline: 3px solid rgba(26,110,245,.45); outline-offset: -3px;
  border-radius: var(--r-md);
}

/* anything focusable we did not name explicitly still gets the brand ring */
a:focus-visible, input:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid rgba(26,110,245,.45); outline-offset: 2px; border-radius: 6px;
}

/* ============================ CENTERING GUARDS ==========================
   Everything in the flow is centred on its own axis and nothing is allowed to
   be wider than the viewport at 360px.
   ======================================================================== */
.wrap { margin-left: auto; margin-right: auto; }
main, .section, .content, .footer { width: 100%; max-width: 100%; }
.topbar, .topbar__in { width: 100%; max-width: 100%; }
.hero, .scanhead, .reporthead, .verdict, .panel, .gate { margin-left: auto; margin-right: auto; }
.scanbox, .checklist, .honesty-note, .trustrow { margin-left: auto; margin-right: auto; }
.hero__eyebrow, .card, .signals, .openrow { margin-left: auto; margin-right: auto; }
.reporthead, .openrow, .signals { max-width: 560px; }
/* every 300x250 sits on the centre line of whatever holds it, with its
   250px of height already reserved (see .adslot) — no shift when it fills */
.adslot, .adtop .adslot, .gate .adslot, .openrow .adslot,
#report-body > .adslot, #gate-slot .adslot {
  margin-left: auto; margin-right: auto;
}
/* (the containers themselves keep their own text alignment — only the ad
   boxes are re-centred, so nothing in the report changes alignment) */
.openrow { text-align: center; }
.openrow .btn { max-width: 420px; margin-left: auto; margin-right: auto; }
.btnrow { justify-content: center; }
.stages, .signals, .hops { width: 100%; max-width: 100%; }
.card, .stage { max-width: 100%; }
.hop__url, .kv__v, .scanhead__url, .verdict__url, .openrow__plain,
.panel__url, .panel__code { overflow-wrap: anywhere; word-break: break-word; }
img, svg, iframe, table { max-width: 100%; }

/* ---- 360px and under: the bar keeps brand + language toggle, nothing
   else, and the wide grids drop to one column ---- */
@media (max-width: 420px) {
  .brand__tag { display: none; }          /* "Link Safety" alone is enough */
}
@media (max-width: 380px) {
  .wrap { padding-left: 12px; padding-right: 12px; }
  .hero__title { font-size: 26px; }
  .hero__eyebrow { font-size: 12px; padding: 5px 11px 5px 9px; }
  .btnrow .btn { flex: 1 1 100%; }
  .kv { flex-direction: column; gap: 2px; }
  .kv__k { flex-basis: auto; }
  .trustrow { grid-template-columns: 1fr; }
  .langtog__b { padding: 6px 9px; min-width: 38px; }
  .langtog__b.is-on,
  .langtog__b[aria-pressed="true"] { padding: 5px 8px; }
  .brand { font-size: 15px; }
  .brand__mark { width: 30px; height: 30px; border-radius: 10px; }
  .navbtn { width: 36px; height: 36px; }
  .nav { left: 8px; right: 8px; }
  .topbar__right { gap: 6px; }
}

/* =============================== RESPONSIVE ============================= */
@media (min-width: 560px) {
  .checklist { grid-template-columns: 1fr 1fr; }
  .engines { grid-template-columns: repeat(4, 1fr); }
  .hero__title { font-size: 34px; }
  .kv__k { flex-basis: 34%; }
  .facts { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 760px) {
  .section { padding: 26px 0 34px; }
  .hero { padding-top: 22px; }
  .hero__shield { width: 132px; height: 132px; }
  .hero__title { font-size: 38px; }
  .hero__sub { font-size: 16px; }
  .content__h { font-size: 23px; }
  .content__h::before { height: 21px; }
  .topbar { padding: 10px 0; }
  .nav { gap: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; }
}

/* ================================ DARK ================================== */
@media (prefers-color-scheme: dark) {
  :root {
    --bg:          #0c111a;
    --bg-soft:     #151d29;
    --surface:     #121a26;
    --surface-2:   #172130;
    --ink:         #eef3fa;
    --ink-2:       #c3d0e0;
    --muted:       #8ea0b6;
    --muted-2:     #66798f;
    --line:        #223044;
    --line-strong: #33455e;

    --brand:       #4f9bff;
    --brand-dark:  #a7c9ff;
    --brand-soft:  #15243a;

    --good:        #35c58c;  --good-soft: #10281f;
    --warn:        #e0a23a;  --warn-soft: #2a2113;
    --bad:         #f3706e;  --bad-soft:  #2b1517;
    --demo:        #92a3b8;  --demo-soft: #1a2331;

    --sh-1: 0 1px 2px rgba(0,0,0,.4);
    --sh-2: 0 2px 8px rgba(0,0,0,.45), 0 18px 40px -22px rgba(0,0,0,.9);
    --sh-3: 0 3px 12px rgba(0,0,0,.5), 0 30px 60px -28px rgba(0,0,0,.95);
    --sh-brand: 0 10px 24px -14px rgba(79,155,255,.75);
    --ring: 0 0 0 3px rgba(79,155,255,.42);
    --ring-col: rgba(79,155,255,.5);
  }
  body {
    background-image:
      radial-gradient(52rem 26rem at 50% -12rem, rgba(79,155,255,.14), transparent 70%),
      radial-gradient(36rem 20rem at 88% -6rem, rgba(53,197,140,.08), transparent 72%);
  }
  /* header + nav */
  .topbar { border-bottom-color: var(--line); }
  .brand__mark { background: linear-gradient(160deg, #5ba3ff, #2b7bf0); }
  .brand__mark::after { border-color: rgba(255,255,255,.18); }
  /* the nav panel, the links and the menu button are already built entirely
     out of tokens, so they follow the dark palette on their own — only the
     one hard-coded light border needs restating */
  .topbar.is-open .navbtn { border-color: #21375a; }
  .langtog { box-shadow: none; }
  .hero__eyebrow { border-color: var(--line); }
  .hero__eyebrow .icon { color: var(--good); }
  .hero__shield { filter: drop-shadow(0 18px 30px rgba(79,155,255,.20)); }
  .content__h::before { background: linear-gradient(180deg, #6fb0ff, var(--brand)); }
  .faq__i[open] .faq__q::before { border-color: #21375a; }
  .faq__i[open] .faq__q::after { border-right-color: var(--brand); border-bottom-color: var(--brand); }
  .scanbox__row:hover { border-color: #3c5878; }
  .btn--ghost:hover { border-color: #3c5878; }
  /* (the verdict rail keeps its tone gradients; the neutral default already
     follows --line-strong, which is redefined above) */
  .honesty-note { border-color: #21375a; }
  .hop__dot { border-color: #21375a; }
  .rpath { border-color: var(--line); }
  .housead { border-color: var(--line); }
  .housead__tag { border-color: var(--line); }
  .housead__icon { border-color: var(--line); }
  .housead__cta { color: #06101f; }
  .signal--good { border-color: #1d4e3b; }
  .signal--warn { border-color: #4a3a17; }
  .signal--bad  { border-color: #5a2427; }
  .signal--good .signal__ic,
  .signal--warn .signal__ic,
  .signal--bad  .signal__ic { color: #0c111a; }
  .langtog__b.is-on,
  .langtog__b[aria-pressed="true"] { background: var(--bg-soft); color: var(--brand-dark); }
  .score__track { border-color: var(--line); }
  .pill--good { border-color: #1d4e3b; }
  .pill--warn { border-color: #4a3a17; }
  .pill--bad  { border-color: #5a2427; }
  .pill--info { border-color: #21375a; }
  .status--2xx { border-color: #1d4e3b; }
  .status--3xx { border-color: #21375a; }
  .status--4xx { border-color: #4a3a17; }
  .status--5xx { border-color: #5a2427; }
  .verdict--safe    { border-color: #1d4e3b; }
  .verdict--caution { border-color: #4a3a17; }
  .verdict--danger  { border-color: #5a2427; }
  .verdict--safe    .verdict__title { color: #63dcab; }
  .verdict--caution .verdict__title { color: #f0c476; }
  .verdict--danger  .verdict__title { color: #ff9b99; }
  .verdict--demo    .verdict__title,
  .verdict--unknown .verdict__title { color: #c3d0e0; }
  .verdict--cnv     { border-color: #47412c; }
  .verdict--cnv     .verdict__title { color: #e9dcb8; }
  .panel--cnv       { border-color: #2b384a; }
  .panel--cnv .panel__icon { background: var(--demo); color: #fff; }
  .panel--error { border-color: #5a2427; }
  .verdict--safe .verdict__icon,
  .verdict--caution .verdict__icon,
  .verdict--danger .verdict__icon { color: #0c111a; }
  /* the could-not-verify icon keeps its own slate/white pairing */
  .verdict--cnv .verdict__icon { background: var(--demo); color: #fff; }
  .panel__icon { color: #0c111a; }
  .btn--primary { color: #06101f; }
  .btn--open { color: #06101f; }
}

/* optAd360 switch (2026-09-17): hide leftover GAM ad slots now that ADS_LIVE is off */
.adslot--ph{display:none!important}
.adslot:empty{display:none!important}
