/* Anony Balance — the signed-in APP look (feat/app-look, preview): PORTED from AnonyVPN's static/app.css (the Anony Labs
   signed-in style, itself AnonyChat's design system; AnonyMail's static/app.css is the same file with its blue), so the
   balance looks like the other product dashboards: ink #151719, off-white #F3F2ED, the same graphite grounds and rules,
   type scale, radii (chip 6, control 10, card 14), focus ring, 44 px targets, the rail (72 px, hover-expands to 240 px
   over the content, labelled from 1280 px) and the phone bottom bar. Each block is copied verbatim and marked with its
   source lines; ONLY the accent changes: Anony Labs off-white (anonylabs.com's own colour — the products' colours are
   taken: AnonyChat yellow, AnonyMail blue, AnonyVPN orange, AnonyID violet). Anony Balance's few additions are at the
   end ("Anony Balance additions"). No inline styles anywhere (CSP style-src 'self'). Used by the balance page only on
   this branch; every other page keeps static/balance.css. */
/* [AnonyVPN static/app.css 8-62] */
@font-face { font-family: "Inter"; src: url("/static/fonts/inter-var-latin.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Plex Mono"; src: url("/static/fonts/plex-mono-400-latin.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Space Grotesk"; src: url("/static/fonts/space-grotesk-latin.woff2?v=1") format("woff2"); font-weight: 300 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Space Grotesk Fallback"; src: local("Arial"); ascent-override: 89.71%; descent-override: 26.62%; line-gap-override: 0%; size-adjust: 109.69%; }

:root {
  /* grounds and rules (AnonyChat's palette) */
  --bg: #151719; --surface: #1c1f21; --raised: #24282b; --overlay: #2b2f32; --field: #1b1e20;
  --rule: #303538; --rule-strong: #3c4246; --rule-hover: #4a5156;
  /* text */
  --fg: #f3f2ed; --fg-soft: #dad9d4; --fg-2: #bbbfc1; --fg-3: #999fa3; --placeholder: #6f7579;
  /* the one accent: Anony Labs off-white (AnonyVPN: orange, AnonyMail: blue) */
  --accent: #f3f2ed; --accent-hover: #ffffff; --accent-soft: #26282a; --accent-line: rgba(243, 242, 237, 0.4); --on-accent: #151719;
  /* status colours (badges, meters, banners) — never decoration */
  --ok: #3ce8a0; --warn: #f2c94c; --danger: #ff6b8a; --info: #6cb6ff;
  --ok-line: rgba(60, 232, 160, 0.4); --warn-line: rgba(242, 201, 76, 0.4); --danger-line: rgba(255, 107, 138, 0.45); --info-line: rgba(108, 182, 255, 0.4);
  --warn-bg: rgba(242, 201, 76, 0.07); --danger-bg: rgba(255, 107, 138, 0.08); --info-bg: rgba(108, 182, 255, 0.07); --note-bg: rgba(243, 242, 237, 0.04);
  /* data states (owner 2026-10-10: "you can add green/red for data to display"): green = connected / ok / up, red =
     error / over the limit / down; they are --ok and --danger above (on --bg 11.3:1 and 6.6:1, on --surface 10.4:1 and 6.1:1), never decoration */
  --ok-bg: rgba(60, 232, 160, 0.08); --ok-halo: rgba(60, 232, 160, 0.16); --accent-glow: rgba(243, 242, 237, 0.06);
  /* shape, type, motion */
  --r-chip: 6px; --r-control: 10px; --r-card: 14px; --radius: var(--r-control);
  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ui: "Space Grotesk", "Space Grotesk Fallback", "Segoe UI", system-ui, sans-serif;
  --display: "Archivo Black", "Archivo Black Fallback", var(--font);
  --mono: "Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --shadow-overlay: 0 16px 48px -12px rgba(0, 0, 0, 0.7);
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); }
body { font: 400 16px/1.55 var(--font); min-height: 100vh; display: flex; flex-direction: column; -webkit-font-smoothing: antialiased; }
a { color: var(--fg); text-underline-offset: 3px; }
a:hover { color: #fff; }
::selection { background: rgba(243, 242, 237, 0.25); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
h1, h2, h3, h4 { font-weight: 600; letter-spacing: -0.025em; line-height: 1.15; margin: 0 0 0.5em; }
h1 { font-size: clamp(28px, 5vw, 40px); }
h2 { font-size: 21px; }
h3 { font-size: 17px; }
h4 { font-size: 15px; }
p { margin: 0 0 1em; }
code { font-family: var(--mono); font-size: 0.88em; }
.lead { color: var(--fg-2); font-size: 17px; }
.small, .hint { color: var(--fg-3); font-size: 14px; }
.mono { font-family: var(--mono); font-size: 13px; }
.nowrap { white-space: nowrap; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }
.ico { width: 20px; height: 20px; flex: none; }
.ico--sm { width: 16px; height: 16px; }
.ico--xs { width: 14px; height: 14px; }

/* [AnonyVPN static/app.css 63-75] */
/* ---- public pages (legal, "not open yet"): a slim top bar and a footer ---- */
.top { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 24px; }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.brand img { display: block; height: 25px; width: auto; }
.main { width: 100%; max-width: 760px; margin: 0 auto; padding: 40px 16px 64px; flex: 1; }
.main--wide { max-width: 1100px; }
/* The public footer: static/footer.css (shared with AnonyMail and anonylabs.com, owner 2026-10-13). AnonyVPN's colours
   and faces for it: */
:root {
  --foot-fg: var(--fg); --foot-fg-2: var(--fg-2); --foot-fg-3: var(--fg-3); --foot-rule: var(--rule); --foot-rule-strong: var(--rule-strong);
  --foot-accent: var(--accent); --foot-panel: var(--surface); --foot-hover: var(--raised); --foot-current: var(--accent-soft);
  --foot-sans: var(--font); --foot-mono: var(--mono);
}
/* [AnonyVPN static/app.css 76-86] */
.eyebrow { font: 400 12px/1 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-3); }
.legal h2 { margin-top: 1.6em; }
.legal li { margin: 0 0 6px; color: var(--fg-2); }
.head { margin: 0 0 20px; }
.plain { list-style: none; padding: 0; margin: 0 0 16px; }
.plain li { padding: 8px 0; border-bottom: 1px solid var(--rule); }
.plain li:last-child { border-bottom: 0; }
.steps { padding-inline-start: 20px; color: var(--fg-2); margin: 0 0 12px; }
.steps li { margin: 0 0 6px; padding-inline-start: 4px; }
.steps li::marker { color: var(--fg-3); font-variant-numeric: tabular-nums; }

/* [AnonyVPN static/app.css 87-224] */
/* ---- cards (AnonyChat's Card: elevation 1 = surface + a 1 px rule, card radius, no shadow) ---- */
.card { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); padding: 24px; margin: 0 0 24px; min-width: 0; }
.card--quiet { background: transparent; }
.card--empty { padding: 0; }
.card__head { margin: 0 0 16px; }
.card__head h2 { display: flex; align-items: center; gap: 10px; margin: 0 0 4px; }
.card__head h2 .ico { color: var(--fg-3); }
.card__desc { margin: 0; color: var(--fg-3); font-size: 14px; max-width: 70ch; }
.card > :last-child { margin-bottom: 0; }

/* ---- notes, banners, toasts ---- */
.note { background: var(--note-bg); border: 1px solid var(--rule); border-radius: var(--r-control); padding: 12px 14px; font-size: 15px; }
.note--warn { background: var(--warn-bg); border-color: var(--warn-line); }
.warn-text { color: var(--warn); }
.banner { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 20px; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--note-bg); color: var(--fg-soft); font-size: 14px; line-height: 1.45; }
.banner > .ico { margin-top: 1px; }
.banner > div > :last-child { margin-bottom: 0; }
.banner strong { color: var(--fg); }
.banner--warn { background: var(--warn-bg); border-color: var(--warn-line); }
.banner--warn > .ico { color: var(--warn); }
.banner--danger { background: var(--danger-bg); border-color: var(--danger-line); }
.banner--danger > .ico { color: var(--danger); }
.banner--info { background: var(--info-bg); border-color: var(--info-line); }
.banner--info > .ico { color: var(--info); }
.toast {
  position: fixed; z-index: 50; left: 50%; bottom: calc(88px + env(safe-area-inset-bottom)); translate: -50% 0; width: max-content; max-width: calc(100vw - 32px);
  display: flex; align-items: center; gap: 10px; margin: 0; padding: 12px 16px; border: 1px solid var(--rule-strong); border-radius: 12px;
  background: var(--overlay); box-shadow: var(--shadow-overlay); color: var(--fg); font: 500 14px/1.35 var(--ui);
  animation: toast-in 220ms var(--ease) both, toast-out 320ms var(--ease) 6s forwards;
}
.toast > .ico { color: var(--ok); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to { opacity: 0; visibility: hidden; transform: translateY(8px); } }
@media (min-width: 768px) { .toast { inset-inline-start: auto; inset-inline-end: 24px; top: 20px; bottom: auto; translate: none; } }

/* ---- buttons (AnonyChat's Button: 44 px, radius 10; secondary = surface + rule; primary = the accent, at most one per
   screen; danger tinted, never the brand fill) ---- */
.button, button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 16px; border-radius: var(--r-control);
  border: 1px solid var(--rule-strong); background: var(--surface); color: var(--fg-soft); cursor: pointer; text-decoration: none; white-space: nowrap;
  font-family: inherit; font-size: 14px; font-weight: 500; line-height: 1.2; transition: color 150ms, background-color 150ms, border-color 150ms;
}
.button:hover, button:hover { border-color: var(--accent-line); color: var(--fg); }
.primary, .button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.primary:hover, .button.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
.danger, .button.danger { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-line); font-weight: 600; }
.danger:hover, .button.danger:hover { background: rgba(255, 107, 138, 0.15); border-color: var(--danger); color: var(--danger); }
.link { min-height: 0; background: none; border: 0; padding: 0; font: inherit; color: var(--fg-2); text-decoration: underline; text-underline-offset: 3px; }
.link:hover { color: var(--fg); }
.small-btn { min-height: 36px; padding: 0 12px; font-size: 13px; gap: 6px; }
.icon-btn { min-height: 32px; width: 32px; padding: 0; border-color: transparent; background: transparent; color: var(--fg-3); }
.icon-btn:hover { background: var(--raised); color: var(--fg); border-color: transparent; }
.icon-btn.is-done { color: var(--ok); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
button[aria-busy="true"] { cursor: progress; }
@media (max-width: 767.98px), (pointer: coarse) {
  .small-btn { min-height: 44px; }
  .icon-btn { min-height: 44px; width: 44px; }
}
form.inline { display: inline; margin: 0; }
.row, .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.stack { display: flex; flex-direction: column; gap: 8px; max-width: 520px; }
.stack button { align-self: flex-start; margin-top: 8px; }

/* ---- form controls ---- */
label { font-family: inherit; font-size: 14px; font-weight: 500; line-height: 1.3; color: var(--fg-2); }
label.check { display: flex; gap: 10px; align-items: flex-start; color: var(--fg-soft); min-height: 24px; }
label.check input { margin-top: 3px; }
input, select, textarea {
  font-family: inherit; font-size: 16px; line-height: 1.3; color: var(--fg); background: var(--field); border: 1px solid var(--rule-strong); border-radius: var(--r-control);
  padding: 11px 12px; width: 100%; min-height: 44px; transition: border-color 150ms;
}
input:hover, select:hover, textarea:hover { border-color: var(--rule-hover); }
input:focus, select:focus, textarea:focus { border-color: var(--accent); }
input::placeholder, textarea::placeholder { color: var(--placeholder); }
input[type=checkbox], input[type=radio] { width: 18px; height: 18px; min-height: 0; padding: 0; accent-color: var(--accent); flex: none; }
select option { background: var(--surface); }
textarea { font: 400 13.5px/1.5 var(--mono); }
input.date { width: auto; min-height: 36px; padding: 6px 8px; font-size: 13px; }
fieldset { border: 1px solid var(--rule); border-radius: var(--r-card); padding: 16px 18px 18px; margin: 0 0 8px; min-width: 0; }
legend { padding: 0 6px; font-weight: 600; }

/* ---- badges (AnonyChat's Badge: a label, never a control; one colour per status) ---- */
.pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 7px; border: 1px solid var(--rule-strong); border-radius: var(--r-chip);
  font-family: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.35; color: var(--fg-3); white-space: nowrap; vertical-align: middle; text-decoration: none;
}
.pill--accent { color: var(--accent); border-color: var(--accent-line); }
.pill--ok { color: var(--ok); border-color: var(--ok-line); }
.pill--warn { color: var(--warn); border-color: var(--warn-line); }
.pill--danger { color: var(--danger); border-color: var(--danger-line); }
.pill--info { color: var(--info); border-color: var(--info-line); }
.pill--dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.pill--wrap { display: inline-block; white-space: normal; }
.pill--wrap.pill--dot::before { display: inline-block; margin-inline-end: 6px; vertical-align: 1px; }
.pill--link { min-height: 32px; padding: 0 10px; transition: background-color 150ms; }
.pill--link:hover { background: var(--accent-soft); color: var(--accent); }

