/* APOLLO VPN — components: badges, forms, toasts, modals, tooltips, states */

/* ============================ Badge / chip ============================ */

.badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 15px 7px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-hi);
  background: var(--glass);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  font-family: var(--font-display);
  font-size: var(--t-micro); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-2);
}
.badge__dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--violet);
  box-shadow: 0 0 0 3px var(--violet-a20), 0 0 10px var(--violet);
}

.tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px; border-radius: var(--r-xs);
  border: 1px solid var(--line-soft);
  background: oklch(1 0 0 / 0.03);
  font-family: var(--font-mono); font-size: var(--t-micro);
  letter-spacing: 0.04em; color: var(--ink-3);
}
.tag--demo { color: var(--warn); border-color: oklch(0.82 0.15 82 / 0.28); background: oklch(0.82 0.15 82 / 0.08); }

/* Status pill */
.pill {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--t-xs); font-weight: 600; color: var(--ink-2);
}
.pill__led {
  position: relative; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--ink-4);
}
.pill--on .pill__led { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-a14); }
.pill--on .pill__led::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 1px solid var(--ok); opacity: 0.6;
  animation: ledPulse 2.4s var(--ease-out) infinite;
}
.pill--on { color: var(--ok); }
.pill--busy .pill__led { background: var(--warn); box-shadow: 0 0 0 3px oklch(0.82 0.15 82 / 0.16); }
.pill--busy { color: var(--warn); }
.pill--off .pill__led { background: var(--ink-4); }
.pill--off { color: var(--ink-4); }
.pill--down .pill__led { background: var(--danger); }
.pill--down { color: var(--danger); }

@keyframes ledPulse {
  0%   { transform: scale(1);   opacity: 0.65; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .pill--on .pill__led::after { animation: none; opacity: 0.4; } }

/* Flag: drawn, not emoji — regional indicators degrade to letter pairs on
   several platforms, which reads as a rendering failure. */
.flag {
  display: inline-block; flex: none;
  width: 1.5em; height: 1em;
  border-radius: 3px; overflow: hidden;
  vertical-align: -0.14em;
  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.16), 0 1px 3px oklch(0.02 0 0 / 0.5);
}
.flag svg { display: block; width: 100%; height: 100%; }

/* ============================ Forms ============================ */

.field { display: grid; gap: 7px; }
.field__label {
  font-size: var(--t-xs); font-weight: 600; color: var(--ink-3);
  letter-spacing: 0.01em;
}
.field__hint { font-size: var(--t-xs); color: var(--ink-4); }
.field__err {
  font-size: var(--t-xs); color: var(--danger);
  display: flex; align-items: center; gap: 6px;
  opacity: 0; transform: translateY(-3px);
  transition: opacity var(--d-tip) var(--ease-out), transform var(--d-tip) var(--ease-out);
  min-height: 0;
}
.field[data-invalid="true"] .field__err { opacity: 1; transform: none; }

.input, .select, .textarea {
  width: 100%;
  font-family: inherit; font-size: var(--t-body); color: var(--ink);
  background: oklch(0.10 0.026 274 / 0.7);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 13px 15px;
  min-height: 48px;
  transition: border-color var(--d-menu) ease, box-shadow var(--d-menu) ease, background-color var(--d-menu) ease;
}
.textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
.input::placeholder, .textarea::placeholder { color: var(--ink-4); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--line-hi); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 3px var(--violet-a12);
  background: oklch(0.12 0.03 274 / 0.85);
}
.field[data-invalid="true"] .input,
.field[data-invalid="true"] .select { border-color: var(--danger); }
.field[data-invalid="true"] .input:focus { box-shadow: 0 0 0 3px oklch(0.66 0.20 22 / 0.16); }

.select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%238e8fa8%22 stroke-width=%222%22 stroke-linecap=%22round%22%3E%3Cpath d=%22M6 9l6 6 6-6%22/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 17px;
  padding-right: 40px;
  cursor: pointer;
}
.select option { background: var(--surface-1); color: var(--ink); }

