/* Pars Abr "X-mono".
 *
 * No brand hue anywhere. Hierarchy comes from luminance, weight and elevation,
 * and dark and light read as the same brand. The only colour in the interface
 * carries meaning: a status LED on a true measured state, never decoration.
 * The logo gradient stays inside the logo.
 */

@font-face {
  font-family: 'Vazirmatn';
  src: url('/assets/fonts/vazirmatn.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}

:root {
  color-scheme: light dark;

  --paper: #eef1f4;
  --card: #ffffff;
  --sunken: #e7ebef;
  --text-1: #0f1113;
  --text-2: #49555e;
  --text-3: #6b7780;
  --hairline: rgba(0, 0, 0, .14);
  --catch: inset 0 1px 0 rgba(255, 255, 255, .65);

  --led-ok: #15803d;
  --led-warn: #b45309;
  --led-down: #b91c1c;
  --led-idle: #7b868e;

  --ink: linear-gradient(135deg, #1b1b1f, #0c0c0e 55%, #000);
  --on-ink-1: #ffffff;
  --on-ink-2: #a8aeb5;

  --btn-primary: linear-gradient(180deg, #30343a, #0f1113);
  --btn-primary-text: #ffffff;
  --btn-glow: 0 6px 18px rgba(15, 17, 19, .28);

  --r-card: 1rem;
  --r-inner: .8rem;
  --r-input: .75rem;
  --r-pill: 999px;

  --ease: cubic-bezier(.2, .7, .3, 1);
  --t-fast: 120ms;
  --t-slow: 180ms;

  --grid: rgba(0, 0, 0, .055);
  --glow: rgba(0, 0, 0, .06);
}

:root[data-theme="dark"],
:root:not([data-theme="light"]) {
  --paper: #000000;
  --card: #0a0a0b;
  --sunken: #0e0e10;
  --text-1: #ffffff;
  --text-2: #9aa3ab;
  --text-3: #6e777e;
  --hairline: rgba(255, 255, 255, .10);
  --catch: inset 0 1px 0 rgba(255, 255, 255, .04);

  --led-ok: #4ade80;
  --led-warn: #fbbf24;
  --led-down: #f87171;
  --led-idle: #5c656c;

  --on-ink-1: #ffffff;
  --on-ink-2: #a8aeb5;

  --btn-primary: linear-gradient(180deg, #ffffff, #dfe2e5);
  --btn-primary-text: #0b0d0f;
  --btn-glow: 0 6px 20px rgba(255, 255, 255, .14);

  --grid: rgba(255, 255, 255, .045);
  --glow: rgba(255, 255, 255, .05);
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --paper: #eef1f4;
    --card: #ffffff;
    --sunken: #e7ebef;
    --text-1: #0f1113;
    --text-2: #49555e;
    --text-3: #6b7780;
    --hairline: rgba(0, 0, 0, .14);
    --catch: inset 0 1px 0 rgba(255, 255, 255, .65);
    --led-ok: #15803d;
    --led-warn: #b45309;
    --led-down: #b91c1c;
    --led-idle: #7b868e;
    --btn-primary: linear-gradient(180deg, #30343a, #0f1113);
    --btn-primary-text: #ffffff;
    --btn-glow: 0 6px 18px rgba(15, 17, 19, .28);
    --grid: rgba(0, 0, 0, .055);
    --glow: rgba(0, 0, 0, .06);
  }
}

*, *::before, *::after { box-sizing: border-box; }

/* The hidden attribute only works through a user agent rule of display:none,
   which any component rule with a display of its own outranks. The looking
   glass fields set display:flex, so hiding them in script had no visible
   effect and every field showed for every test. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text-1);
  font-family: 'Peyda', 'Vazirmatn', system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* One 56px hairline square grid plus a single monochrome glow. Never a dot grid. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(900px 520px at 50% -10%, var(--glow), transparent 70%),
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 100% 100%, 56px 56px, 56px 56px;
  mask-image: linear-gradient(180deg, #000 0, #000 60vh, transparent 100vh);
}

a { color: inherit; text-decoration: none; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }

/* ---------- frosted capsule header ---------- */

.topbar { position: sticky; top: 0; z-index: 40; padding: 14px 20px; }
.topbar__inner {
  max-width: 1180px;
  margin: 0 auto;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 14px;
  /* Less padding on the logo side: the mark already carries its own clear
     space, and the pill should hug it rather than float it. */
  padding: 0 10px 0 22px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--paper) 96%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--catch);
}

.brand { display: flex; align-items: center; flex: none; }
.brand img { height: 38px; width: auto; display: block; }
.topbar__end { display: flex; align-items: center; gap: 8px; flex: none; }
:root[data-theme="dark"] .brand img,
:root:not([data-theme="light"]) .brand img { filter: brightness(0) invert(1); opacity: .92; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .brand img { filter: none; opacity: 1; }
}
.brand__sep { width: 1px; height: 20px; background: var(--hairline); }
.brand__label { font-size: 13px; font-weight: 700; color: var(--text-2); }

/* Logo pinned to the reading start, navigation centred in what is left, the
   single filled action at the far end. */
.topnav { margin-inline: auto; display: flex; align-items: center; gap: 4px; }
.topnav a {
  font-size: 13px; font-weight: 600; color: var(--text-2);
  padding: 8px 14px; border-radius: var(--r-pill);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.topnav a:hover { color: var(--text-1); background: color-mix(in srgb, var(--text-1) 7%, transparent); }
.topnav a[aria-current="page"] { color: var(--text-1); }

.icon-btn {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--text-1) 5%, transparent);
  box-shadow: var(--catch);
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}
.icon-btn:hover { color: var(--text-1); }

/* ---------- buttons: soft keys ---------- */

.btn {
  font: inherit; font-weight: 700; font-size: 13px;
  border-radius: var(--r-pill);
  padding: 11px 20px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.btn--primary {
  background: var(--btn-primary);
  color: var(--btn-primary-text);
  box-shadow: var(--btn-glow);
}
.btn--primary:active { transform: translateY(1px); box-shadow: none; }
.btn--ghost {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--text-1) 8%, transparent),
    color-mix(in srgb, var(--text-1) 4%, transparent));
  border-color: var(--hairline);
  box-shadow: var(--catch);
  color: var(--text-1);
}
.btn--ghost:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn--sm { padding: 9px 16px; font-size: 12.5px; }