/* ---- meters ---- */
.meter { display: block; height: 6px; margin: 10px 0 0; border-radius: 99px; background: var(--raised); overflow: hidden; }
.meter__fill { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.meter--warn .meter__fill { background: var(--warn); }
.meter--danger .meter__fill { background: var(--danger); }
.meter--ok .meter__fill { background: var(--ok); }
.w-0 { width: 0; } .w-5 { width: 5%; } .w-10 { width: 10%; } .w-15 { width: 15%; } .w-20 { width: 20%; } .w-25 { width: 25%; } .w-30 { width: 30%; }
.w-35 { width: 35%; } .w-40 { width: 40%; } .w-45 { width: 45%; } .w-50 { width: 50%; } .w-55 { width: 55%; } .w-60 { width: 60%; } .w-65 { width: 65%; }
.w-70 { width: 70%; } .w-75 { width: 75%; } .w-80 { width: 80%; } .w-85 { width: 85%; } .w-90 { width: 90%; } .w-95 { width: 95%; } .w-100 { width: 100%; }
.load { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg-2); white-space: nowrap; }
.load__bars { display: inline-flex; gap: 3px; }
.load__bar { width: 12px; height: 6px; border-radius: 2px; background: var(--rule-strong); }
.load--low .is-on { background: var(--ok); }
.load--medium .is-on { background: var(--warn); }
.load--high .is-on { background: var(--danger); }

/* ---- tables (sticky headers, tabular numbers) ---- */
.tablewrap { overflow: auto; margin: 0 0 24px; border: 1px solid var(--rule); border-radius: var(--r-card); background: var(--surface); }
.tablewrap--scroll { max-height: calc(100vh - 96px); max-height: calc(100dvh - 96px); overscroll-behavior: contain; }
.card .tablewrap { border: 0; border-radius: 0; background: transparent; margin: 0 -24px 16px; padding: 0 12px; }
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13.5px; }
.table thead th { position: sticky; top: 0; z-index: 1; background: var(--surface); }
.table th { text-align: start; font-weight: 500; font-size: 12.5px; color: var(--fg-3); padding: 10px 12px; border-bottom: 1px solid var(--rule); white-space: nowrap; }
.table tbody th[scope="row"] { color: var(--fg-2); font-size: 13.5px; white-space: normal; }
.table td { padding: 12px; border-bottom: 1px solid var(--rule); vertical-align: top; }
.table tbody tr:last-child > * { border-bottom: 0; }
.table tbody tr:hover > td { background: rgba(243, 242, 237, 0.02); }
.table .num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table .actions { margin: 0; gap: 6px; }
.table td.actions { display: table-cell; }
.table td.actions > * { margin: 0 0 4px; margin-inline-end: 4px; }
.table tr.group th { color: var(--fg); font-size: 13px; font-weight: 600; padding: 14px 12px 8px; background: var(--bg); border-bottom: 1px solid var(--rule); }
.table tr.group th .ico { color: var(--fg-3); vertical-align: -3px; margin-inline-end: 6px; }
.table td.mono { white-space: nowrap; }
h1 .mono { font-size: 0.8em; letter-spacing: 0; }
.row > input:not([type=hidden]), .row > select { width: auto; flex: 0 1 140px; min-width: 80px; }
.table .sub { display: block; color: var(--fg-3); font-size: 12.5px; margin-top: 2px; }
.table .key { word-break: break-all; }
.tabnum { font-variant-numeric: tabular-nums; }

/* [AnonyVPN static/app.css 225-327] */
/* ---- the app shell (signed-in pages): AnonyChat's layout. The rail is fixed to the viewport (100dvh) and never
   scrolls; only the page content scrolls; the account entry stays pinned at the bottom at every window height. ---- */
:root { --rail: 72px; --rail-full: 240px; --radius-control: 10px; --ease-rail: cubic-bezier(0.4, 0, 0.2, 1); }
.avatar { width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center; background: var(--accent-soft); color: var(--accent); flex: none; }
.avatar .ico { width: 15px; height: 15px; }
.avatar--sm { width: 22px; height: 22px; }

/* phones: no rail, a fixed bottom bar (at most 5 cells; an Admin page, reached through /settings there, marks Settings
   with aria-current="true") */