.input-wrap { position: relative; }
.input-wrap .input { padding-right: 46px; }
.input-wrap__btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 0; background: transparent; color: var(--ink-4); cursor: pointer;
  border-radius: var(--r-sm);
  transition: color var(--d-menu) ease, background-color var(--d-menu) ease, transform var(--d-press) var(--ease-out);
}
.input-wrap__btn:hover { color: var(--ink-2); background: oklch(1 0 0 / 0.05); }
.input-wrap__btn:active { transform: translateY(-50%) scale(0.9); }

/* Checkbox */
.check { display: flex; align-items: flex-start; gap: 11px; cursor: pointer; font-size: var(--t-sm); color: var(--ink-3); }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check__box {
  width: 19px; height: 19px; flex: none; margin-top: 1px;
  border-radius: 6px; border: 1px solid var(--line-hi);
  background: oklch(0.10 0.026 274 / 0.7);
  display: grid; place-items: center;
  transition: background-color var(--d-tip) ease, border-color var(--d-tip) ease, transform var(--d-press) var(--ease-out);
}
.check:active .check__box { transform: scale(0.9); }
.check__box svg { width: 12px; height: 12px; opacity: 0; transform: scale(0.6); color: oklch(0.99 0 0);
  transition: opacity var(--d-tip) var(--ease-out), transform var(--d-tip) var(--ease-out); }
.check input:checked + .check__box { background: var(--violet); border-color: var(--violet); }
.check input:checked + .check__box svg { opacity: 1; transform: scale(1); }
.check input:focus-visible + .check__box { outline: 2px solid var(--violet); outline-offset: 3px; }
.check a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-hi); }
.check a:hover { color: var(--violet); }

/* Toggle */
.toggle { display: inline-flex; align-items: center; gap: 11px; cursor: pointer; }
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle__track {
  width: 42px; height: 24px; border-radius: var(--r-pill); flex: none;
  background: var(--surface-3); border: 1px solid var(--line);
  padding: 2px;
  transition: background-color var(--d-menu) ease, border-color var(--d-menu) ease;
}
.toggle__knob {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--ink-3);
  transition: transform var(--d-menu) var(--ease-out), background-color var(--d-menu) ease;
}
.toggle input:checked + .toggle__track { background: var(--violet); border-color: var(--violet); }
.toggle input:checked + .toggle__track .toggle__knob { transform: translateX(18px); background: oklch(0.99 0 0); }
.toggle input:focus-visible + .toggle__track { outline: 2px solid var(--violet); outline-offset: 3px; }

/* Segmented control — clip-path duplication for a seamless colour swap */
.seg {
  position: relative; display: inline-flex; padding: 4px; gap: 2px;
  border-radius: var(--r-pill); border: 1px solid var(--line);
  background: oklch(0.10 0.026 274 / 0.7);
  overflow: hidden;
}
.seg__ind {
  position: absolute; top: 4px; bottom: 4px; left: 0;
  border-radius: var(--r-pill);
  background: linear-gradient(118deg, var(--violet-deep), var(--violet));
  box-shadow: 0 4px 16px -6px oklch(0.665 0.235 296 / 0.9);
  transition: transform var(--d-menu) var(--ease-out), width var(--d-menu) var(--ease-out);
  will-change: transform, width;
}
.seg__btn {
  position: relative; z-index: 1;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-display); font-size: var(--t-xs); font-weight: 700;
  color: var(--ink-3); padding: 8px 16px; border-radius: var(--r-pill);
  white-space: nowrap;
  transition: color var(--d-menu) ease, transform var(--d-press) var(--ease-out);
}
.seg__btn:active { transform: scale(0.96); }
.seg__btn[aria-selected="true"] { color: oklch(0.99 0 0); }

/* ============================ Skeleton ============================ */

.sk {
  position: relative; overflow: hidden;
  background: oklch(0.18 0.03 274 / 0.55);
  border-radius: var(--r-xs);
  height: 12px;
}
.sk::after {
  content: ""; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.07), transparent);
  animation: shimmer 1.4s var(--ease-out) infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }
.sk--title { height: 18px; width: 58%; }
.sk--line { height: 11px; width: 100%; }
.sk--line-sm { height: 11px; width: 72%; }
.sk--chip { height: 22px; width: 64px; border-radius: var(--r-pill); }

/* ============================ Empty / error state ============================ */