/* ---------- structure ---------- */

.section { padding: 46px 0; }
.eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  color: var(--text-3); margin: 0 0 10px;
}
h1 { font-size: clamp(30px, 4.4vw, 46px); line-height: 1.25; font-weight: 800; margin: 0; letter-spacing: -.01em; }
h2 { font-size: clamp(21px, 2.4vw, 27px); line-height: 1.35; font-weight: 800; margin: 0 0 6px; }
h3 { font-size: 16px; font-weight: 700; margin: 0; }
.sub { color: var(--text-2); margin: 8px 0 0; max-width: 62ch; }

.card {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--catch);
  padding: 20px;
}

.grid-2 { display: grid; grid-template-columns: 1.05fr .95fr; gap: 20px; align-items: start; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }

/* ---------- LED: only ever on a real measured state ---------- */

.led {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  display: inline-block; background: currentColor;
  box-shadow: 0 0 6px currentColor;
}
.led--ok { color: var(--led-ok); animation: breathe 2.4s var(--ease) infinite; }
.led--warn { color: var(--led-warn); animation: breathe 2.4s var(--ease) infinite; }
.led--down { color: var(--led-down); box-shadow: none; }
.led--idle { color: var(--led-idle); box-shadow: none; }

@keyframes breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.t-ok { color: var(--led-ok); }
.t-warn { color: var(--led-warn); }
.t-down { color: var(--led-down); }
.t-idle { color: var(--text-3); }
.t-2 { color: var(--text-2); }
.t-3 { color: var(--text-3); }

/* ---------- stats ---------- */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 2px; }
.stat { padding: 14px 16px; }
.stat__v { font-size: 26px; font-weight: 800; line-height: 1.2; }
.stat__l { font-size: 12px; color: var(--text-3); margin-top: 2px; }

/* ---------- table ---------- */