.rail { display: none; }
.bar {
  position: fixed; inset: auto 0 0 0; z-index: 20; display: flex; align-items: center; justify-content: space-around; gap: 2px;
  padding: 10px 4px calc(12px + env(safe-area-inset-bottom)); border-top: 1px solid var(--rule); background: rgba(21, 23, 25, 0.95);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.bar__cell { position: relative; flex: 1 1 0; min-width: max-content; /* equal cells; a longer label (de "Einstellungen") takes what it needs from the others */ display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px 0; color: var(--fg-3); text-decoration: none; }
.bar__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 500 12px/1.2 var(--ui); }
.bar__cell[aria-current] { color: var(--fg); }
.bar__cell[aria-current] .ico { color: var(--accent); }
.bar__cell[aria-current] .bar__label { font-weight: 600; }
.bar__cell[aria-current]::after { content: ""; position: absolute; top: -10px; width: 32px; height: 3px; border-radius: 99px; background: var(--accent); }
html.app .appmain { min-height: 100vh; display: flex; flex-direction: column; padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
html.app .main { padding-top: 28px; }

@media (min-width: 768px) {
  .bar { display: none; }
  html.app .appmain { margin-inline-start: var(--rail); padding-bottom: 0; }
  html.app .main { padding-top: 48px; }
  .rail {
    position: fixed; inset-inline-start: 0; top: 0; z-index: 30; display: flex; flex-direction: column; height: 100vh; height: 100dvh;
    width: var(--rail); padding: 12px; overflow: hidden; border-inline-end: 1px solid var(--rule); background: var(--bg);
    transition: width 280ms var(--ease-rail), padding 280ms var(--ease-rail), box-shadow 280ms var(--ease-rail);
  }
  /* The brand slot = AnonyChat's signed-in rail, to the pixel (owner 2026-10-09): one 44 px row; compact: the mark's
     100-unit box 28 px at 8 px in (viewport 20,20); labelled (≥ 1280): the lockup 26.17 px tall at 12.14 px in
     (viewport 28.14,26.52), its mark exactly where the compact mark sits (24,24 there). They swap on rail state AND when the collapsed rail expands on hover
     or keyboard focus (AnonyChat's rail follow-up R-1, layouts.tsx: the mark gives way to the lockup; owner 2026-10-09). */
  .rail__brand { position: relative; display: flex; align-items: center; height: 44px; margin-bottom: 16px; flex: none; }
  .rail__mark { position: absolute; inset-inline-start: 8px; width: 28px; height: 28px; transition: opacity 200ms; }
  /* The lockup's mark lands EXACTLY on the compact mark (no jump when they cross-fade; owner 2026-10-09): in the lockup
     SVG the mark's 100-unit box is translate(-15.984 -9.72) scale(1.08) of a 551.849 × 100.947 viewBox, so at 28/108 px
     per unit the lockup is 26.17 px tall, 4.14 px left of and 2.52 px above the mark's box (8 px in, centred 28 px). */
  .rail__wordmark {
    position: absolute; inset-inline-start: calc(8px - 28px * -15.984 / 108); top: calc(50% - 14px - 28px * -9.72 / 108);
    height: calc(28px * 100.947 / 108); width: auto; max-width: none; opacity: 0; transition: opacity 200ms;
  }
  /* Too short a window for every entry (e.g. 360 px tall since the account chip, 2026-10-12): the list scrolls on its
     own, so the chip stays reachable; the page never moves the rail. */
  .rail__nav { flex: 1; display: flex; flex-direction: column; gap: 4px; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
  .rail__nav::-webkit-scrollbar { display: none; }
  .rail__spacer { flex: 1; }
  .rail__link {
    position: relative; display: flex; align-items: center; justify-content: center; min-height: 44px; border-radius: var(--radius-control);
    color: var(--fg-3); text-decoration: none; cursor: pointer; list-style: none; transition: background-color 150ms, color 150ms;
  }
  .rail__link::-webkit-details-marker { display: none; }
  .rail__link:hover { background: rgba(28, 31, 33, 0.6); color: var(--fg-2); }
  .rail__link[aria-current="page"] { background: var(--surface); color: var(--fg); }
  .rail__link[aria-current="page"] > .ico { color: var(--accent); }
  .rail__link[aria-current="page"]::before { content: ""; position: absolute; inset-inline-start: 0; top: 8px; bottom: 8px; width: 3px; border-radius: 99px; background: var(--accent); }
  .rail__label { margin-inline-start: 0; max-width: 0; overflow: hidden; white-space: nowrap; font: 500 15px/1.2 var(--ui); opacity: 0;
    transition: max-width 200ms cubic-bezier(0.22, 0.61, 0.36, 1), margin 200ms cubic-bezier(0.22, 0.61, 0.36, 1), opacity 200ms; }
  .rail__account { position: relative; }
  /* fixed (not absolute): the rail never scrolls and clips its overflow; a fixed menu is not clipped by it */
  .rail__menu {
    position: fixed; inset-inline-start: 12px; bottom: 68px; z-index: 40; min-width: 216px; padding: 6px; display: grid; gap: 2px;
    background: var(--surface); border: 1px solid var(--rule-strong); border-radius: 12px; box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.7);
  }
  .rail__menu .small { margin: 6px 10px 4px; font-size: 12.5px; }
  .rail__menu a, .rail__menu button {
    display: block; width: 100%; padding: 10px 12px; border: 0; border-radius: 8px; background: none; color: var(--fg); font: 400 15px/1.2 var(--font);
    text-align: start; text-decoration: none; justify-content: flex-start;
  }
  .rail__menu a:hover, .rail__menu button:hover { background: rgba(243, 242, 237, 0.06); color: var(--fg); border-color: transparent; }
  .rail__menu form { margin: 0; }
}
/* hover (collapsed rail, real pointer, after 120 ms) or keyboard focus: widen OVER the content, labels in; the icons
   and the brand stay exactly where they are (AnonyChat's rail brief F-2) */
@media (min-width: 768px) and (max-width: 1279.98px) {
  @media (hover: hover) and (pointer: fine) {
    .rail:hover { width: var(--rail-full); transition-delay: 120ms; box-shadow: 26px 0 50px -24px rgba(0, 0, 0, 0.9); }
    .rail:hover .rail__link { justify-content: flex-start; padding-inline-start: 14px; }
    .rail:hover .rail__label { flex: 1; max-width: 10rem; margin-inline-start: 12px; opacity: 1; transition-delay: 120ms; }
    .rail:hover .rail__mark { opacity: 0; transition-delay: 120ms; }
    .rail:hover .rail__wordmark { opacity: 1; transition-delay: 120ms; }
  }
  .rail:has(:focus-visible) { width: var(--rail-full); box-shadow: 26px 0 50px -24px rgba(0, 0, 0, 0.9); }
  .rail:has(:focus-visible) .rail__link { justify-content: flex-start; padding-inline-start: 14px; }
  .rail:has(:focus-visible) .rail__label { flex: 1; max-width: 10rem; margin-inline-start: 12px; opacity: 1; }
  .rail:has(:focus-visible) .rail__mark { opacity: 0; }
  .rail:has(:focus-visible) .rail__wordmark { opacity: 1; }
}
@media (min-width: 1280px) {
  html.app .appmain { margin-inline-start: var(--rail-full); }
  .rail { width: var(--rail-full); padding: 16px; }
  .rail .rail__link { justify-content: flex-start; padding: 0 12px; }
  .rail .rail__label { margin-inline-start: 12px; max-width: 10rem; flex: 1; opacity: 1; }
  .rail .rail__mark { opacity: 0; }
  .rail .rail__wordmark { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .rail, .rail__label, .rail__mark, .rail__wordmark { transition: none; }
}
/* [AnonyVPN static/app.css 390-391] */
.out { margin-inline-start: auto; padding-inline-start: 8px; color: var(--fg-3); }
.chev { margin-inline-start: auto; display: inline-flex; color: var(--fg-3); }
/* [AnonyVPN static/app.css 409-455] */
/* ---- the signed-in app: type and page frame (AnonyChat: Space Grotesk; title-1 32 / title-3 17 / body 15) ---- */
html.app body { font: 400 15px/1.45 var(--ui); font-feature-settings: "kern", "calt"; }
html.app .main { max-width: 1040px; padding: 28px 16px 64px; }
html.app h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
html.app h2 { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; }
html.app h3 { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
html.app .lead { font-size: 15px; line-height: 1.5; }
html.app .small, html.app .hint { font-size: 13.5px; line-height: 1.45; }
html.app p.hint { margin: 6px 0 0; }
html.app .mono { font-size: 12.5px; }
@media (min-width: 768px) {
  html.app .main { padding: 48px 32px 80px; }
  html.app h1 { font-size: 32px; line-height: 1.15; }
}

/* the page header: title + one line + the page's primary action */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 24px; margin: 0 0 28px; }
.page-head__text { min-width: 0; flex: 1 1 22rem; }
.page-head h1 { margin: 0 0 6px; }
.page-head .lead { margin: 0; max-width: 68ch; color: var(--fg-2); }
.page-head .lead strong { color: var(--fg); font-weight: 600; }
.page-head__eyebrow { margin: 0 0 6px; font-size: 13px; color: var(--fg-3); }
.page-head__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.section-title { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 32px 0 12px; }
.section-title h2 {
  margin: 0; font-size: 12.5px !important; font-weight: 600 !important; letter-spacing: 0.14em !important; text-transform: uppercase; color: var(--fg-3);
}
.section-title__extra { font-size: 13px; color: var(--fg-3); font-variant-numeric: tabular-nums; }
.page-note { display: flex; gap: 8px; align-items: flex-start; margin: 24px 0 0; }
.page-note .ico { margin-top: 2px; }
.back { margin: 0 0 16px; font-size: 14px; }
.back a { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; color: var(--fg-2); text-decoration: none; }
.back a:hover { color: var(--fg); }
.ico--back { transform: rotate(180deg); }

/* disclosure (details) */
.disclosure { margin: 0 0 16px; border: 1px solid var(--rule); border-radius: var(--r-control); }
.disclosure > summary {
  display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; cursor: pointer; list-style: none; color: var(--fg-soft); font-weight: 500; font-size: 14px;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: ""; width: 7px; height: 7px; border-inline-end: 1.6px solid var(--fg-3); border-bottom: 1.6px solid var(--fg-3); transform: rotate(-45deg); transition: transform 150ms; margin-inline-end: 4px; }
.disclosure[open] > summary::before { transform: rotate(45deg); }
.disclosure > summary:hover { color: var(--fg); }
.disclosure > :not(summary) { margin-inline-start: 14px; margin-inline-end: 14px; }
.disclosure > :last-child { margin-bottom: 14px; }

/* [AnonyVPN static/app.css 470-553] */
/* ---- Devices (design A, owner 2026-10-10): one Devices panel — the capacity bar, then the devices as rows separated by
   rules; each row's live view in an inset (its rule green while connected: a data state), Manage at the row's end. ---- */
.devices { list-style: none; padding: 0; margin: 4px 0 0; border-top: 1px solid var(--rule); }
.device { position: relative; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 14px; padding: 18px 0; min-width: 0; border-top: 1px solid var(--rule); }
.device:first-child { border-top: 0; }
.device:last-child { padding-bottom: 4px; }
.device__icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-control); background: var(--raised); color: var(--fg-2); }
.device--paused .device__icon { color: var(--fg-3); background: transparent; border: 1px dashed var(--rule-strong); }
.device--restricted .device__icon { color: var(--warn); background: var(--warn-bg); }
.device--suspended .device__icon { color: var(--danger); background: var(--danger-bg); }
.device__body { flex: 1 1 0; min-width: 0; }
.device__top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-height: 24px; }
.device__name { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; color: var(--fg); overflow-wrap: anywhere; }
.device__meta { margin: 3px 0 0; font-size: 13px; color: var(--fg-3); }
.device__meta .mono { font-size: 12px; }
.device__where { display: flex; align-items: flex-start; gap: 6px; margin: 8px 0 0; font-size: 13px; color: var(--fg-2); }
.device__where .ico { margin-top: 2px; color: var(--fg-3); }
/* the device's live view (owner 2026-10-10; RAM only, refreshed by devices.js) and its monthly total */
.device__live { margin: 12px 0 0; padding: 12px 14px; border: 1px solid var(--rule); border-radius: 12px; background: var(--bg); }
.device__live[data-connected="1"] { border-color: var(--ok-line); background: linear-gradient(180deg, var(--ok-bg), transparent 70%), var(--bg); }
.device__live [hidden] { display: none !important; }
.device__live-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0; font-size: 13.5px; font-weight: 500; color: var(--fg); }
.device__live .device__live-facts { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0 20px; margin: 10px 0 0; }
@media (min-width: 640px) { .device__live .device__live-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.device__top .pill { white-space: normal; max-width: 100%; }
.device__live-facts .ov-fact { padding: 8px 0 0; border-top: 0; }
.device__live-facts .ov-fact dd { font-size: 14px; }
.device__live-note { margin: 8px 0 0; font-size: 12.5px; }
.device__live-refresh { margin-inline-start: 6px; }
.device__edit { flex: 1 1 100%; min-width: 0; margin-top: 14px; }
.device__edit > summary { list-style: none; }
.device__edit > summary::-webkit-details-marker { display: none; }
.device__edit[open] > summary { border-color: var(--accent-line); color: var(--fg); background: var(--raised); }
.device__panel { display: grid; gap: 18px; margin-top: 14px; padding: 18px; border: 1px solid var(--rule); border-radius: var(--r-card); background: var(--bg); }
.device__form { display: grid; gap: 6px; margin: 0; }
.device__form + .device__form, .device__hint + .device__form { padding-top: 18px; border-top: 1px solid var(--rule); }
.device__form p { margin: 0; }
.device__form > button { justify-self: start; margin-top: 6px; }
.device__form--danger { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.device__form--danger > button { margin-top: 0; }
.inline-field { display: flex; gap: 8px; max-width: 460px; }
.inline-field input { flex: 1; min-width: 0; }
/* Devices → Allowed sites (migration 021): one row per site, Remove on the right */
.allow-list { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 0; }
.allow-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--rule); min-width: 0; }
.allow-list li > span { overflow-wrap: anywhere; min-width: 0; }
.allow-list form.inline { margin: 0; flex: none; }
.device__form fieldset { margin: 0; padding: 10px 14px 12px; }
.device__form fieldset .check { display: block; margin: 4px 0; }
.device__hint { display: flex; gap: 8px; align-items: flex-start; margin: 0; font-size: 13.5px; color: var(--fg-2); }
.device__hint .ico { margin-top: 2px; color: var(--fg-3); }
@media (min-width: 640px) {
  .device__body { padding-inline-end: 112px; }
  .device__edit > summary { position: absolute; top: 18px; inset-inline-end: 0; }
  .device__edit { margin-top: 0; }
  .device__panel { margin-top: 16px; margin-inline-start: 54px; }
}
.dv-empty { margin: 6px 0 0; border: 1px dashed var(--rule-strong); border-radius: var(--r-card); }
.dv-panel > .page-note { margin-top: 18px; }

