/* ===========================================================================
   科学上网工具 · /fanqiang/
   ---------------------------------------------------------------------------
   THE PAGE CONSUMES THE SITE'S TOKENS AND CARRIES NO PALETTE OF ITS OWN — the
   same rule after-the-wall.css keeps, and the reason both pages follow the
   dark-mode switch without knowing it exists. --bg / --surface / --ink /
   --ink-2 / --rule / --rule-strong / --accent / --art-gold are defined by the
   theme; theme-dark.css redefines them under html[data-mh-theme="dark"] and
   this file inherits the result.

   THE ONE EXCEPTION IS THE WALL, and it is deliberate rather than an
   oversight. The hero is a night scene: a wall, ladders against it, and the
   names of what is on the other side. It is dark in BOTH modes because a
   night sky that turns cream in light mode is not a night sky — the same
   reasoning the 文库 shelf uses for its own fixed greens. Its colours are
   therefore literal, and they are the only literal colours in the file.

   NOTHING FIXED-POSITION LIVES HERE. The floating 留声机 dock and the 回到顶部
   arrow are site furniture (chrome.css) and they sit over this page like any
   other; this stylesheet must not place anything in their corner or compete
   for their z-index band (they hold 189/190).
   =========================================================================== */

.fq{ margin:0 }

/* The page's own column. The site chrome keeps its 1080px shell; the tools
   body is 1100px because the upstream package's directory geometry was
   measured at that width. Two different widths on one page is intentional,
   and stated here so nobody "fixes" it later. */
.fq-in{
  width:1100px;
  max-width:calc(100vw - 32px);
  margin-inline:auto;
}
.fq-sr{ position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap }

/* ======================= 墙与梯子 ======================= */
.fq-scene{
  position:relative;
  overflow:hidden;
  color:#eef2f0;
  background:linear-gradient(180deg,#0b1f28 0%,#122a35 46%,#16323d 100%);
}
.fq-scene .fq-in{ position:relative;z-index:3;padding:30px 0 0 }
.fq-h1{
  font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:30px;line-height:1.35;margin:0 0 6px;font-weight:700;color:#eef2f0;
}
.fq-lede{ color:#9fc0cd;font-size:14px;margin:0;max-width:60ch;line-height:1.75 }

/* 字符雨 — what is on the other side, falling past.
   ---------------------------------------------------------------------------
   Behind everything (z-index 0): the wall is 1, the ladders 2, the text 3, so
   the rain can never come between a reader and a word.

   TRANSFORM-ONLY, AND THAT IS THE WHOLE PERFORMANCE STORY. Each column is one
   text node moved by a composited keyframe — no canvas, no rAF, no layout, no
   paint per frame. The string is rendered twice and the animation travels
   exactly -50%, so the loop closes on itself instead of snapping back.

   The mask is what makes it read as falling rather than as scrolling text: the
   column fades in at the top and out at the bottom, so characters appear to
   emerge and dissolve rather than slide in from an edge. */
.fq-rain{
  position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  display:flex;justify-content:space-between;padding:0 6px;
}
.fq-rain-col{
  font-family:var(--mh-mono,ui-monospace,"SFMono-Regular",monospace);
  font-size:12px;line-height:1.32;letter-spacing:.06em;
  white-space:pre;
  /* the same phosphor the 探路 dots use for a reachable site */
  color:#5fd0a0;
  opacity:.30;
  will-change:transform;
  animation-name:fq-fall;
  animation-timing-function:linear;
  animation-iteration-count:infinite;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 18%,#000 62%,transparent 97%);
          mask-image:linear-gradient(180deg,transparent 0,#000 18%,#000 62%,transparent 97%);
}
/* not one flat sheet: a third of the columns sit further back */
.fq-rain-col.is-dim{ opacity:.15;font-size:11px;color:#7fa8b8 }
@keyframes fq-fall{
  from{ transform:translateY(-50%) }
  to  { transform:translateY(0) }
}
/* A SCRIM OVER THE READING COLUMN, and the reason is legibility rather than
   taste: the headline and the lede sit on the left, and characters falling
   behind a sentence make it work harder to read than a sentence should. The
   gradient calms the left half and lets the right stay lively — the same
   instinct that kept the old static domain names off the headline's column.
   Above the rain (0), below the wall and the text, so it darkens only the
   rain. */
.fq-scene::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(90deg,
    rgba(11,31,40,.92) 0%,
    rgba(11,31,40,.78) 34%,
    rgba(11,31,40,.28) 58%,
    rgba(11,31,40,0) 78%);
}

.fq-wallwrap{ position:relative;z-index:2;margin-top:20px;height:212px }
.fq-wall{
  position:absolute;left:0;right:0;bottom:0;height:104px;z-index:1;
  background:
    repeating-linear-gradient(0deg,#262b2f 0 2px,transparent 2px 26px),
    repeating-linear-gradient(90deg,#262b2f 0 2px,transparent 2px 62px),
    linear-gradient(180deg,#3a3f43 0%,#31363a 100%);
  border-top:5px solid #565d62;
  box-shadow:0 -1px 0 rgba(255,255,255,.08) inset, 0 14px 30px -14px #000;
}
/* alternate courses, so it reads as brickwork rather than graph paper */
.fq-wall::before,.fq-wall::after{
  content:"";position:absolute;left:0;right:0;height:26px;
  background:repeating-linear-gradient(90deg,#262b2f 0 2px,transparent 2px 62px);
  transform:translateX(31px);
}
.fq-wall::after{ top:26px }
.fq-wall::before{ top:78px }

/* IN FRONT OF THE WALL. Both are absolute in the same box, so without this
   the wall — later in the DOM — paints over every ladder. */
.fq-ladders{
  position:absolute;left:0;right:0;bottom:0;height:212px;z-index:2;
  display:flex;align-items:flex-end;gap:34px;padding-left:8px;
}
/* THE ONE TO CLIMB IS THE ONE THAT REACHES: unselected ladders stop below the
   capstone, the chosen one goes over it. That contrast is the whole reason
   the wall is drawn. Fixed height on the button, ladder pinned to the ground,
   caption in the sky — a caption in flow lifts every ladder until all four
   clear the wall and the picture stops saying anything. */
.fq-lad{
  position:relative;width:74px;height:212px;flex:none;
  background:none;border:0;padding:0;cursor:pointer;font:inherit;color:inherit;
}
.fq-lad-fig{
  display:block;position:absolute;left:0;right:0;bottom:0;height:78px;
  transform-origin:bottom center;transform:rotate(-4deg);
  transition:height .46s cubic-bezier(.2,.8,.25,1), transform .46s;
}
.fq-lad-fig::before,.fq-lad-fig::after{
  content:"";position:absolute;bottom:0;top:0;width:5px;border-radius:2px;
  background:linear-gradient(180deg,#c9a86a,#8d7440);
}
.fq-lad-fig::before{ left:12px }
.fq-lad-fig::after{ right:12px }
.fq-rung{
  position:absolute;left:12px;right:12px;height:4px;border-radius:1px;
  background:linear-gradient(90deg,#8d7440,#c9a86a,#8d7440);
}
.fq-lad-cap{
  position:absolute;left:-8px;right:-8px;top:0;text-align:center;
  font-size:11.5px;color:#a9c3ce;letter-spacing:.02em;line-height:1.3;
}
.fq-lad-n{
  display:block;font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:13.5px;color:#dbe6ea;font-weight:700;
}
.fq-lad:hover .fq-lad-fig{ transform:rotate(-4deg) translateY(-4px) }
.fq-lad[aria-pressed="true"] .fq-lad-fig{ height:176px;transform:rotate(-2deg) }
.fq-lad[aria-pressed="true"] .fq-lad-fig::before,
.fq-lad[aria-pressed="true"] .fq-lad-fig::after{
  background:linear-gradient(180deg,#f0d9a6,#c9a86a);
  box-shadow:0 0 12px rgba(240,217,166,.5);
}
.fq-lad[aria-pressed="true"] .fq-lad-n{ color:#f7e6bf }
.fq-lad[aria-pressed="true"] .fq-lad-cap{ color:#cbb583 }
.fq-lad:focus-visible{ outline:2px solid #f0d9a6;outline-offset:4px }

/* 放一架梯子下去 — the far side of the wall.
   Pinned to the right of the wall box and lifted above the capstone, because
   that is literally where a volunteer stands: outside, reaching back over.
   The ladders on the near side are ways out; this is the one thing a reader
   who is already out can do for someone who is not. */
.fq-help{
  position:absolute;right:0;bottom:0;z-index:3;width:290px;
  padding:14px 16px 13px;
  background:rgba(9,26,33,.9);
  border:1px solid rgba(240,217,166,.28);
  border-bottom:0;
}
.fq-help-t{
  margin:0 0 6px;font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:15px;font-weight:700;color:#f7e6bf;line-height:1.45;
}
.fq-help-b{ margin:0 0 11px;font-size:12.5px;color:#9fc0cd;line-height:1.65 }
.fq-help-go{
  appearance:none;font:inherit;font-size:13.5px;font-weight:600;cursor:pointer;
  padding:6px 18px;color:#20140a;background:#f0d9a6;border:1px solid #f0d9a6;
}
.fq-help-go:hover{ background:#fff }
.fq-help-go[disabled]{ opacity:.55;cursor:default }
.fq-help-go:focus-visible{ outline:2px solid #f0d9a6;outline-offset:3px }
.fq-help-n{ margin:9px 0 0;font-size:11px;color:#7f9daa;line-height:1.5 }
/* THE GLOBE'S ROOM. The widget left the plaque when the layout became
   `banner` — that is the only one of the three that draws the rotating globe,
   and it wants roughly 1068x626, which a 290px plaque would crush. So it opens
   full width beneath the wall instead, where the globe is worth looking at.
   The widget draws all its own furniture; this box only gives it space, a rule
   to sit under, and a floor so it never touches the section edge. */
.fq-help-box{
  margin:18px 0 0;padding:16px 0 4px;
  border-top:1px solid rgba(240,217,166,.22);
  min-height:120px;
}
.fq-help-box[hidden]{ display:none }
/* Their canvas is a fixed 400x400; on a narrow screen let it shrink rather
   than push the page sideways. */
.fq-help-box canvas{ max-width:100%;height:auto }

.fq-crossed{
  position:relative;z-index:4;background:rgba(9,26,33,.86);
  border:1px solid rgba(240,217,166,.32);padding:16px 20px;margin:0 0 24px;
}
.fq-crossed-top{ display:flex;align-items:baseline;gap:12px;flex-wrap:wrap }
.fq-crossed-n{
  font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:22px;font-weight:700;color:#f7e6bf;
}
.fq-crossed-w{ font-size:13.5px;color:#9fc0cd }
.fq-crossed-row{ display:flex;gap:10px;flex-wrap:wrap;margin-top:13px;align-items:center }
.fq-go{
  display:inline-block;background:#f0d9a6;color:#20140a;text-decoration:none;
  font-weight:700;font-size:14.5px;padding:9px 20px;border:1px solid #f0d9a6;
}
.fq-go:hover{ background:#fff;color:#20140a }
.fq-go2{
  display:inline-block;text-decoration:none;color:#cfe3ea;font-size:13.5px;
  padding:9px 14px;border:1px solid rgba(255,255,255,.26);
}
.fq-go2:hover{ border-color:#cfe3ea }
.fq-crossed-note{ margin:11px 0 0;font-size:12.5px;color:#8fb0be;line-height:1.6 }

.fq-devs{ display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin:16px 0 0 }
.fq-devs-l{ font-size:12.5px;color:#8fb0be;margin-right:6px }
.fq-dev{
  appearance:none;border:1px solid rgba(255,255,255,.26);background:transparent;
  color:#dfe8e3;font:inherit;font-size:13.5px;padding:6px 15px;cursor:pointer;
}
.fq-dev:hover{ border-color:#9fc0cd }
.fq-dev[aria-pressed="true"]{ background:#f0d9a6;color:#20140a;border-color:#f0d9a6;font-weight:600 }
.fq-dev:focus-visible,.fq-probe-go:focus-visible,.fq-chip:focus-visible{
  outline:2px solid var(--art-gold,#c9a86a);outline-offset:2px;
}

/* ======================= 探路 ======================= */
.fq-probe{ background:#14312a;color:#e9f0ec;padding:26px 0 }
.fq-probe-h{ display:flex;align-items:baseline;gap:14px;flex-wrap:wrap }
.fq-probe h2{
  font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:21px;margin:0;font-weight:700;color:#e9f0ec;
}
.fq-why{ font-size:13px;color:#9dbfae;flex:1 1 320px;line-height:1.65;margin:0 }
.fq-why strong{ color:#d9ece3 }
.fq-probe-go{
  appearance:none;background:transparent;border:1px solid #7fb69c;color:#d9ece3;
  font:inherit;font-size:14px;font-weight:600;padding:8px 20px;cursor:pointer;white-space:nowrap;
}
.fq-probe-go:hover{ background:#7fb69c;color:#0f2b20 }
.fq-probe-go[disabled]{ opacity:.5;cursor:default }
.fq-dots{ display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:8px 20px;margin-top:16px }
.fq-dot{ display:flex;align-items:center;gap:9px;font-size:13.5px;font-family:var(--mh-mono,ui-monospace,monospace) }
.fq-dot i{ width:9px;height:9px;border-radius:50%;background:#4b6a5f;flex:none;transition:background .3s }
.fq-dot.is-ok i{ background:#5fd0a0;box-shadow:0 0 9px rgba(95,208,160,.6) }
.fq-dot.is-no i{ background:#e0705f;box-shadow:0 0 9px rgba(224,112,95,.55) }
.fq-dot.is-run i{ background:#e9d18a;animation:fq-pulse 1s ease-in-out infinite }
@keyframes fq-pulse{ 0%,100%{opacity:.35} 50%{opacity:1} }
.fq-dot b{ font-weight:400;color:#bcd3dc }
.fq-dot em{ font-style:normal;margin-left:auto;font-size:11.5px;color:#7f9d92 }
.fq-verdict{ margin:14px 0 0;font-size:14px;color:#d9ece3;line-height:1.7 }
.fq-verdict b{ color:#f0d9a6 }

/* ======================= paper sections ======================= */
.fq-sec{ padding:36px 0;border-bottom:1px solid var(--rule,#e3e1da);background:var(--bg,#fafaf7) }
.fq-sec-h{ display:grid;grid-template-columns:minmax(0,1fr) 380px;gap:34px;align-items:end;margin-bottom:20px }
.fq-sec-h h2{
  font-family:var(--mh-serif,"Noto Serif SC",serif);
  font-size:24px;margin:0;font-weight:700;color:var(--ink,#1a1a18);
}
.fq-sec-h p{ margin:0;font-size:13.5px;color:var(--ink-2,#5c5c56);line-height:1.75 }

.fq-steps{ border-top:1px solid var(--rule-strong,#c9c6bc) }
.fq-step{ display:grid;grid-template-columns:30px minmax(0,1fr);gap:0 16px;padding:14px 0;border-bottom:1px solid var(--rule,#e3e1da) }
.fq-step-n{ font-family:var(--mh-mono,ui-monospace,monospace);font-size:12px;color:var(--flag,#8a4b1f);padding-top:3px }
.fq-step h3{ margin:0 0 4px;font-size:15.5px;font-weight:700;color:var(--ink,#1a1a18) }
.fq-step p{ margin:0;font-size:14px;color:var(--ink-2,#5c5c56);line-height:1.72 }
.fq-lk{ margin-top:6px;font-size:13.5px }
.fq-lk a{ color:var(--accent,#1e6b4e);text-decoration:none;border-bottom:1px solid var(--rule-strong,#c9c6bc);margin-right:14px }
.fq-lk a:hover{ border-bottom-color:var(--accent,#1e6b4e) }

.fq-bar{ display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:14px }
.fq-bar input{
  flex:1 1 240px;min-width:0;font:inherit;font-size:14px;padding:8px 12px;
  border:1px solid var(--rule-strong,#c9c6bc);background:var(--surface,#fff);color:var(--ink,#1a1a18);
}
.fq-chip{
  appearance:none;font:inherit;font-size:13px;padding:6px 13px;cursor:pointer;
  background:var(--surface,#fff);border:1px solid var(--rule-strong,#c9c6bc);color:var(--ink-2,#5c5c56);
}
.fq-chip[aria-pressed="true"]{ background:var(--accent,#1e6b4e);border-color:var(--accent,#1e6b4e);color:#fff }
.fq-count{ font-family:var(--mh-mono,ui-monospace,monospace);font-size:12.5px;color:var(--ink-2,#5c5c56);margin-left:auto }

table.fq-tools{ width:100%;border-collapse:collapse;font-size:14px;background:var(--surface,#fff) }
table.fq-tools th{
  text-align:left;font-size:12px;letter-spacing:.06em;color:var(--ink-2,#5c5c56);
  font-weight:600;padding:9px 12px;border-bottom:1.5px solid var(--rule-strong,#c9c6bc);white-space:nowrap;
}
table.fq-tools td{ padding:12px;border-bottom:1px solid var(--rule,#e3e1da);vertical-align:top }
table.fq-tools tr:hover td{ background:var(--bg,#fafaf7) }
.fq-t-n{ font-family:var(--mh-serif,"Noto Serif SC",serif);font-size:16px;font-weight:700;white-space:nowrap;color:var(--ink,#1a1a18) }
.fq-t-en{
  font-family:var(--mh-mono,ui-monospace,monospace);font-size:10.5px;color:var(--ink-2,#5c5c56);
  letter-spacing:.05em;display:block;margin-top:2px;opacity:.75;
}
.fq-t-for{ font-size:13.5px;color:var(--ink-2,#5c5c56);line-height:1.6 }
.fq-t-lim{ font-size:12.5px;color:var(--flag,#8a4b1f);line-height:1.55;margin-top:5px }
.fq-t-meta{ font-family:var(--mh-mono,ui-monospace,monospace);font-size:11.5px;color:var(--ink-2,#5c5c56);line-height:1.85 }
.fq-t-get a{
  display:inline-block;font-size:13px;text-decoration:none;color:var(--accent,#1e6b4e);
  border:1px solid var(--rule-strong,#c9c6bc);padding:5px 11px;white-space:nowrap;
}
.fq-t-get a:hover{ border-color:var(--accent,#1e6b4e) }
.fq-empty{ padding:24px 12px;color:var(--ink-2,#5c5c56);font-size:14px;background:var(--surface,#fff) }

.fq-bounds{ display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border:1px solid var(--rule-strong,#c9c6bc);background:var(--surface,#fff) }
.fq-bound{ padding:18px 20px }
.fq-bound + .fq-bound{ border-left:1px solid var(--rule,#e3e1da) }
.fq-bound h3{ margin:0 0 7px;font-family:var(--mh-serif,"Noto Serif SC",serif);font-size:16.5px;font-weight:700;color:var(--ink,#1a1a18) }
.fq-bound p{ margin:0;font-size:13.5px;color:var(--ink-2,#5c5c56);line-height:1.72 }
.fq-bound b{ color:var(--flag,#8a4b1f);font-weight:600 }

.fq-gloss{ display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px }
.fq-gl h3{ margin:0 0 4px;font-size:14.5px;font-weight:700;color:var(--ink,#1a1a18) }
.fq-gl-k{ font-family:var(--mh-mono,ui-monospace,monospace);font-size:10.5px;color:var(--ink-2,#5c5c56);letter-spacing:.06em;display:block;opacity:.75 }
.fq-gl p{ margin:5px 0 0;font-size:13px;color:var(--ink-2,#5c5c56);line-height:1.68 }

.fq-disc{ padding:20px 0;font-size:12.5px;color:var(--ink-2,#5c5c56);line-height:1.8 }
.fq-rev{ font-family:var(--mh-mono,ui-monospace,monospace);font-size:11.5px }

@media (prefers-reduced-motion:reduce){
  .fq-lad-fig{ transition:none }
  .fq-dot.is-run i{ animation:none }
  /* the rain stops where it stands — still a texture, no longer motion */
  .fq-rain-col{ animation:none }
}

/* ---- phones. The wall stays; it is the page's one picture and it survives
   the tier intact, only shorter. The table becomes stacked rows because a
   four-column comparison at 390px is unreadable however it is squeezed. ---- */
@media (max-width:900px){
  .fq-sec-h{ grid-template-columns:minmax(0,1fr);gap:8px }
  .fq-bounds,.fq-gloss{ grid-template-columns:minmax(0,1fr) }
  .fq-bound + .fq-bound{ border-left:0;border-top:1px solid var(--rule,#e3e1da) }
  .fq-h1{ font-size:24px }
  /* No far side on a phone: the sign leaves the wall and becomes an ordinary
     block under it, or it would cover the ladders it is standing beside. */
  .fq-help{ position:static;width:auto;border-bottom:1px solid rgba(240,217,166,.28);margin-top:14px }
  .fq-wallwrap{ height:170px }
  .fq-wall{ height:84px }
  .fq-lad{ height:170px }
  .fq-lad-fig{ height:62px }
  .fq-lad[aria-pressed="true"] .fq-lad-fig{ height:142px }
  .fq-ladders{ height:170px;overflow-x:auto;gap:22px;padding-bottom:2px }
  /* fewer, thinner columns on a phone: 26 at 12px is a wall of noise at
     390px, and every column is one more animated layer to composite */
  .fq-rain{ padding:0 2px }
  .fq-rain-col{ font-size:10px;letter-spacing:.02em;opacity:.24 }
  .fq-rain-col:nth-child(2n){ display:none }

  table.fq-tools thead{ display:none }
  table.fq-tools,table.fq-tools tbody,table.fq-tools tr,table.fq-tools td{ display:block;width:100% }
  table.fq-tools tr{ border-bottom:1px solid var(--rule-strong,#c9c6bc);padding:10px 0 }
  table.fq-tools td{ border:0;padding:2px 12px }
  /* the arrow and the 留声机 dock own the bottom-right corner; keep the last
     row clear of them */
  .fq-empty,table.fq-tools{ margin-bottom:56px }
}