.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tbl th {
  text-align: start; font-size: 11.5px; font-weight: 700; color: var(--text-3);
  padding: 0 12px 10px; white-space: nowrap;
}
.tbl td { padding: 9px 12px; border-top: 1px solid var(--hairline); vertical-align: middle; }
.tbl tbody tr { transition: background var(--t-fast) var(--ease); }
.tbl tbody tr:hover { background: color-mix(in srgb, var(--text-1) 4%, transparent); }
.tbl .num { font-variant-numeric: tabular-nums; white-space: nowrap; unicode-bidi: isolate; }
.tbl .name { font-weight: 700; white-space: nowrap; }
.scroll-x { overflow-x: auto; }

.tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 700;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: color-mix(in srgb, currentColor 10%, transparent);
}

/* ---------- radar ---------- */

.radar-card { padding: 14px; }
.radar-box { position: relative; width: 100%; aspect-ratio: 1 / .84; min-height: 300px; }
.radar-box canvas { width: 100%; height: 100%; display: block; }
.radar-tip {
  position: absolute; pointer-events: none; opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--t-fast) var(--ease);
  background: var(--card); border: 1px solid var(--hairline);
  border-radius: var(--r-inner); box-shadow: var(--catch);
  padding: 8px 12px; font-size: 12px; white-space: nowrap; z-index: 3;
}
.radar-tip[data-open="true"] { opacity: 1; }
.legend { display: flex; flex-wrap: wrap; gap: 14px; padding: 10px 6px 2px; font-size: 12px; color: var(--text-3); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }

/* ---------- forms ---------- */

.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 12px; font-weight: 700; color: var(--text-3); }
.field input, .field select {
  font: inherit; font-size: 14px;
  background: var(--sunken);
  color: var(--text-1);
  border: 1px solid var(--hairline);
  border-radius: var(--r-input);
  padding: 11px 14px;
  box-shadow: var(--catch);
}
.field input:focus-visible, .field select:focus-visible { outline: 2px solid var(--text-1); outline-offset: 1px; }
/* The form changes shape with the test, so the fields flow rather than sit in
   fixed columns that would leave gaps when one is hidden. */
.lg-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
.lg-form .field { flex: 1 1 190px; min-width: 130px; }
.lg-form .field[data-for="count"],
.lg-form .field[data-for="hops"],
.lg-form .field[data-for="port"] { flex: 0 0 120px; }
.lg-form .btn { flex: 0 0 auto; height: 44px; }
.seg { display: flex; gap: 4px; padding: 4px; border-radius: var(--r-pill);
  border: 1px solid var(--hairline); background: var(--sunken); box-shadow: var(--catch); }