/* panels with a sentence under the title (Add a device, Server details, Multi-hop) */
.ov-panel__head--desc { align-items: flex-start; }
.ov-panel__desc { margin: 6px 0 0; max-width: 72ch; color: var(--fg-3); font-size: 13.5px; line-height: 1.5; }
.ov-panel .tablewrap { margin: 14px -12px 0; padding: 0; border: 0; border-radius: 0; background: transparent; }
.ov-panel .disclosure { margin: 0 0 14px; }
[data-testid="server-details"] > .hint { margin: 0 0 12px; }
.sd-city { font-weight: 600; color: var(--fg); }
.table .ov-fast { margin-inline-start: 6px; }
/* Multi-hop: the route in one line (you → entry → exit → internet) */
.hop { display: flex; align-items: center; gap: 8px; margin: 0 0 18px; font-size: 12.5px; font-weight: 500; color: var(--fg-3); }
.hop__node { display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 5px 10px; border: 1px solid var(--rule-strong); border-radius: 99px; white-space: nowrap; }
.hop__node--on { border-color: var(--accent-line); color: var(--fg); }
.hop__node--on .ico { color: var(--accent); }
.hop__line { flex: 1 1 16px; min-width: 8px; height: 1px; background: repeating-linear-gradient(90deg, var(--rule-hover) 0 4px, transparent 4px 8px); }
@media (max-width: 479.98px) { .hop__node .ico { display: none; } .hop { gap: 4px; } .hop__node { padding: 4px 8px; } }

/* empty state (AnonyChat's EmptyState + the family's line illustration) */
.empty-state { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 40px 24px 44px; }
.empty-state--compact { padding: 24px 16px; }
.empty-state .art { width: 200px; height: 150px; margin: 0 0 16px; }
.empty-state__title { margin: 0; font-size: 17px; }
.empty-state__body { margin: 8px 0 0; max-width: 44ch; color: var(--fg-2); font-size: 14px; line-height: 1.5; }
.empty-state__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 20px; }

/* [AnonyVPN static/app.css 679-750] */
/* ---- Plan (design A): the current plan (the membership card beside its timeline and the devices in use), the plans
   side by side as panels, the orders and what we keep. ---- */
.plan-now { margin: 0 0 8px; padding: 18px 16px; }
@media (min-width: 640px) { .plan-now { padding: 20px 22px 22px; } }
.plan-now__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
.plan-now__side { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.plan-now__side > * { margin: 0; }
.plan-now__side .ov-next { margin: 0 0 6px; }
.plan-now__queue .hint { margin-top: 8px; }
.plan-now__label { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-size: 12.5px; color: var(--fg-3); }
.plan-now__devices .ov-cap { margin: 0; }
.plan-now__side .plan-now__feats { margin: 0; padding-top: 14px; }
.done__lead { margin: 0 0 8px; }
.done .actions { margin: 18px 0 0; }
.plan-now__note { display: flex; gap: 8px; align-items: flex-start; padding-top: 14px; border-top: 1px solid var(--rule); font-size: 13px; color: var(--fg-2); }
.plan-now__note .ico { margin-top: 2px; color: var(--accent); }
@media (min-width: 768px) {
  .plan-now__grid { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 32px; align-items: start; }
  .plan-now__grid > .ov-member { min-height: 180px; }
}
.plans-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin: 0 0 12px; }
@media (min-width: 720px) { .plans-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; } }
.plan-card { position: relative; display: flex; flex-direction: column; min-width: 0; padding: 20px 22px 22px; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-card); }
.plan-card.is-current { border-color: var(--accent-line); background: radial-gradient(90% 60% at 100% 0%, var(--accent-glow), transparent 70%), var(--surface); }
.plan-card__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
.plan-card__head h2 { margin: 0; font: 600 15px/1.2 var(--ui); letter-spacing: -0.01em; }
.plan-card__price { margin: 14px 0 16px; font: 600 32px/1.05 var(--ui); letter-spacing: -0.03em; color: var(--fg); }
.plan-card__net { display: block; margin-top: 6px; font: 400 12.5px/1.3 var(--ui); letter-spacing: 0; color: var(--fg-3); }
.vat-note { margin: 10px 0 0; }
.plan-card__rows { margin: 0 0 auto; }
.plan-card__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 0; border-top: 1px solid var(--rule); }
/* label and value may break inside a word, never below one character (pt-PT "Todas as funcionalidades" at 320 px ran out of the card) */
.plan-card__row > * { overflow-wrap: anywhere; }
.plan-card__row dt { display: flex; align-items: center; gap: 10px; color: var(--fg-2); font-size: 13.5px; }
.plan-card__row dt .ico { color: var(--fg-3); }
.plan-card__row dd { margin: 0; text-align: end; font-weight: 600; font-size: 13.5px; color: var(--fg); }
.plan-card .yes { color: var(--ok); }
.plan-card .no { color: var(--fg-3); }
.plan-card__foot { margin: 16px 0 0; padding: 12px 14px; border-radius: var(--r-control); background: var(--note-bg); color: var(--fg-2); font-size: 13.5px; }
.plan-card__foot--current { display: flex; align-items: center; gap: 8px; background: var(--accent-soft); color: var(--fg-soft); }
.plan-card__foot--current .ico { color: var(--accent); }
.plan-card__note { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0 0; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--note-bg); }
.plan-card__note > .ico { margin-top: 2px; color: var(--fg-3); }
.plan-card__note .plan-card__foot { margin: 0; padding: 0; background: none; line-height: 1.5; }
.plan-card__note a { color: var(--fg); }
.buy .buy__go { width: 100%; }
.facts-list { list-style: none; margin: 0; padding: 0; }
.facts-list li { position: relative; padding: 0 0 10px; padding-inline-start: 24px; color: var(--fg-2); font-size: 13.5px; }
.facts-list li:last-child { padding-bottom: 0; }
.facts-list li::before { content: ""; position: absolute; inset-inline-start: 3px; top: 0.5em; width: 9px; height: 5px; border-left: 1.6px solid var(--accent); border-bottom: 1.6px solid var(--accent); transform: rotate(-45deg); }
.facts-list a { color: var(--fg-2); }
/* the checkout: the order (membership card + what you agree to) beside the price and the consent */
.kv-rows { margin: 16px 0 0; }
.kv-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 16px; padding: 12px 0; border-top: 1px solid var(--rule); }
.kv-row:first-child { border-top: 0; }
.kv-row dt { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg-3); }
.kv-row dd { margin: 0; font-size: 14px; color: var(--fg-soft); }
.kv-row dd strong { color: var(--fg); }
@media (min-width: 640px) { .kv-row { grid-template-columns: 140px minmax(0, 1fr); align-items: baseline; } }
.co-price { margin: 0; }
.co-price strong { font: 600 44px/1 var(--ui); letter-spacing: -0.035em; color: var(--fg); }
.co-sats { margin: 10px 0 18px; font-size: 14px; color: var(--fg-2); }
.co-sats strong { color: var(--fg); font-weight: 600; }
.co-sats .hint { display: block; margin-top: 2px; }
/* the VAT quote before the invoice (owner 2026-10-15): price excl. VAT, VAT (rate, country), total */
.co-vat { margin: 0 0 14px; padding: 0; display: grid; gap: 4px; font-size: 14px; color: var(--fg-2); }
.co-vat__row { display: flex; justify-content: space-between; gap: 12px; margin: 0; }
.co-vat__row dt, .co-vat__row dd { margin: 0; }
.co-vat__total { padding-top: 6px; border-top: 1px solid var(--rule); color: var(--fg); font-weight: 600; }
.co-form { display: grid; gap: 12px; margin: 0; padding-top: 16px; border-top: 1px solid var(--rule); }
.co-form .consent { margin: 0; }
.co-form .hint { margin: 0; }
/* [AnonyVPN static/app.css 756-772] */
/* the order page */
.done__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
@media (min-width: 768px) { .done__grid { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 32px; align-items: start; } }
.order-state__body { display: flex; align-items: flex-start; gap: 14px; }
.order-state__body p { margin: 8px 0 0; color: var(--fg-soft); }
.order-state__icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-control); background: var(--raised); color: var(--fg-2); }
.order-state--ok .order-state__icon { color: var(--ok); }
.order-state--warn .order-state__icon { color: var(--warn); background: var(--warn-bg); }
.order-state--danger .order-state__icon { color: var(--danger); background: var(--danger-bg); }
.order-state--info .order-state__icon { color: var(--info); }
.order-state .actions { margin: 18px 0 0; }
.order-status .ov-dot--wait { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); animation: ov-halo-wait 2.4s ease-out infinite; }
@keyframes ov-halo-wait { 0% { box-shadow: 0 0 0 0 rgba(243, 242, 237, 0.45); } 70%, 100% { box-shadow: 0 0 0 7px rgba(243, 242, 237, 0); } }
@media (prefers-reduced-motion: reduce) { .order-status .ov-dot--wait { animation: none; } }
.invoice-panel .invoice__amount strong { font: 600 34px/1.1 var(--ui); letter-spacing: -0.03em; }
.invoice-panel .invoice__main > p { margin-bottom: 12px; }

/* [AnonyVPN static/app.css 773-794] */
/* ---- Settings → Account (design A): the same panels as Overview; rows inside separated by rules ---- */
.settings-content { max-width: 1040px; }
.group__card { padding: 0; overflow: hidden; margin: 0; }
.group__row { display: flex; align-items: flex-start; gap: 14px; padding: 14px 0; border-top: 1px solid var(--rule); }
.ov-panel__head + .group__row { padding-top: 0; border-top: 0; }
.group__row--action { flex-wrap: wrap; align-items: center; justify-content: space-between; }
.group__icon { align-self: flex-start; flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r-control); background: var(--raised); color: var(--fg-2); }
.group__icon .ico { width: 18px; height: 18px; }
.group__text { flex: 1 1 16rem; min-width: 0; }
.group__lead { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--fg); }
.group__lead .pill { margin-inline-start: 6px; }
.group__lead .anonyid-pill { margin: 0 0.1em; }
.group__text .hint a { color: var(--fg-2); }
.group__links { display: flex; flex-direction: column; }
.group__link { display: flex; align-items: center; gap: 12px; min-height: 48px; border-top: 1px solid var(--rule); color: var(--fg-soft); font-size: 14px; text-decoration: none; transition: color 150ms; }
.group__link:first-child { border-top: 0; }
.group__link .ico { color: var(--fg-3); }
.group__link:hover { color: var(--fg); }
.group__link:hover .chev { color: var(--accent); }
.group__cap { margin: 16px 0 0; }
.anonyid-pill { display: inline-block; vertical-align: middle; margin: 0 0.2em; }