.state {
  display: grid; justify-items: center; text-align: center; gap: var(--s-4);
  padding: clamp(40px, 6vw, 76px) var(--s-5);
}
.state__icon {
  width: 58px; height: 58px; border-radius: var(--r-lg);
  display: grid; place-items: center;
  border: 1px solid var(--line-hi);
  background: var(--violet-a12);
  color: var(--violet);
}
.state__icon svg { width: 25px; height: 25px; }
.state h3 { text-transform: uppercase; letter-spacing: 0.06em; font-size: var(--t-h3); }
.state p { color: var(--ink-4); font-size: var(--t-sm); max-width: 42ch; }
.state--error .state__icon { color: var(--danger); border-color: oklch(0.66 0.20 22 / 0.3); background: oklch(0.66 0.20 22 / 0.1); }

/* ============================ Toast ============================ */

.toaster {
  position: fixed; z-index: 180;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  display: flex; flex-direction: column-reverse; gap: 10px;
  width: min(380px, calc(100vw - 32px));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 15px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-hi);
  background: oklch(0.125 0.030 272 / 0.92);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--sh-3);
  color: var(--ink-2);
  font-size: var(--t-sm);
  /* transitions, not keyframes: toasts stack fast and must retarget mid-flight */
  opacity: 1; transform: translateY(0) scale(1);
  transition: opacity 320ms var(--ease-out), transform 320ms var(--ease-out);
}
.toast[data-enter="true"] { opacity: 0; transform: translateY(16px) scale(0.96); }
.toast[data-exit="true"]  { opacity: 0; transform: translateY(8px) scale(0.97); transition-duration: 200ms; }
.toast__ic { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.toast__body { flex: 1; min-width: 0; }
.toast__t { font-weight: 700; color: var(--ink); font-family: var(--font-display); }
.toast__d { color: var(--ink-4); font-size: var(--t-xs); margin-top: 2px; }
.toast--ok .toast__ic { color: var(--ok); }
.toast--err .toast__ic { color: var(--danger); }
.toast--info .toast__ic { color: var(--blue); }
.toast__x {
  border: 0; background: transparent; color: var(--ink-4); cursor: pointer;
  width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--r-xs); flex: none;
  transition: color var(--d-tip) ease, transform var(--d-press) var(--ease-out);
}
.toast__x:hover { color: var(--ink); }
.toast__x:active { transform: scale(0.88); }

/* ============================ Modal ============================ */

.modal {
  position: fixed; inset: 0; z-index: 170;
  display: grid; place-items: center;
  padding: var(--s-5);
  visibility: hidden;
}
.modal[data-open="true"] { visibility: visible; }
.modal__scrim {
  position: absolute; inset: 0;
  background: oklch(0.03 0.01 276 / 0.76);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity var(--d-modal) var(--ease-out);
}
.modal[data-open="true"] .modal__scrim { opacity: 1; }
.modal__card {
  position: relative;
  width: min(460px, 100%);
  max-height: min(86dvh, 760px);
  overflow: auto;
  padding: var(--s-6);
  border-radius: var(--r-xl);
  border: 1px solid var(--line-hi);
  background: oklch(0.11 0.028 273 / 0.95);
  backdrop-filter: blur(26px); -webkit-backdrop-filter: blur(26px);
  box-shadow: var(--sh-3), inset 0 1px 0 oklch(1 0 0 / 0.06);
  /* modals are not anchored to a trigger — they stay centre-origin */
  transform-origin: center;
  opacity: 0; transform: scale(0.95) translateY(10px);
  transition: opacity var(--d-modal) var(--ease-out), transform var(--d-modal) var(--ease-out);
}
.modal[data-open="true"] .modal__card { opacity: 1; transform: none; }
.modal__head { display: flex; align-items: flex-start; gap: var(--s-4); margin-bottom: var(--s-5); }
.modal__head h3 { text-transform: uppercase; letter-spacing: 0.05em; flex: 1; }
.modal__x {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: transparent; color: var(--ink-3); cursor: pointer;
  transition: color var(--d-tip) ease, border-color var(--d-tip) ease, transform var(--d-press) var(--ease-out);
}
.modal__x:hover { color: var(--ink); border-color: var(--line-hi); }
.modal__x:active { transform: scale(0.92); }
.modal__foot { display: flex; gap: 10px; margin-top: var(--s-6); flex-wrap: wrap; }
/* flex:1 (flex-basis:0) forces every footer button to the exact same
   width regardless of label — fine for two short, similar labels, but a
   short "Закрыть" next to a long "Скопировать конфигурацию" ends up
   giving the short one far more room than it needs while starving the
   long one, clipping it (see the identical bug and full reasoning at
   assets/css/dashboard.css's .cfg__acts .btn). flex-basis:auto sizes each
   to its own content and only shrinks what has to shrink. */