.seg button {
  font: inherit; font-size: 12.5px; font-weight: 700; color: var(--text-2);
  background: none; border: 0; border-radius: var(--r-pill); padding: 7px 14px; cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.seg button[aria-pressed="true"] { background: var(--card); color: var(--text-1); box-shadow: var(--catch); }
.seg--scroll { width: max-content; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.seg--scroll::-webkit-scrollbar { display: none; }

/* ---------- load chart ---------- */

.chart-box { position: relative; height: 280px; margin-top: 4px; }
.chart-box canvas { width: 100%; height: 100%; display: block; }
.chart-tip {
  position: absolute; pointer-events: none; opacity: 0; z-index: 2;
  transition: opacity var(--t-fast) var(--ease);
  background: var(--card); border: 1px solid var(--hairline);
  border-radius: var(--r-inner); box-shadow: var(--catch);
  padding: 7px 11px; font-size: 12px; white-space: nowrap;
}
.chart-tip[data-open="true"] { opacity: 1; }

/* The three traffic series are told apart by luminance and weight, not by hue.
   Colour in this interface means status, and a traffic chart is not a status. */
.key { width: 14px; height: 2px; border-radius: 2px; display: inline-block; }
.key--total { background: var(--text-1); height: 2px; }
.key--in { background: var(--text-2); }
.key--out { background: var(--text-3); height: 1px; }

.out {
  margin-top: 14px; padding: 14px;
  background: var(--sunken); border: 1px solid var(--hairline);
  border-radius: var(--r-inner);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.75; color: var(--text-2);
  white-space: pre; overflow-x: auto; direction: ltr; text-align: left;
  min-height: 44px;
}
.out b { color: var(--text-1); font-weight: 700; }
.msg { margin-top: 10px; font-size: 12.5px; color: var(--text-2); }
.msg--bad { color: var(--led-down); }

/* ---------- ink panel ---------- */

.ink {
  background: var(--ink); border-radius: var(--r-card);
  border: 1px solid rgba(255, 255, 255, .08);
  color: var(--on-ink-1); padding: 20px;
}
.ink .t-2, .ink .stat__l, .ink .eyebrow { color: var(--on-ink-2); }

/* ---------- footer ---------- */

.foot {
  margin: 40px 0 24px; border-radius: 24px;
  border: 1px solid var(--hairline); background: var(--card);
  box-shadow: var(--catch); padding: 26px 26px 28px;
  font-size: 13px; color: var(--text-3);
}
.foot__cols { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 26px; }

/* The closing bar matches parsabr.com: the copyright on one side, the trust
   seal on the other, separated from the link columns by a single hairline. */
.foot__bottom {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--hairline);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 12.5px;
}
/* The brand column mirrors parsabr.com: logo, one sentence about the company,
   then the social buttons. */
/* The column is a flex container, so its default stretch alignment pulls the
   logo to the full column width while its height stays fixed, which distorts
   it. Aligning it to the start lets width:auto keep the aspect ratio. */
.foot__brand img { height: 34px; width: auto; display: block; align-self: flex-start; }
:root[data-theme="dark"] .foot__brand img,
:root:not([data-theme="light"]) .foot__brand img { filter: brightness(0) invert(1); opacity: .92; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .foot__brand img { filter: none; opacity: 1; }
}
.foot__brand p { margin: 14px 0 0; max-width: 42ch; line-height: 1.8; }
.foot__socials { display: flex; gap: 10px; margin-top: 18px; }
.foot__socials a {
  width: 36px; height: 36px; border-radius: 8px;
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--text-1) 4%, transparent);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-2);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.foot__socials a:hover { color: var(--text-1); border-color: var(--text-3); }

.foot__copy { display: flex; flex-direction: column; gap: 4px; }
.foot__copy .en {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  opacity: .75;
}

/* The badge image carries its own transparency, so it sits straight on the
   canvas with no panel behind it. It also keeps its own colours: recolouring
   a trust mark misrepresents it, so this is the one image on the page that is
   never knocked to white in dark mode. */
.enamad {
  flex-shrink: 0;
  display: inline-flex;
  line-height: 0;
  transition: opacity var(--t-fast) var(--ease);
}
.enamad:hover { opacity: .82; }
.enamad img { width: auto; height: 52px; }
/* Grid children default to a minimum size of their content, so one long link
   could push the whole footer wider than the page. */
.foot__cols > div { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.foot__cols a { color: var(--text-2); }
.foot__cols a:hover { color: var(--text-1); }
@media (max-width: 900px) {
  .foot__cols { grid-template-columns: 1fr 1fr; gap: 22px; }
  .foot__bottom { align-items: flex-start; }
}

/* ---------- reveal ---------- */

.rise { opacity: 0; transform: translateY(8px); animation: rise .5s var(--ease) forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* Grid and flex children default to a minimum size of their content, which is
   what let a wide table push the whole document past the viewport. */
body { overflow-x: hidden; }
.grid-2 > *, .row-between > * { min-width: 0; }

@media (max-width: 900px) {
  .grid-2 { grid-template-columns: 1fr; }
  .lg-form { grid-template-columns: 1fr; }
  .topbar__inner { height: 52px; gap: 10px; }
  .topnav a { padding: 7px 10px; }
  .brand__sep, .brand__label { display: none; }
}

@media (max-width: 700px) {
  /* The capsule cannot hold the logo, four links and a control at phone width
     without forcing the page wider than the screen. The links are dropped
     rather than shrunk, because the sections they point at start immediately
     below the fold anyway. */
  .topnav a { display: none; }
  .topbar { padding: 10px 12px; }
  .wrap { padding: 0 12px; }
  .section { padding: 30px 0; }
  .radar-box { min-height: 330px; }
  .seg button { padding: 7px 11px; }
  .stat__v { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .rise { opacity: 1; transform: none; }
}