/* [AnonyVPN static/app.css 801-811] */
/* ---- Overview (the home after sign-in, owner 2026-10-10; design direction A "Nightside", approved 2026-10-10 with the
   app's own shell and colours): a hero (what is connected right now, on a globe turned to face it), then uneven panels
   on a 12-column grid from 1024 px (Devices 7 + Plan 5, Locations 5 + Orders 7, Account 7 + Apps 5), one column below.
   Orange = the brand (pins, the plan, the one primary action); green / red = data states only. ---- */
.ov-muted { color: var(--fg-3); }
.ov-show-s { display: none; }
.ov-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--fg-3); }
.ov-dot--ok { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-halo); }
.ov-dot--pulse { animation: ov-halo 2.4s ease-out infinite; }
@keyframes ov-halo { 0% { box-shadow: 0 0 0 0 rgba(60, 232, 160, 0.45); } 70%, 100% { box-shadow: 0 0 0 7px rgba(60, 232, 160, 0); } }

/* [AnonyVPN static/app.css 901-924] */
/* the panels */
.ov-bento { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
@media (min-width: 1024px) {
  .ov-bento { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 16px; }
  .ov-span-5 { grid-column: span 5; }
  .ov-span-7 { grid-column: span 7; }
  .ov-span-12 { grid-column: 1 / -1; }
}
.ov-bento > .card { margin: 0; padding: 18px 16px; }
@media (min-width: 640px) { .ov-bento > .card { padding: 20px 22px 22px; } }
.ov-panel__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 28px; margin: 0 0 16px; }
.ov-panel .ov-panel__head h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0; font: 600 15px/1.2 var(--ui); letter-spacing: -0.01em; }
/* the title gives way to the link (flex: none) instead of pushing it out of the panel (fr "Tous les emplacements" at
   320 px); it only shrinks below its longest word where it ran out before */
.ov-panel .ov-panel__head h2, .ov-panel .ov-panel__head h2 > * { min-width: 0; overflow-wrap: anywhere; }
.ov-panel__count { font-size: 13px; font-weight: 500; letter-spacing: 0; color: var(--fg-3); }
.ov-link { display: inline-flex; flex: none; align-items: center; gap: 2px; margin-inline-end: -4px; padding: 4px; padding-inline-start: 8px; border-radius: var(--r-chip); color: var(--fg-2); font-size: 13px; font-weight: 500; text-decoration: none; }
.ov-link:hover { background: var(--raised); color: var(--fg); }
.ov-panel__foot { display: flex; gap: 10px; margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--rule); color: var(--fg-3); font-size: 13px; line-height: 1.5; }
.ov-panel__foot .ico { margin-top: 1px; }
.ov-panel__foot a, .ov-panel .hint a { color: var(--fg-2); }
.ov-panel .page-note { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--rule); font-size: 13px; }
.ov-empty { margin: 14px 0 0; color: var(--fg-3); font-size: 14px; }

/* [AnonyVPN static/app.css 964-1001] */
/* Plan: the membership card, the timeline, what the plan includes */
.ov-member {
  position: relative; display: flex; flex-direction: column; min-height: 156px; overflow: hidden; padding: 18px 20px; border: 1px solid var(--rule-strong); border-radius: var(--r-card);
  background:
    radial-gradient(120% 140% at 100% 100%, rgba(243, 242, 237, 0.32), rgba(243, 242, 237, 0.08) 38%, transparent 62%),
    linear-gradient(115deg, transparent 35%, rgba(243, 242, 237, 0.05) 48%, transparent 62%),
    linear-gradient(160deg, var(--raised), var(--surface) 70%);
}
.ov-member::before { content: ""; position: absolute; inset: 0; opacity: 0.5; background: repeating-radial-gradient(circle at 115% 130%, transparent 0 9px, rgba(243, 242, 237, 0.035) 9px 10px); }
.ov-member--free { background: linear-gradient(115deg, transparent 35%, rgba(243, 242, 237, 0.04) 48%, transparent 62%), linear-gradient(160deg, var(--raised), var(--surface) 70%); }
.ov-member > * { position: relative; }
.ov-member__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ov-member__mark { display: block; width: 26px; height: 26px; }
.ov-member__kind { font-size: 12px; font-weight: 500; color: var(--fg-2); }
.ov-member__name { margin: auto 0 0; padding-top: 22px; font: 600 30px/1 var(--ui); letter-spacing: -0.03em; color: var(--fg); overflow-wrap: anywhere; }
.ov-member__until { margin: 8px 0 0; font-size: 13px; color: var(--fg-2); }
.ov-member__until strong { color: var(--fg); }
.ov-next { display: flex; align-items: flex-start; gap: 8px; margin: 16px 0 0; font-size: 13px; color: var(--fg-2); }
.ov-next .ico { margin-top: 1px; color: var(--fg-3); }
.ov-next strong { color: var(--fg); }
.ov-next .tabnum { white-space: nowrap; }
.ov-tl { margin: 12px 0 0; }
.ov-tl__bar { display: block; overflow: visible; color: var(--accent); }
.ov-tl__track { fill: var(--raised); }
.ov-tl__hatch-a { fill: rgba(243, 242, 237, 0.2); }
.ov-tl__hatch-b { fill: rgba(243, 242, 237, 0.42); }
.ov-tl__today { fill: var(--fg); stroke: var(--surface); stroke-width: 2px; paint-order: stroke; }
.ov-tl__ticks { display: flex; justify-content: space-between; gap: 12px; margin: 6px 0 0; font-size: 12px; color: var(--fg-3); }
.ov-usage { margin: 16px 0 0; }
.ov-usage__top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; margin: 0; font-size: 13.5px; color: var(--fg-2); }
.ov-usage__top strong { color: var(--fg); }
.ov-feats { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; margin: 18px 0 0; padding: 16px 0 0; border-top: 1px solid var(--rule); }
.ov-feats li { display: flex; align-items: flex-start; gap: 10px; min-width: 0; font-size: 13px; color: var(--fg); }
/* the text may shrink below its longest word (a flex item keeps min-width: auto otherwise): de "Keine
   Geschwindigkeitsbegrenzung" ran out of the box in Safari, which does not hyphenate capitalised words */
.ov-feats li > span { min-width: 0; overflow-wrap: anywhere; }
.ov-feats .ico { margin-top: 1px; color: var(--accent); }

/* [AnonyVPN static/app.css 1016-1049] */
/* Recent orders */
.ov-otable { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.ov-otable th { padding: 0 0 8px; border-bottom: 1px solid var(--rule); text-align: start; font-size: 12px; font-weight: 500; color: var(--fg-3); }
.ov-otable td { padding: 12px 0; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.ov-otable tr:last-child td { border-bottom: 0; padding-bottom: 0; }
.ov-otable th + th, .ov-otable td + td { padding-inline-start: 14px; }
.ov-otable .ov-r { text-align: end; }
.ov-order__date { color: var(--fg); font-weight: 500; text-decoration: none; }
.ov-order__date:hover { text-decoration: underline; }
.ov-order__sub { display: block; margin-top: 2px; font-size: 12px; color: var(--fg-3); white-space: nowrap; }
.ov-otable .ov-show-s { display: none; }
.ov-otable td:nth-child(2) { white-space: nowrap; }
.ov-otable .pill { white-space: normal; }

/* Account, Apps */
.ov-line { margin: 0; font-size: 15px; font-weight: 600; color: var(--fg); }
.ov-line .anonyid-pill { margin: 0 0.1em; }
.ov-text { margin: 8px 0 0; max-width: 60ch; font-size: 13.5px; color: var(--fg-2); }
.ov-restriction { margin: 14px 0 0; }
.ov-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 18px; }
.ov-actions + .hint { margin-top: 12px; }
.ov-apps { list-style: none; margin: 0; padding: 0; }
.ov-apps li { display: flex; align-items: center; gap: 12px; min-height: 46px; border-top: 1px solid var(--rule); }
.ov-apps li:first-child { border-top: 0; }
.ov-apps .ico { color: var(--fg-2); }
.ov-apps__name { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; flex: 1; font-weight: 500; }
.ov-apps + .hint { margin-top: 10px; }
.ov-privacy { margin: 24px 0 0; }

@media (max-width: 639.98px) {
  .ov-hide-s { display: none; }
  .ov-show-s, .ov-otable .ov-show-s { display: block; }
}

/* [AnonyVPN static/app.css 1082-1089] */
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 20px; max-width: 760px; }
.form-grid > label { margin-top: 10px; }
@media (min-width: 900px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid > .span-2 { grid-column: 1 / -1; }
}
.form-grid .f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.form-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 16px; }
/* [AnonyVPN static/app.css 1313-1341] */
/* ---- plans with durations + Lightning checkout (src/views/plan.ts, src/routes/admin-plans.ts) ---------------------- */
.plan-card__desc { margin: 6px 0 0; color: var(--fg-2); font-size: 14px; }
.buy { margin: 16px 0 0; }
.durations { display: flex; flex-direction: column; gap: 8px; margin: 0 0 12px; padding: 0; border: 0; min-width: 0; }
.duration { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--rule-strong); border-radius: var(--r-control); cursor: pointer; }
.duration:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.duration__len { flex: 1 1 auto; color: var(--fg); font-weight: 600; font-size: 14px; }
.duration__price { display: flex; flex-direction: column; align-items: flex-end; font-weight: 600; font-variant-numeric: tabular-nums; }
.duration__price .sub { font-weight: 400; font-size: 12.5px; color: var(--fg-3); }
.buy .hint { margin: 8px 0 0; font-size: 13px; }
.schedule .plain { margin: 0 0 8px; }
.consent { margin: 8px 0; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--note-bg); color: var(--fg-soft); font-size: 14px; line-height: 1.5; white-space: pre-line; }
.invoice { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
@media (min-width: 720px) { .invoice { grid-template-columns: 260px minmax(0, 1fr); align-items: start; } }
.invoice__qr a { display: block; max-width: 260px; margin: 0 auto; border-radius: var(--r-control); overflow: hidden; }
.invoice__qr .qr { display: block; width: 100%; height: auto; }
.invoice__amount { margin: 0 0 6px; font-size: 22px; color: var(--fg); }
.invoice__text { width: 100%; min-height: 96px; word-break: break-all; resize: vertical; }
.order-status { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; color: var(--fg-2); font-size: 14px; }
.done__lead { display: flex; align-items: flex-start; gap: 10px; font-size: 17px; color: var(--fg); }
.done__lead .ico { color: var(--ok); flex: none; margin-top: 3px; }
.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin: 0 0 16px; }
.filters label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--fg-3); }
.filters input, .filters select { width: auto; min-height: 36px; padding: 6px 8px; font-size: 13px; }
select.small-select { width: auto; min-height: 36px; padding: 6px 8px; font-size: 13px; }
.num-input { width: 90px; min-height: 36px; padding: 6px 8px; font-size: 14px; }
.durations-admin { border: 0; padding: 0; margin: 0; min-width: 0; }
.durations-admin legend { margin: 0 0 8px; color: var(--fg-2); font-size: 14px; }