.modal__foot .btn { flex: 1 1 auto; }

/* ============================ Tooltip ============================ */

.tip {
  position: fixed; z-index: 190;
  padding: 7px 11px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-hi);
  background: oklch(0.16 0.032 272 / 0.96);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  color: var(--ink);
  font-size: var(--t-xs); font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: var(--sh-2);
  /* popovers scale from their trigger, never from centre */
  transform-origin: var(--tip-origin, 50% 100%);
  opacity: 0; transform: scale(0.97);
  transition: opacity var(--d-tip) var(--ease-out), transform var(--d-tip) var(--ease-out);
}
.tip[data-open="true"] { opacity: 1; transform: scale(1); }
/* once one tooltip is open, neighbours open instantly */
.tip[data-instant="true"] { transition-duration: 0ms; }

/* ============================ Accordion ============================ */

.acc { border-top: 1px solid var(--line-soft); }
.acc__item { border-bottom: 1px solid var(--line-soft); }
.acc__btn {
  width: 100%; display: flex; align-items: center; gap: var(--s-4);
  padding: 22px 0; text-align: left;
  background: transparent; border: 0; cursor: pointer;
  font-family: var(--font-display); font-size: clamp(1rem, 0.95rem + 0.35vw, 1.15rem); font-weight: 700;
  color: var(--ink);
  transition: color var(--d-menu) ease;
}
@media (hover: hover) and (pointer: fine) { .acc__btn:hover { color: var(--violet); } }
.acc__q { flex: 1; }
.acc__sign {
  width: 30px; height: 30px; flex: none; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--line); color: var(--ink-3);
  transition: transform var(--d-menu) var(--ease-out), border-color var(--d-menu) ease, color var(--d-menu) ease;
}
.acc__sign svg { width: 13px; height: 13px; }
.acc__item[data-open="true"] .acc__sign { transform: rotate(45deg); border-color: var(--violet); color: var(--violet); }
.acc__panel {
  overflow: hidden;
  height: 0;
  transition: height 280ms var(--ease-out), opacity 240ms var(--ease-out);
  opacity: 0;
}
.acc__item[data-open="true"] .acc__panel { opacity: 1; }
.acc__panel > div { padding: 0 52px 24px 0; color: var(--ink-3); font-size: var(--t-sm); line-height: 1.72; }

/* ============================ Copy field ============================ */

.copybox {
  display: flex; align-items: center; gap: 8px;
  /* Needed whenever a flex/grid ancestor tries to shrink this below its
     content's natural width — e.g. as one of .cfg's grid-item children
     (assets/css/dashboard.css) — the code inside already handles its own
     ellipsis via min-width:0, but that only helps once this box itself
     is allowed to actually be narrower than the full link text. */
  min-width: 0;
  padding: 10px 10px 10px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: oklch(0.08 0.02 276 / 0.8);
}
.copybox code {
  flex: 1; min-width: 0;
  font-family: var(--font-mono); font-size: var(--t-xs); color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ============================ Breadcrumbs ============================ */

.crumbs { display: flex; align-items: center; gap: 8px; font-size: var(--t-xs); color: var(--ink-4); margin-bottom: var(--s-5); flex-wrap: wrap; }
.crumbs a { transition: color var(--d-menu) ease; }
.crumbs a:hover { color: var(--violet); }
.crumbs span[aria-hidden] { opacity: 0.5; }

/* ============================ Divider ============================ */

.rule { height: 1px; border: 0; margin: 0; background: linear-gradient(90deg, transparent, var(--line), transparent); }