/* [AnonyVPN static/app.css 1136-1140] */
@font-face { font-family: "Archivo Black"; src: url("/static/fonts/archivo-black-latin.woff2?v=1") format("woff2"); font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Black"; src: url("/static/fonts/archivo-black-latin-ext.woff2?v=1") format("woff2"); font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Archivo Black Fallback"; src: local("Arial"); ascent-override: 70.78%; descent-override: 16.93%; line-gap-override: 0%; size-adjust: 124.05%; }
/* [AnonyVPN static/app.css 1342-1363] */
/* ---- dropdowns: anony-select (static/anony-select/, vendored from /root/anony-design select/; owner 2026-10-11 "all
   dropdowns across ALL sites" like AnonyChat's). Every <select data-anony-select> gets AnonyChat's trigger + panel (flags,
   search past 12 options, a bottom sheet below 640 px); the native select stays in the form. Its tokens -> ours: the
   trigger is drawn like our inputs above (field ground, rule-strong edge, 16 px, 44 px), the panel is the overlay card. */
:root {
  --as-text: var(--fg); --as-text-soft: var(--fg-soft); --as-text-muted: var(--fg-2); --as-text-faint: var(--fg-3);
  --as-placeholder: var(--placeholder); --as-accent: var(--accent); --as-danger: var(--danger);
  --as-font-size: 16px; --as-line-height: 1.3;
  --as-trigger-bg: var(--field); --as-trigger-border: var(--rule-strong); --as-trigger-border-hover: var(--rule-hover);
  --as-trigger-radius: var(--r-control); --as-trigger-height: 44px; --as-trigger-padding: 11px 12px;
  --as-panel-bg: var(--overlay); --as-panel-border: var(--rule-strong); --as-panel-radius: var(--r-card);
  --as-panel-shadow: var(--shadow-overlay); --as-row-active: #24282b; --as-divider: var(--rule); --as-flag-ring: var(--rule);
  --as-scrim: rgb(21 23 25 / 0.8);
}
/* compact: the admin filter row and the per-user plan picker (36 px, 13 px, as .filters input / input.date) */
.filters .anony-select, .anony-select:has(> select.small-select) {
  --as-trigger-height: 36px; --as-trigger-padding: 6px 8px 6px 10px; --as-font-size: 13px; --as-row-height: 36px; --as-trigger-gap: 6px;
}
.filters .anony-select { min-width: 120px; }
.row > .anony-select { flex: 0 1 140px; min-width: 80px; }
.newconf__switch .anony-select { max-width: 320px; }

/* [AnonyVPN static/app.css 1364-1481] */
/* ---- legal pages (src/views/legal.ts) ---- */
.legal .meta { color: var(--fg-3); font-size: 14px; font-variant-numeric: tabular-nums; }
.legal p, .legal dd { color: var(--fg-2); }
.legal ol { padding-inline-start: 22px; color: var(--fg-2); }
.legal-facts, .legal-defs { margin: 0 0 1em; }
.legal-facts { display: grid; grid-template-columns: minmax(120px, 200px) 1fr; gap: 8px 16px; }
.legal-facts dt { color: var(--fg-3); font-size: 14px; }
.legal-facts dd { margin: 0; }
.legal-defs dt { font-weight: 600; color: var(--fg); margin-top: 12px; }
.legal-defs dd { margin: 4px 0 0; }
@media (max-width: 560px) { .legal-facts { grid-template-columns: 1fr; gap: 2px; } .legal-facts dd { margin-bottom: 10px; } }
.table-scroll { overflow-x: auto; margin: 0 0 1em; border: 1px solid var(--rule); border-radius: var(--r-control); }
.legal-table { min-width: 640px; font-size: 14px; }
.legal-table td { color: var(--fg-2); }
.gap { color: var(--warn); background: var(--warn-bg); border-radius: 4px; padding: 0 3px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.legal .quote { margin: 0 0 1em; padding: 10px 14px; border-inline-start: 3px solid var(--accent); background: var(--surface); color: var(--fg-soft); }
.legal .model-form { margin: 0 0 1em; padding: 10px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); }
.legal .model-form summary { cursor: pointer; color: var(--fg); }
.legal .changes li { font-size: 14px; }
/* The legal nav (AnonyChat's legal-nav.tsx): the legal centre and every document above the text, the current one marked;
   one row that scrolls sideways on a phone (inside the page's gutter, so the page never does), wrapping from 1024 px. */
.legal-nav { margin: 0 -8px 24px; overflow-x: auto; scrollbar-width: none; }
.legal-nav::-webkit-scrollbar { display: none; }
.legal-nav ul { display: flex; width: max-content; gap: 4px; list-style: none; margin: 0; padding: 0 8px; }
.legal-nav li { margin: 0; }
.legal-nav a {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 12px; border-radius: var(--r-control); white-space: nowrap;
  font-size: 14px; color: var(--fg-3); text-decoration: none; transition: color 150ms, background-color 150ms;
}
.legal-nav a:hover { color: var(--fg); }
.legal-nav a[aria-current="page"] { background: var(--raised); color: var(--fg); font-weight: 600; }
@media (min-width: 1024px) { .legal-nav ul { width: auto; flex-wrap: wrap; } }
/* The legal centre (/legal): AnonyChat's hub — one card per document, the title with its version, one line about it. */
.legal-hub { display: grid; gap: 10px; list-style: none; margin: 24px 0 0; padding: 0; }
.legal-hub li { margin: 0; }
.legal-hub__item {
  display: block; padding: 16px 20px; border: 1px solid var(--rule); border-radius: var(--r-card); background: var(--surface);
  text-decoration: none; transition: border-color 150ms;
}
.legal-hub__item:hover { border-color: var(--accent-line); }
.legal-hub__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.legal-hub__title { font-weight: 600; color: var(--fg); }
.legal-hub__version { flex: none; font-size: 13px; color: var(--fg-3); font-variant-numeric: tabular-nums; }
.legal-hub__desc { display: block; margin-top: 4px; font-size: 14px; line-height: 1.5; color: var(--fg-2); }

/* ======================================================================================================================
   DISPLAY FONT + LEGAL TABLE OF CONTENTS (owner 2026-10-13, branch feat/display-font-legal-toc). Kept in this one
   section on purpose (the shared footer work changes other parts of this file).
   1. The landing tagline's face — Archivo Black, upper case, tight tracking (.tagline) — for the signed-in hero box's
      headline (Overview's globe box; the Locations globe box is the same component) and the legal pages' headings
      (h1, h2). Archivo Black covers Latin + Latin Extended only, so in Greek / Cyrillic and in Arabic, Devanagari and
      CJK the same headings use the system's own face at weight 800 instead (one face per heading — never Archivo's
      Latin letters mixed with a fallback; no tracking where it breaks the script; upper case where the script has it),
      as anonymail.app's landing sets its tagline in those languages. The legal articles are English (lang="en"), so
      their headings are always Archivo Black.
   2. The legal pages' table of contents (src/views/legal-toc.ts, AnonyChat's legal-toc.tsx): from 1100 px a sticky
      column beside the text ("On this page"), below it the collapsible "Contents" block at the top of the article.
   ==================================================================================================================== */
.ov-hero .ov-hero__title, .legal h1, .legal h2 {
  font-family: var(--display); font-weight: 400; text-transform: uppercase; font-feature-settings: "kern"; text-wrap: balance;
}
.ov-hero .ov-hero__title {
  margin-top: 14px; font-size: 30px; line-height: 1; letter-spacing: -0.04em;
  background: none; -webkit-background-clip: border-box; background-clip: border-box; color: var(--fg);
}
.ov-hero .ov-hero__copy--long .ov-hero__title { font-size: 25px; line-height: 1.04; }
@media (min-width: 1112px) {
  .ov-hero .ov-hero__title { font-size: 46px; margin-top: 16px; }
  .ov-hero .ov-hero__copy--long .ov-hero__title { font-size: 36px; }
}
.legal h1 { margin: 0 0 14px; font-size: clamp(30px, 4.4vw, 46px); line-height: 1; letter-spacing: -0.04em; }
.legal h2 { margin: 2.2em 0 0.7em; font-size: 19px; line-height: 1.12; letter-spacing: -0.02em; }
@media (min-width: 768px) { .legal h2 { font-size: 21px; } }
.legal h2[id], .legal [id] { scroll-margin-top: 24px; }
/* the scripts Archivo Black does not cover: the system's face, bold, the same upper case where the script has one */
:is(.ov-hero .ov-hero__title, .legal h1, .legal h2):is(:lang(el), :lang(ru), :lang(uk)) { font-family: var(--font); font-weight: 800; letter-spacing: -0.02em; }
:is(.ov-hero .ov-hero__title, .legal h1, .legal h2):is(:lang(ar), :lang(hi), :lang(ja), :lang(ko), :lang(zh)) {
  font-family: var(--font); font-weight: 800; letter-spacing: 0; line-height: 1.2; text-transform: none;
}
.ov-hero .ov-hero__title:lang(ja) { word-break: auto-phrase; } /* Chromium: break between phrases, not inside a word */

/* the layout: the text column (as before: at most 760 px of page) and, from 1100 px, the contents beside it */
.legal-layout > .legal { min-width: 0; }
.legal-lang + .legal-layout { margin-top: 28px; } /* clear of the "English only" note */
.legal-aside { display: none; }
@media (max-width: 1099.98px) { .main--wide:has(> .legal-layout) { max-width: 760px; } }
@media (min-width: 1100px) {
  .legal-layout { display: grid; grid-template-columns: minmax(0, 720px) 236px; justify-content: space-between; align-items: start; gap: 56px; }
  .legal-aside { display: block; position: sticky; top: 24px; }
  .ltoc--inline { display: none; }
}
.ltoc .ltoc__list { margin: 0; padding: 0; list-style: none; } /* (beats .legal ol / .legal li inside the article) */
.ltoc .ltoc__list li { margin: 0; }
.ltoc__link {
  display: block; padding: 7px 10px; border-radius: var(--r-chip); font-size: 13.5px; line-height: 1.35; color: var(--fg-3); text-decoration: none;
  transition: color 150ms, background-color 150ms;
}
.ltoc__link:hover { color: var(--fg); background: var(--surface); }
.ltoc__link[aria-current] { color: var(--fg); background: var(--surface); font-weight: 600; box-shadow: inset 2px 0 0 var(--accent); }
/* the side column: its own scroll when the list is taller than the window */
.ltoc--side { max-height: calc(100vh - 48px); overflow-y: auto; overscroll-behavior: contain; padding-bottom: 8px; scrollbar-width: thin; }
.ltoc__h { margin: 0; padding: 0 10px 10px; font: 400 11px/1.4 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-3); }
/* phones and tablets: a closed "Contents" block at the top of the article (a <details>: no JavaScript needed) */
.ltoc--inline { margin: 20px 0 8px; border: 1px solid var(--rule); border-radius: var(--r-control); background: var(--surface); }
.ltoc__sum {
  display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 14px; cursor: pointer; list-style: none; user-select: none;
  font-size: 15px; font-weight: 500; color: var(--fg-soft); border-radius: var(--r-control);
}
.ltoc__sum::-webkit-details-marker { display: none; }
.ltoc__ico, .ltoc__chev { width: 18px; height: 18px; flex: none; color: var(--fg-3); }
.ltoc__chev { margin-inline-start: auto; transition: transform 150ms var(--ease); }
.ltoc--inline[open] .ltoc__chev { transform: rotate(180deg); }
.ltoc--inline nav { padding: 6px; border-top: 1px solid var(--rule); }
:is(.ltoc__h, .ltoc__sum):is(:lang(ar), :lang(hi), :lang(ja), :lang(ko), :lang(zh), :lang(el), :lang(ru), :lang(uk)) { letter-spacing: 0; }
.ltoc__h:is(:lang(ar), :lang(hi), :lang(ja), :lang(ko), :lang(zh), :lang(el), :lang(ru), :lang(uk)) { font-family: var(--font); font-size: 12.5px; font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .ltoc__chev, .ltoc__link { transition: none; } }
@media print { .legal-aside, .ltoc--inline { display: none; } }
/* ==== end DISPLAY FONT + LEGAL TABLE OF CONTENTS ==== */
/* [AnonyVPN static/app.css 1484-1486] */
.biz-form, .biz { margin-top: 14px; }
.biz-form > .form-grid { margin-top: 10px; }

/* [AnonyVPN static/app.css 1665-1667] */
/* the skip link (as AnonyMail): first in the page, shown on keyboard focus */
.skip { position: absolute; inset-inline-start: 12px; top: -60px; z-index: 60; padding: 10px 14px; border-radius: var(--r-control); background: var(--overlay); color: var(--fg); }
.skip:focus { top: 12px; }
/* [AnonyVPN static/app.css 1670-1755] */
/* ---- The account chip (owner 2026-10-12, AnonyMail's of 2026-10-11; src/views/account.ts): avatar (the initial on a
   tinted circle), the AnonyID display name, the AnonyID glyph (mark only). Rail: pinned below Settings; compact = the
   avatar with the glyph on its corner, labelled = avatar, name, glyph. Settings list (< 1280 px): a 64 px row on top.
   Settings → Account and the Overview's Account panel: the panel size. Signed out: the glyph on a graphite disc +
   "Sign in". ---- */
.acct__avatar {
  flex: none; display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  font: 600 13px/1 var(--ui); letter-spacing: 0; text-transform: uppercase; background: var(--raised); color: var(--fg-2);
  box-shadow: inset 0 0 0 1px rgba(243, 242, 237, 0.08);
}
.acct__avatar .ico { width: 60%; height: 60%; }
.acct__avatar--row { width: 36px; height: 36px; font-size: 15px; }
.acct__avatar--panel { width: 44px; height: 44px; font-size: 18px; }
.acct__avatar--gate { width: 24px; height: 24px; font-size: 11px; }
.acct__tint-0 { background: #1c2937; color: #8cc4ff; }
.acct__tint-1 { background: #2a2440; color: #c9b8ff; }
.acct__tint-2 { background: #163027; color: #6fe3b4; }
.acct__tint-3 { background: #322a17; color: #f2cf66; }
.acct__tint-4 { background: #35202a; color: #ffa3b8; }
.acct__tint-5 { background: #163036; color: #73d6e3; }
.acct__glyph { flex: none; width: 16px; height: 16px; margin-inline-start: 6px; vertical-align: -2px; }
.acct__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg); font-weight: 600; }
/* rail */
.rail__rule { height: 1px; margin: 6px 4px; background: var(--rule); flex: none; }
.acct--rail { min-height: 48px; }
.acct__face { position: relative; flex: none; display: inline-grid; }
.acct__badge {
  position: absolute; inset-inline-end: -4px; bottom: -3px; display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%;
  background: var(--bg); box-shadow: 0 0 0 1px var(--rule-strong); transition: opacity 200ms;
}
.acct__badge-glyph { width: 12px; height: 12px; }
.acct__label { display: flex; align-items: center; min-width: 0; }
.acct__label .acct__name { font: 600 14px/1.2 var(--ui); }
.acct__label .acct__glyph { margin-inline-start: 8px; }
.acct--rail[aria-current="page"]::before { display: none; }
.acct--rail[aria-current="page"] { box-shadow: inset 0 0 0 1px var(--rule-strong); }
@media (min-width: 768px) and (max-width: 1279.98px) {
  @media (hover: hover) and (pointer: fine) { .rail:hover .acct__badge { opacity: 0; transition-delay: 120ms; } }
  .rail:has(:focus-visible) .acct__badge { opacity: 0; }
}
@media (min-width: 1280px) { .rail .acct__badge { opacity: 0; } }
@media (min-width: 1280px) and (max-width: 1535.98px) {
  html.has-pane .rail .acct__badge { opacity: 1; }
  @media (hover: hover) and (pointer: fine) { html.has-pane .rail:hover .acct__badge { opacity: 0; transition-delay: 120ms; } }
  html.has-pane .rail:has(:focus-visible) .acct__badge { opacity: 0; }
}
/* the settings list's account row */
.settings-list--account { margin-bottom: 16px; }
.acct--row { min-height: 64px; }
.acct__text { flex: 1; min-width: 0; display: flex; align-items: center; }
.acct--row .acct__name { font: 600 16px/1.2 var(--ui); }
.acct--row .acct__glyph { margin: 0; margin-inline-end: 4px; }
@media (min-width: 1280px) { .settings-list--account { display: none; } }
/* Settings → Account, the Overview's Account panel */
.acct--panel { display: flex; align-items: center; gap: 14px; flex: 1; min-width: 0; }
.acct--panel .acct__text { display: block; }
.acct--panel .acct__name { display: flex; align-items: center; flex-wrap: wrap; gap: 0 6px; margin: 0 0 2px; font: 600 18px/1.25 var(--ui); white-space: normal; overflow-wrap: anywhere; }
.acct--panel .acct__name .acct__glyph { width: 18px; height: 18px; margin: 0; }
.acct--panel .hint { margin: 0; }
.ov-panel--account .acct--panel { margin-bottom: 4px; }
/* the public frame's card */
.acct--gate { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; margin: 0 0 16px; padding: 4px 0; padding-inline: 4px 10px; border: 1px solid var(--rule-strong); border-radius: 99px; background: var(--raised); }
.acct--gate .acct__name { font: 600 14px/1.2 var(--ui); }
.acct--gate .acct__glyph { margin: 0; }
/* signed out: the sign-in button (the app's .button, the landing's .lbtn) */
.button.signin, .lbtn.signin { display: inline-flex; align-items: center; gap: 10px; padding-inline-start: 8px; }
.signin__glyph { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--bg); }
.signin__glyph img { width: 20px; height: 20px; }
.lbtn.signin { gap: 8px; padding-inline-start: 8px; }
.lbtn.signin .signin__glyph { width: 26px; height: 26px; }
.lbtn.signin .signin__glyph img { width: 18px; height: 18px; }

/* ---- languages (owner 2026-10-12): the switcher, the legal pages' note, right-to-left ---------------------------- */
.settings-language { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.legal-lang { margin: 12px 0 0; padding: 10px 14px; border: 1px solid var(--rule); border-radius: var(--r-control); font-size: 13.5px; color: var(--fg-2); }
/* direction-bearing icons point the other way in right-to-left languages */
[dir="rtl"] .ico--dir { transform: scaleX(-1); }
[dir="rtl"] .ico--dir.ico--back { transform: none; }
/* Latin-only display faces: other scripts fall back to the system's (the font stacks already end in system fonts) */
:lang(ar) .tagline, :lang(hi) .tagline, :lang(ja) .tagline, :lang(ko) .tagline, :lang(zh-Hans) .tagline, :lang(el) .tagline, :lang(ru) .tagline, :lang(uk) .tagline { letter-spacing: 0; }
/* long compound words (de "Geschwindigkeitsbegrenzung") break instead of widening the page; hyphenated where the
   language has long compounds */
body { overflow-wrap: break-word; }
:lang(de), :lang(nl), :lang(da), :lang(sv), :lang(hu), :lang(el), :lang(ru), :lang(uk), :lang(pl), :lang(cs) { -webkit-hyphens: auto; hyphens: auto; hyphenate-limit-chars: 12 5 5; }
.bar__label, .rail__label, .button, .lbtn, .pill, .langsw__btn, .langsw__item { -webkit-hyphens: manual; hyphens: manual; }
:lang(ja) th, :lang(ko) th, :lang(zh-Hans) th, .ov-dhead > span { white-space: nowrap; }
/* [AnonyMail static/app.css 1165-1172] */
/* the public frame (src/views/layout.ts gatePage: "AnonyMail isn't open yet", "Sign-in failed"): AnonyVPN's public
   pages (.top / .main / .foot), in the app's type */
html.gate body { font: 400 15px/1.45 var(--ui); font-feature-settings: "kern", "calt"; }
html.gate .gate__main { max-width: 560px; padding-top: max(40px, 10vh); }
html.gate .gate__main--doc { max-width: 760px; padding-top: 32px; }
html.gate h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; margin: 0 0 10px; }
html.gate .lead { font-size: 15px; line-height: 1.5; }
.gate__card form { margin-top: 16px; }
/* [AnonyMail static/app.css 1363-1366] */
.ov-gate { max-width: 640px; padding: 28px; }
.ov-gate__icon { display: grid; place-items: center; width: 44px; height: 44px; margin: 0 0 16px; border-radius: var(--r-control); background: var(--raised); color: var(--fg-2); }
.ov-gate h1 { margin: 0 0 8px; font-size: 24px; }
.ov-gate__actions { margin: 20px 0 0; }
@media (min-width: 1100px) { html.gate .gate__main--doc { max-width: 1100px; } }  /* [AnonyMail static/app.css 1262] */

/* ==== Anony Balance additions (no sibling has these; each is the smallest change to a ported piece) ==== */
/* The rail brand: Anony Balance has no lockup of its own, so the Anony Labs lockup + the product's name as a tag — the
   admin hub's Labs rail (anony-admin static/app.css .rail__tag, verbatim). In AnonyVPN's brand slot (the compact mark
   where it sits there; the lockup group cross-fades in exactly as AnonyVPN's .rail__wordmark), the lockup at 20 px
   (AnonyVPN: 26 px) so lockup + tag fit the 240 px rail in every language. */
.rail__tag { display: inline-block; flex: none; font: 400 10.5px/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent);
  padding: 4px 6px; border: 1px solid var(--accent-line); border-radius: var(--r-chip); }
@media (min-width: 768px) {
  .rail__wordmark.rail__lockup { display: flex; align-items: center; gap: 8px; inset-inline-start: 8px; top: calc(50% - 10px); height: 20px; }
  .rail__lockup-img { display: block; height: 20px; width: auto; }
}
/* The history table (AnonyVPN's Recent orders table, .ov-otable): its second column is the description, which wraps
   (AnonyVPN's is a short plan name kept on one line); on phones it moves under the date (AnonyVPN's .ov-order__sub). */
.ov-otable td:nth-child(2).hist__what { white-space: normal; }
.ov-otable .hist__what .ov-order__sub, .hist__when .ov-order__sub { white-space: normal; }
.hist__when { white-space: nowrap; }
.hist__in { color: var(--ok); }
.hist__more { margin: 14px 0 0; }
/* The shared footer under the app's page: the page's width (AnonyVPN's app pages have no footer). */
html.app .appmain > .foot { width: 100%; }
/* The history's descriptions come from the ledger's shared text (src/views/pages.ts opText, also on Orders & receipts):
   its second line, its quiet method name and its "test" tag in the table's terms (.ov-order__sub, .ov-muted, .pill). */
.ov-otable .row__sub { display: block; margin-top: 2px; font-size: 12px; color: var(--fg-3); }
.ov-otable .muted { color: var(--fg-3); }
.ov-otable .tag { display: inline-flex; padding: 2px 7px; border: 1px solid var(--warn-line); border-radius: var(--r-chip); font-size: 12px; font-weight: 600; color: var(--warn); }
/* The phone bar: Anony Balance's section names are longer than the siblings' (de "Bestellungen & Belege", "Verknüpfte
   Apps"), so a label may take two lines instead of pushing the last cell off the screen (AnonyVPN: one line, max-content). */
@media (max-width: 767.98px) {
  .bar__cell { min-width: 0; }
  .bar__label { white-space: normal; text-align: center; line-height: 1.15; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
  html.app .appmain { padding-bottom: calc(92px + env(safe-area-inset-bottom)); }
}

/* ---- the rest of the signed-in pages (owner 2026-10-15: "I approve the design") ---------------------------------- */
/* The e-mail setting on Orders & receipts: AnonyChat's Switch (src/components/ui/switch.tsx: role="switch" on a real
   button, 28 × 48, a 20 px knob; on = the brand fill with the knob in the ink, off = the raised ground with a light knob),
   in these tokens. Anony Balance's switch posts the form (no script). */
.switch { position: relative; flex: none; width: 48px; height: 28px; min-height: 0; padding: 0; border-radius: 99px; border: 1px solid var(--rule-strong); background: var(--raised); cursor: pointer; transition: background-color 150ms, border-color 150ms; }
.switch__knob { position: absolute; top: 3px; inset-inline-start: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--fg); transition: inset-inline-start 150ms var(--ease), background-color 150ms; }
.switch[aria-checked="true"] { background: var(--accent); border-color: transparent; }
.switch[aria-checked="true"] .switch__knob { inset-inline-start: 23px; background: var(--on-accent); }
.switch:hover { border-color: var(--rule-hover); }
.switch[data-disabled] { opacity: 0.4; cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) { .switch, .switch__knob { transition: none; } }
.orders__lede { margin: 0 0 4px !important; }
.hist__doc { display: inline-flex; margin-top: 6px; margin-inline-start: -8px; }
td > .hist__doc { display: flex; width: max-content; }
/* Add money: AnonyVPN's duration rows for the amounts and the way to pay; a row that doesn't fit the room left is off;
   "Other amount" carries its own field (the app's input, compact as AnonyVPN's admin filters). */
.durations > legend { padding: 0; margin: 0 0 8px; font-size: 14px; font-weight: 500; color: var(--fg-2); }
.duration.is-off { opacity: 0.45; cursor: not-allowed; }
.duration > .ico { color: var(--fg-3); }
.duration:has(input:checked) > .ico { color: var(--accent); }
.duration__other { display: inline-flex; align-items: center; gap: 6px; color: var(--fg-3); }
.duration__other input { width: 112px; min-height: 36px; padding: 6px 10px; font-size: 15px; }
.buy__country { margin: 18px 0 16px; max-width: none; }
.buy .durations + .durations { margin-top: 4px; }
/* The public frame's cards (the link confirmation, the sign-in states): AnonyMail's .gate__card with AnonyVPN's 18+ card. */
.gate__card { margin: 0; }
.gate__card .actions { margin: 20px 0 0; }
.gate__card .kv-rows { margin: 16px 0 0; border-top: 1px solid var(--rule); }
.gate__card .kv-rows .kv-row:first-child { border-top: 0; }
.gate__card .facts-list { margin: 16px 0 12px; }
html.gate .brand .rail__tag { margin-inline-start: 2px; }
/* The card's 3-D Secure step in the page (static/topup.js puts Mollie's page in this frame). */
.threeds__frame { margin-top: 16px; border-radius: var(--r-control); overflow: hidden; border: 1px solid var(--rule); background: #fff; }
.threeds__frame[hidden] { display: none; }
.threeds__iframe { display: block; width: 100%; height: 640px; border: 0; }

/* ==== The payment-method picker (src/views/paypicker.ts) — designed ONCE here from the siblings' pieces, for reuse by
   any Anony Labs checkout that takes Mollie: AnonyVPN's checkout form around it, the wallets as full-width buttons,
   the card as AnonyVPN / AnonyMail's disclosure with input-drawn fields, the banks as AnonyVPN's duration rows. ==== */
.pm-form { gap: 14px; }
.pm-mode { margin: 0; }
.pm-title { margin: 4px 0 0; font: 600 15px/1.2 var(--ui); letter-spacing: -0.01em; }
.wallets { display: grid; gap: 10px; }
.wallets:not(:has(> :not([hidden]))) { display: none; }
.wallet { width: 100%; min-height: 48px; padding: 0; border-radius: var(--r-control); border: 0; cursor: pointer; }
.wallet[hidden] { display: none; }
/* Apple's own button where Safari draws it (developer.apple.com: displaying Apple Pay buttons using CSS) */
@supports (-webkit-appearance: -apple-pay-button) {
  .wallet--apple { -webkit-appearance: -apple-pay-button; -apple-pay-button-type: plain; -apple-pay-button-style: white; }
}
@supports not (-webkit-appearance: -apple-pay-button) {
  .wallet--apple { background: #fff; color: #000; font: 600 17px/1 system-ui, sans-serif; }
  .wallet--apple::after { content: "Apple Pay"; }
}
.wallet--google { min-height: 48px; background: transparent; }
.wallet--google > * { width: 100%; }
.wallet--other { gap: 10px; border: 1px solid var(--rule-strong); background: var(--surface); color: var(--fg-soft); }
.pm.disclosure { margin: 0; }
.pm__name { flex: 1; color: var(--fg); }
.pm__body { display: grid; gap: 14px; }
.pm__icon { width: 32px; height: 24px; flex: none; border-radius: 4px; background: #fff; object-fit: contain; padding: 2px; }
.pm__icon--none { background: var(--raised); }
.cardfields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.cardfield { display: grid; gap: 6px; min-width: 0; }
.cardfield--wide { grid-column: 1 / -1; }
.mollie-slot { min-height: 44px; padding: 9px 12px; border: 1px solid var(--rule-strong); border-radius: var(--r-control); background: var(--field); transition: border-color 150ms; }
.mollie-slot:hover { border-color: var(--rule-hover); }
.mollie-slot.is-invalid { border-color: var(--danger); }
/* Mollie's fields are iframes: the iframe takes the light scheme and stays transparent, or the browser paints a white
   backdrop behind it on a dark page (owner 2026-10-15: white fields); their own background is transparent (pay.ts). */
.mollie-slot iframe { color-scheme: light; background: transparent; }
.pm__pay { width: 100%; }
.pm__note { display: flex; gap: 8px; align-items: flex-start; margin: 0 !important; }
.pm__note .ico { margin-top: 2px; }
.pm-banks { margin: 0; }
.bank {
  display: flex; align-items: center; justify-content: flex-start; gap: 10px; width: 100%; min-height: 44px; padding: 10px 12px; border: 1px solid var(--rule-strong);
  border-radius: var(--r-control); background: transparent; color: var(--fg); font-size: 14px; font-weight: 600; text-align: start; white-space: normal;
}
.bank:hover, .bank:focus-visible { border-color: var(--accent); background: var(--accent-soft); color: var(--fg); }
.bank__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bank > .ico { color: var(--fg-3); }
.bank:disabled, .wallet:disabled { opacity: 0.5; cursor: progress; }
.pm-banks > .hint { margin: 4px 0 0; }
.card-error { margin: 0; color: var(--danger); font-size: 14px; }
/* The shared footer's headings are h2s: in the app shell the app's h2 type (html.app h2) would win over static/footer.css's
   .foot__h, so its own rule is restated here at the shell's weight (the siblings' app pages have no footer). */
html.app .foot h2.foot__h { margin: 0; font: 400 11px/1.4 var(--foot-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--foot-fg-3); }
html.app .foot:is(:lang(ar), :lang(hi), :lang(ja), :lang(ko), :lang(zh-Hans)) h2.foot__h { letter-spacing: 0; }
/* The confirmation: the order panel keeps its height beside the longer payment panel. */
.checkout.ov-bento { align-items: start; }
/* Signed amounts never break after their sign (−€4.95 on a phone). */
.ov-otable .tabnum { white-space: nowrap; }
