/* ============================================================================
   Personal IT Guy - marketing site
   A dark, professional "cyber" theme. RTL/LTR aware via logical properties.
   ============================================================================ */

:root {
    --bg:        #07070e;
    --bg-alt:    #0b0b16;
    --surface:   rgba(20, 20, 36, 0.72);
    --surface-2: rgba(255, 255, 255, 0.04);
    --border:    rgba(255, 255, 255, 0.09);
    --border-lit:rgba(108, 99, 255, 0.4);
    --text:      #eef0ff;
    --muted:     rgba(200, 204, 235, 0.66);
    /* 0.58 is the point where small --faint text still clears 4.5:1 on --bg
       (IS 5568 / WCAG AA). Do not lower it. */
    --faint:     rgba(200, 204, 235, 0.58);
    --accent:    #6c63ff;
    --accent-2:  #22d3ee;
    --accent-3:  #a78bfa;
    --danger:    #f87171;
    /* Text colour of the gallery badge when the admin has not chosen one. Kept
       as a variable of its own so the light theme can restate it without
       stepping on an admin colour, which arrives as --eb further down. */
    --eb-text:   #a78bfa;
    --radius:    16px;
    --radius-sm: 11px;
    --maxw:      1160px;
    --shadow:    0 24px 70px rgba(0, 0, 0, 0.5);
    --font:      'Heebo', system-ui, -apple-system, sans-serif;
    --font-head: 'Rubik', 'Heebo', system-ui, sans-serif;
}

/* ── Light theme (toggled from the nav; persisted in localStorage) ──
   Built on separation rather than on brightness. The first version of this was
   a pale lavender page carrying near-white cards: two values a fraction apart,
   borders at 12% that disappeared between them, and body text at 72% over it -
   so the whole thing read as washed out, and the only solid thing on the screen
   was a heading. The ground is a step deeper and almost neutral, the cards are
   plain white, and the lines between them are dark enough to be lines. */
:root[data-theme="light"] {
    --bg:        #e9ecf1;
    --bg-alt:    #dfe3ea;
    /* Opaque, not 92%: a translucent card over a tinted page takes the tint and
       stops being a card. */
    --surface:   #ffffff;
    --surface-2: rgba(17, 24, 45, 0.055);
    --border:    rgba(17, 24, 45, 0.16);
    --border-lit:rgba(108, 99, 255, 0.5);
    --text:      #10131c;
    --muted:     rgba(30, 37, 58, 0.80);
    /* Same 4.5:1 floor as the dark theme - see the note there. Raised from 0.66:
       the floor was being met on paper and read faint on a screen. */
    --faint:     rgba(30, 37, 58, 0.72);
    --eb-text:   #4a42d4;
    /* Two layers rather than one enormous soft one: a close shadow draws the
       edge of the card, and the wide one gives it height. A single 60px blur at
       18% is a haze under a card, not a card that sits above the page. */
    --shadow:    0 10px 26px rgba(19, 27, 54, 0.10), 0 2px 5px rgba(19, 27, 54, 0.07);
}
/* Component overrides where colors were hardcoded for the dark theme */
/* The page itself, and the three things that were bleaching it: a lavender wash
   over the whole ground, and two coloured clouds at 14% on top of that. A light
   page does not need atmosphere to look designed - it needs its content to sit
   on something steady. */
:root[data-theme="light"] .bg { background: linear-gradient(180deg, #edeff4 0%, var(--bg) 40%, #dfe3eb 100%); }
:root[data-theme="light"] .bg__grid { background-image:
    linear-gradient(rgba(17, 24, 45, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(17, 24, 45, 0.05) 1px, transparent 1px); }
:root[data-theme="light"] .bg__glow--1 { background: radial-gradient(circle, rgba(108, 99, 255, 0.07), transparent 65%); }
:root[data-theme="light"] .bg__glow--2 { background: radial-gradient(circle, rgba(34, 211, 238, 0.05), transparent 65%); }
/* Nearly opaque, and with a line under it: at 75% the bar took the colour of
   whatever was scrolling beneath it and the page had no top edge. */
:root[data-theme="light"] .nav { background: rgba(255, 255, 255, 0.94); border-bottom-color: rgba(17, 24, 45, 0.12); }
/* Deeper stops, and the third one no longer a bright sky blue: the headline is
   the biggest thing on a light page and it was ending in a colour paler than the
   body text under it. */
:root[data-theme="light"] .hero__title { background: linear-gradient(120deg, #12142c 15%, #3a33b5 62%, #0f5f9c 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent; }
/* The pill and the quiet button are objects on a white page, so they get an
   edge and a ground of their own instead of a tint that the page swallows. */
:root[data-theme="light"] .hero__badge, :root[data-theme="light"] .dl-hero__badge {
    background: #ffffff; border-color: rgba(108, 99, 255, 0.38);
    box-shadow: 0 2px 6px rgba(19, 27, 54, 0.07);
}
:root[data-theme="light"] .btn--ghost {
    background: #ffffff; border-color: rgba(17, 24, 45, 0.20);
    box-shadow: 0 2px 6px rgba(19, 27, 54, 0.06);
}
:root[data-theme="light"] .btn--ghost:hover { background: #f2f4f8; border-color: rgba(17, 24, 45, 0.30); }
:root[data-theme="light"] .footer { background: rgba(255, 255, 255, 0.6); }
:root[data-theme="light"] .lang-switch__flag, :root[data-theme="light"] .cms__langpill-btn img { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12); }
:root[data-theme="light"] .btn--ghost { color: var(--text); }
:root[data-theme="light"] .cta__inner { background: radial-gradient(ellipse at 50% 0%, rgba(108, 99, 255, 0.16), var(--surface) 70%); }
:root[data-theme="light"] .lmodal__card, :root[data-theme="light"] .wiz-terms__card { background: rgba(255, 255, 255, 0.98); }
:root[data-theme="light"] .lmodal__body { scrollbar-color: rgba(108, 99, 255, 0.7) rgba(20, 25, 60, 0.08); }
:root[data-theme="light"] .lmodal__body::-webkit-scrollbar-track { background: rgba(20, 25, 60, 0.08); }
:root[data-theme="light"] .cookiebar__inner { background: rgba(255, 255, 255, 0.97); }
:root[data-theme="light"] .cookiebar__link { color: #4b45c7; }
/* A card that lifts on a dark page borrows a black shadow and a glow. On a light
   page that reads as a smudge, so the lift is drawn with the page's own shadow
   colour instead - deeper than the resting one, and nothing else. */
:root[data-theme="light"] .card:hover, :root[data-theme="light"] .svc:hover, :root[data-theme="light"] .step:hover {
    box-shadow: 0 16px 34px rgba(19, 27, 54, 0.14), 0 3px 8px rgba(19, 27, 54, 0.08);
}
/* Panels that sit inside a section need to be told apart from the page as well
   as from the cards on it - one step down from white rather than a tint of the
   accent, which is what made the surfaces read as one wash. */
:root[data-theme="light"] .catalog, :root[data-theme="light"] .footer { background: #f6f7fa; }
:root[data-theme="light"] .catalog__chip.is-on {
    background: rgba(108, 99, 255, 0.12);
    border-color: rgba(108, 99, 255, 0.42);
    color: #1b1f33;
}
/* Accent text on the light theme: #a78bfa is a dark-theme colour and only
   reaches ~2.1:1 over a pale background. These are the places it is used as
   *text* (not as a glow or a border), so they get a darker violet that clears
   4.5:1, and the gradient headline numbers get a darker pair for 3:1. */
:root[data-theme="light"] .hero__badge,
:root[data-theme="light"] .cta__ver,
:root[data-theme="light"] .dl-hero__badge,
:root[data-theme="light"] .dl-hero__notes-label { color: #5b32c9; }
:root[data-theme="light"] .stat__num,
:root[data-theme="light"] .dl-hero__ver { background-image: linear-gradient(135deg, #5b32c9, #0e7490); }

/* Theme toggle button.
   Note: nothing in the nav transitions `color`. A colour that comes from a
   custom property does not always re-run its transition when the theme switches
   var(--muted) underneath it, which left the toggle and the language switch
   showing dark-theme grey on the light background until the next reload. */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 10px; cursor: pointer; background: var(--surface-2); border: 1px solid var(--border);
    color: var(--muted); font-size: 16px; transition: border-color 0.15s; }
.theme-toggle:hover { color: var(--text); border-color: var(--border-lit); }

/* Floating "back to top" button (position + on/off from the admin) */
.fab { width: 50px; height: 50px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer;
    background: var(--surface); border: 1px solid var(--border-lit); color: var(--text); box-shadow: var(--shadow), 0 0 26px rgba(108, 99, 255, 0.15);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: transform 0.15s; }
.fab:hover { transform: translateY(-2px); color: var(--accent-3); }
.fab:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.fab--top { position: fixed; z-index: 8000; animation: fab-in 0.25s ease; }
.fab--top[hidden] { display: none; }
@keyframes fab-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.fab--top.fab--bottom-end   { bottom: 20px; inset-inline-end: 20px; }
.fab--top.fab--bottom-start { bottom: 20px; inset-inline-start: 20px; }
.fab--top.fab--top-end      { top: 82px; inset-inline-end: 20px; }
.fab--top.fab--top-start    { top: 82px; inset-inline-start: 20px; }

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Global styled scrollbars (never the plain browser ones) */
* { scrollbar-width: thin; scrollbar-color: rgba(108, 99, 255, 0.5) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { border-radius: 999px; border: 3px solid transparent; background-clip: content-box;
    background-color: rgba(108, 99, 255, 0.45); }
::-webkit-scrollbar-thumb:hover { background-color: rgba(108, 99, 255, 0.75); }
::-webkit-scrollbar-corner { background: transparent; }

html { scroll-behavior: smooth; }

/* ── Keyboard accessibility (IS 5568 / WCAG AA) ──────────────────────────────
   One visible focus ring for everything that can hold focus. :where() keeps the
   specificity at zero, so the few components that draw their own ring still win.
   The ring clears 3:1 against both themes' backgrounds. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
    border-radius: 5px;
}
/* <main> only takes focus so the skip link can land on it - no ring needed. */
main:focus, main:focus-visible { outline: none; }

/* "Skip to main content": off-screen until it is focused, then the first thing
   on the page. Sits above the fixed header. */
.skip-link {
    position: fixed; inset-block-start: -100px; inset-inline-start: 16px; z-index: 9999;
    padding: 12px 20px; border-radius: 0 0 12px 12px;
    background: #4a42d4; color: #fff; font-weight: 700; font-size: 15px;
    text-decoration: none; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
    transition: inset-block-start 0.18s ease;
}
.skip-link:focus { inset-block-start: 0; }

body {
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 24px; }

/* ── Animated cyber background ── */
.bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; background:
    radial-gradient(ellipse 100% 80% at 50% -10%, #14142e 0%, var(--bg) 55%, #05050b 100%); }
/* -- The moving background --
   Six of them, chosen in the admin, all reading the same two colours
   (--bg-anim-1 / --bg-anim-2, set from the theme settings) so recolouring is a
   setting rather than a variant of each. The layer markup is identical for all
   six - only the class on .bg changes - so switching between them never asks
   the page to be built differently.

   Every one stops for prefers-reduced-motion, at the foot of this block. A
   background that keeps moving after the visitor's system has asked it not to
   is the most common accessibility failure on a site that looks like this. */
.bg__grid, .bg__glow, .bg__particles { position: absolute; }

/* 1. Cyber grid - the look the site shipped with. */
.bg--grid .bg__grid {
    inset: -40%;
    background-image:
        linear-gradient(color-mix(in srgb, var(--bg-anim-1, #6c63ff) 7%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 7%, transparent) 1px, transparent 1px);
    background-size: 52px 52px;
    mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 10%, transparent 72%);
    -webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 10%, transparent 72%);
    animation: grid-drift 30s linear infinite;
}
@keyframes grid-drift { from { transform: translateY(0); } to { transform: translateY(52px); } }

.bg__glow { border-radius: 50%; filter: blur(40px); opacity: 0.7; }
.bg__glow--1 { width: 620px; height: 620px; top: -12%; inset-inline-start: 6%;
    background: radial-gradient(circle, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 18%, transparent), transparent 65%);
    animation: glow-a 20s ease-in-out infinite alternate; }
.bg__glow--2 { width: 540px; height: 540px; bottom: -14%; inset-inline-end: 4%;
    background: radial-gradient(circle, color-mix(in srgb, var(--bg-anim-2, #22d3ee) 13%, transparent), transparent 65%);
    animation: glow-b 24s ease-in-out infinite alternate; }
@keyframes glow-a { to { transform: translate(90px, 70px); } }
@keyframes glow-b { to { transform: translate(-80px, -60px); } }
.bg__particles { inset: 0; width: 100%; height: 100%; }
/* The particle canvas belongs to the grid alone - the other backgrounds carry
   their own motion, and two moving things at once reads as a page that cannot
   settle. site.js skips the work entirely when the canvas is not shown. */
.bg:not(.bg--grid) .bg__particles { display: none; }

/* 2. Aurora - two soft clouds circling each other, and nothing else. */
.bg--aurora .bg__grid { display: none; }
.bg--aurora .bg__glow { filter: blur(90px); opacity: 0.85; }
.bg--aurora .bg__glow--1 {
    width: 78vw; height: 62vh; top: -18%; inset-inline-start: -10%;
    background: radial-gradient(circle, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 34%, transparent), transparent 62%);
    animation: aurora-a 34s ease-in-out infinite alternate;
}
.bg--aurora .bg__glow--2 {
    width: 70vw; height: 58vh; bottom: -20%; inset-inline-end: -8%;
    background: radial-gradient(circle, color-mix(in srgb, var(--bg-anim-2, #22d3ee) 28%, transparent), transparent 62%);
    animation: aurora-b 40s ease-in-out infinite alternate;
}
@keyframes aurora-a { to { transform: translate(16vw, 22vh) scale(1.18); } }
@keyframes aurora-b { to { transform: translate(-14vw, -18vh) scale(1.12); } }

/* 3. Waves - lines flowing across the foot of the page, drawn as repeating
   gradients so there is no asset to load and nothing to decode. */
.bg--waves .bg__grid {
    inset: auto 0 0 0; height: 60vh;
    background-image:
        repeating-linear-gradient(115deg,
            transparent 0 38px,
            color-mix(in srgb, var(--bg-anim-1, #6c63ff) 12%, transparent) 38px 40px),
        repeating-linear-gradient(65deg,
            transparent 0 54px,
            color-mix(in srgb, var(--bg-anim-2, #22d3ee) 9%, transparent) 54px 56px);
    mask-image: linear-gradient(to top, #000 5%, transparent 95%);
    -webkit-mask-image: linear-gradient(to top, #000 5%, transparent 95%);
    animation: wave-flow 26s linear infinite;
}
@keyframes wave-flow { to { background-position: 400px 0, -400px 0; } }
.bg--waves .bg__glow--1, .bg--waves .bg__glow--2 { opacity: 0.5; }

/* 4. Starfield - points of light drifting up, in two sizes so it has depth.
   Pure background-image: no DOM nodes and no canvas. */
.bg--stars .bg__grid {
    inset: -10%;
    background-image:
        radial-gradient(1.6px 1.6px at 20% 30%, color-mix(in srgb, var(--bg-anim-2, #22d3ee) 90%, transparent), transparent),
        radial-gradient(1.4px 1.4px at 70% 65%, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 85%, transparent), transparent),
        radial-gradient(1.2px 1.2px at 45% 85%, rgba(255, 255, 255, 0.7), transparent),
        radial-gradient(1.8px 1.8px at 85% 15%, rgba(255, 255, 255, 0.55), transparent);
    background-size: 340px 340px, 260px 260px, 420px 420px, 300px 300px;
    animation: star-rise 60s linear infinite;
    opacity: 0.85;
}
@keyframes star-rise { to { background-position: 0 -340px, 0 -260px, 0 -420px, 0 -300px; } }
.bg--stars .bg__glow { filter: blur(70px); opacity: 0.55; }

/* 5. Soft mesh - one wide wash that breathes. The quietest of the animated set. */
.bg--mesh .bg__grid {
    inset: -20%;
    background-image:
        radial-gradient(ellipse 60% 50% at 20% 25%, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 26%, transparent), transparent 70%),
        radial-gradient(ellipse 55% 45% at 80% 70%, color-mix(in srgb, var(--bg-anim-2, #22d3ee) 22%, transparent), transparent 70%),
        radial-gradient(ellipse 45% 40% at 60% 10%, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 16%, transparent), transparent 70%);
    filter: blur(30px);
    animation: mesh-breathe 26s ease-in-out infinite alternate;
}
@keyframes mesh-breathe { to { transform: scale(1.14) translateY(-3%); } }
.bg--mesh .bg__glow { display: none; }

/* 6. No animation - the still version, and the lightest thing to render. */
.bg--plain .bg__grid {
    inset: -40%;
    background-image:
        linear-gradient(color-mix(in srgb, var(--bg-anim-1, #6c63ff) 6%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--bg-anim-1, #6c63ff) 6%, transparent) 1px, transparent 1px);
    background-size: 52px 52px;
    mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 10%, transparent 72%);
    -webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 30%, #000 10%, transparent 72%);
}
.bg--plain .bg__glow { animation: none; }

/* Asked not to move - so nothing does. The accessibility widget's own "stop
   animations" switch (.a11y-noanim on <html>) is honoured the same way. */
@media (prefers-reduced-motion: reduce) {
    .bg__grid, .bg__glow { animation: none !important; }
}
.a11y-noanim .bg__grid, .a11y-noanim .bg__glow { animation: none !important; }

/* ── Buttons ── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 12px 24px; border-radius: var(--radius-sm); border: 1px solid transparent;
    font-family: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
    transition: transform 0.06s ease, opacity 0.15s, background 0.15s, border-color 0.15s;
    white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn.is-disabled { opacity: 0.4; cursor: default; pointer-events: none; box-shadow: none; filter: saturate(0.6); }
.btn--primary { background: linear-gradient(135deg, #5d54f0, #4a42d4); color: #fff;
    box-shadow: 0 10px 30px rgba(108, 99, 255, 0.4); }
.btn--primary:hover { opacity: 0.93; }
.btn--ghost { background: var(--surface-2); color: var(--text); border-color: var(--border); }
.btn--ghost:hover { background: rgba(255, 255, 255, 0.09); }
.btn--danger { background: rgba(248, 113, 113, 0.14); color: var(--danger); border-color: rgba(248, 113, 113, 0.35); }
.btn--danger:hover { background: rgba(248, 113, 113, 0.22); }
/* Working on it.
   For the forms whose answer takes real seconds - an SMTP conversation, mostly -
   where a plain POST leaves the page looking untouched until it comes back, and
   the button gets pressed a second time. Applied by admin.js to any button that
   carries data-busy; the disabled state above stops the second press, and the
   ring is what says it is still going rather than broken. Keeps its own colour:
   dimming it to 0.4 like a disabled button would read as "unavailable". */
.btn.is-busy { opacity: 1; filter: none; cursor: progress; }
.btn.is-busy::before {
    content: ''; width: 14px; height: 14px; flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid currentColor; border-top-color: transparent;
    animation: btn-busy-spin 0.7s linear infinite;
}
@keyframes btn-busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn.is-busy::before { animation-duration: 2.4s; } }

.btn--sm { padding: 8px 16px; font-size: 13.5px; }
.btn--lg { padding: 15px 32px; font-size: 16px; }
.btn--block { width: 100%; }
/* Download button with a clean inline icon */
.btn--dl { gap: 9px; }
.btn--dl .ico-dl { flex-shrink: 0; }
/* Directional arrow inside a button. It is a flex item, not a character in the
   label, so the side is decided by writing direction rather than by the bidi
   algorithm - which moved it and left it pointing the wrong way. */
.btn__arw { flex-shrink: 0; font-size: 1.05em; line-height: 1; opacity: .8; }
/* "See features" button with bobbing side chevrons */
.btn--seefeat { gap: 10px; }
.seefeat__chev { display: inline-flex; will-change: transform; animation: chev-bob 1.05s ease-in-out infinite; }
.seefeat__chev:last-child { animation-delay: 0.18s; }
@keyframes chev-bob { 0% { transform: translateY(-4px); opacity: 0.6; } 50% { transform: translateY(5px); opacity: 1; } 100% { transform: translateY(-4px); opacity: 0.6; } }

/* ── Nav ── */
.nav { position: sticky; top: 0; z-index: 50;
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    background: rgba(7, 7, 14, 0.7); border-bottom: 1px solid var(--border); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; height: 66px; gap: 20px; }
.nav__brand { display: flex; align-items: center; gap: 10px; font-weight: 800; font-size: 18px; }
.nav__logo { width: 40px; height: 40px; object-fit: contain; display: block;
    filter: drop-shadow(0 2px 10px rgba(108, 99, 255, 0.45)); }
.nav__links { display: flex; gap: 26px; }
.nav__links a { color: var(--muted); font-size: 14.5px; font-weight: 600; transition: color 0.15s; }
.nav__links a:hover { color: var(--text); }
.nav__actions { display: flex; align-items: center; gap: 12px; }
.lang-switch { display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px;
    border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border);
    font-size: 13px; font-weight: 700; color: var(--muted); transition: border-color 0.15s; }
.lang-switch:hover { color: var(--text); border-color: var(--border-lit); }
.lang-switch__flag { width: 20px; height: 14px; border-radius: 3px; object-fit: cover;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); display: block; }

/* ── Hero ── */
.hero { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: center;
    padding-block: clamp(24px, 4.5vw, 60px); }
.hero__logo { width: 260px; max-width: 72%; height: auto; display: block; margin-bottom: 22px;
    filter: drop-shadow(0 6px 26px rgba(108, 99, 255, 0.4)); }
@media (max-width: 900px) { .hero__logo { margin-inline: auto; } }
.hero__badge { display: inline-block; padding: 7px 15px; border-radius: 999px;
    background: rgba(108, 99, 255, 0.14); border: 1px solid var(--border-lit);
    color: var(--accent-3); font-size: 13px; font-weight: 700; margin-bottom: 22px; }
.nav__brand, .hero__title, .section__title, .card__title, .svc__title, .cta__title,
.shot__cap h3, .step__title, .stat__num, .legal-page__title { font-family: var(--font-head); }

.hero__title { font-size: clamp(28px, 4.2vw, 48px); line-height: 1.1; font-weight: 900;
    letter-spacing: -0.5px; margin-bottom: 20px;
    background: linear-gradient(120deg, #fff 20%, #c9c6ff 60%, #8fd8ff 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero__subtitle { font-size: clamp(15px, 1.9vw, 19px); color: var(--muted); max-width: 40ch; margin-bottom: 30px; }
.hero__cta { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 40px; }
.hero__stats { display: flex; gap: 34px; flex-wrap: wrap; }
.stat__num { font-size: 30px; font-weight: 900;
    background: linear-gradient(135deg, var(--accent-3), var(--accent-2));
    -webkit-background-clip: text; background-clip: text; color: transparent; }
.stat__label { font-size: 13px; color: var(--faint); font-weight: 600; }

/* Browser-ish mock frame */
.mock, .shot__frame { position: relative; border-radius: var(--radius);
    background: var(--surface); border: 1px solid var(--border);
    box-shadow: var(--shadow), 0 0 60px rgba(108, 99, 255, 0.1); overflow: hidden; }
.mock { transform: perspective(1400px) rotateY(-6deg) rotateX(2deg); transition: transform 0.5s; }
.hero__visual:hover .mock { transform: perspective(1400px) rotateY(0) rotateX(0); }
html[dir="rtl"] .mock { transform: perspective(1400px) rotateY(6deg) rotateX(2deg); }
html[dir="rtl"] .hero__visual:hover .mock { transform: perspective(1400px) rotateY(0) rotateX(0); }
.mock__bar, .shot__bar { display: flex; gap: 7px; padding: 12px 16px;
    background: rgba(0, 0, 0, 0.3); border-bottom: 1px solid var(--border); }
.mock__bar span, .shot__bar span { width: 11px; height: 11px; border-radius: 50%; background: rgba(255, 255, 255, 0.18); }
.mock__bar span:first-child { background: #ff5f57; }
.mock__bar span:nth-child(2) { background: #febc2e; }
.mock__bar span:nth-child(3) { background: #28c840; }
.mock img, .shot img { width: 100%; height: auto; }
/* Inline illustrations (SVG embedded so they inherit the page's Google font).
   Force LTR base direction: the mockups are laid out with LTR x-coordinates and
   text-anchor, so inheriting the page's RTL direction would flip every anchor
   and shove the text out of its boxes. */
.illus { display: block; direction: ltr; }
.illus svg, .illus svg text, .illus svg tspan { direction: ltr; }
.illus svg { display: block; width: 100%; height: auto; }

/* ── Sections ── */
.section { padding-block: clamp(38px, 5vw, 64px); }
.section--alt { position: relative; background: linear-gradient(180deg, transparent, var(--bg-alt) 12%, var(--bg-alt) 88%, transparent); }
.section__head { text-align: center; max-width: 640px; margin: 0 auto clamp(36px, 5vw, 56px); }
.section__title { font-size: clamp(26px, 3.6vw, 40px); font-weight: 900; letter-spacing: -0.4px; margin-bottom: 14px; }
.section__sub { font-size: 16px; color: var(--muted); }
/* A footnote, not a statement: it says the screens are drawings, and it is meant to
   be found rather than read. Set apart by its own space so it belongs to the page
   rather than to the cards above it. */
.section__disclaimer { margin-top: clamp(28px, 4vw, 44px); text-align: center;
    font-size: 12.5px; color: var(--muted); opacity: 0.62; }

.grid { display: grid; gap: 20px; }
.grid--3 { grid-template-columns: repeat(3, 1fr); }

/* ── Feature cards ── */
.card { padding: 28px 24px; border-radius: var(--radius);
    background: var(--surface); border: 1px solid var(--border);
    transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s; }
.card:hover { transform: translateY(-5px); border-color: var(--border-lit);
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4), 0 0 30px rgba(108, 99, 255, 0.14); }
.card__icon { font-size: 34px; margin-bottom: 16px; line-height: 1; }

/* ── Drawn icons ──
   A tile rather than a loose glyph: the drawing needs something to sit in, or it
   floats in the corner of the card at whatever weight the stroke happens to be. The
   tile carries the accent colour and the glow the emoji used to get from a filter. */
.ico { display: inline-flex; align-items: center; justify-content: center;
    padding: 9px;
    border-radius: 15px; color: var(--accent-3);
    border: 1px solid var(--border-lit);
    background: linear-gradient(140deg, rgba(108, 99, 255, 0.20), rgba(34, 211, 238, 0.08));
    box-shadow: 0 10px 26px rgba(108, 99, 255, 0.20), inset 0 1px 0 rgba(255, 255, 255, 0.06); }
.ico svg { display: block; }

/* The small line glyphs: they belong to the line of text they sit in, so they take
   its colour and sit on its baseline rather than hanging above it. */
.gly { vertical-align: -0.18em; flex-shrink: 0; }
.gly--win { vertical-align: -0.14em; }
.dl-hero__badge .gly, .dl-trust__item .gly, .dl-chip .gly { color: inherit; opacity: .9; }
/* A drawing needs more air beside text than an emoji did: the emoji carried its own
   padding inside the glyph, a drawn mark ends where its ink ends. The chips already
   space their contents with a gap; these lines are plain text, so the mark spaces
   itself - logically, so it works the same way in both directions. */
.dl-hero__badge, .dl-trust__item { display: inline-flex; align-items: center; gap: 9px; }
/* The version line is a block and so breaks the line above it, but everything after
   it here is inline: an inline-flex box and the download button are two boxes on one
   line the moment nothing block-level separates them. Usually the "what's new" panel
   does - which is why this looked right nearly everywhere - but that panel is
   optional: a release published without notes, or the notes switched off in the
   admin, and the line describing Windows landed beside the button. A flex row of its
   own always takes the whole line. */
.dl-hero__os { display: flex; justify-content: center; align-items: center; gap: 9px; }
.dl-title .gly { margin-inline-end: 10px; }
.dl-install__step-title .gly { margin-inline-end: 7px; }
.dl-title .gly { vertical-align: -0.12em; color: var(--accent-3); }
.dl-install__step-title .gly { color: var(--accent-3); }
/* The tile has to hold its own against a white card. At 16% over 92%-white it
   was a suggestion of a tile; solid, with a real edge, it reads as an object and
   the drawing inside it has something to sit on. */
:root[data-theme="light"] .ico { color: #3d34c9;
    background: linear-gradient(140deg, rgba(108, 99, 255, 0.15), rgba(34, 211, 238, 0.09)), #ffffff;
    border-color: rgba(108, 99, 255, 0.28);
    box-shadow: 0 4px 12px rgba(56, 48, 140, 0.12); }
/* The card lifts, and its icon lifts a little more - the same movement the rest of
   the card already has, so nothing new is introduced, only carried through. */
.card:hover .ico, .svc:hover .ico { color: var(--text); border-color: var(--accent);
    background: linear-gradient(140deg, rgba(108, 99, 255, 0.34), rgba(34, 211, 238, 0.14)); }
.ico { transition: color .2s ease, border-color .2s ease, background .2s ease; }
@media (prefers-reduced-motion: reduce) { .ico { transition: none; } }
.card__title { font-size: 19px; font-weight: 800; margin-bottom: 9px; }
.card__desc { font-size: 14.5px; color: var(--muted); }

/* ── The server band ──
   Built on the favourites band's shape - a drawn screen on one side, the case for
   it on the other - but mirrored: the picture leads here, because "the app has a
   server screen" is a thing to be shown before it is argued. Cyan rather than the
   favourites' gold: this is the business half of the page, not the personal one. */
/* The same vertical rhythm every .section on the page has, top AND bottom. The
   favourites band below gets away with padding on one side because the band that
   follows it brings its own; this one sits between two ordinary sections, so a
   one-sided padding left it hugging the section under it.
   Above it, though, the gallery's own bottom padding stacked on top of this one
   and opened a gap twice the size of the ones between the shots. The band reads
   as one more item in that run, so the space above it matches the shots' gap
   exactly and the gallery hands its bottom padding over (see #gallery below). */
.srv { position: relative; padding-block: clamp(40px, 6vw, 72px) clamp(38px, 5vw, 64px); }
/* Only when the band actually follows the gallery - with the server section
   turned off, the gallery keeps the bottom padding every other section has. */
#gallery:has(+ .srv) { padding-block-end: 0; }
.srv__inner {
    display: grid; grid-template-columns: 1.15fr 0.85fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.srv__copy { display: flex; flex-direction: column; gap: 14px; }
.srv__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(34, 211, 238, 0.38);
    background: rgba(34, 211, 238, 0.08);
    font-size: 12.5px; font-weight: 800; color: var(--accent-2);
}
.srv__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.srv__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.srv__points { list-style: none; display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
.srv__points li { display: flex; align-items: flex-start; gap: 11px; font-size: 14px; line-height: 1.6; }
.srv__points .gly { flex-shrink: 0; margin-top: 3px; color: var(--accent-2); }
.srv__note { font-size: 12.5px; line-height: 1.6; color: var(--faint); }

.srv__shot { margin: 0; }
.srv__frame {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.srv__bar { display: flex; gap: 6px; padding: 10px 14px; background: rgba(255, 255, 255, 0.03); border-bottom: 1px solid var(--border); }
.srv__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.srv__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.srv__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.srv__frame img { display: block; width: 100%; height: auto; }

@media (max-width: 860px) { .srv__inner { grid-template-columns: 1fr; } }

/* ── The full capability catalogue ──
   A framed panel with its own scroll. The complete list is 60-odd lines long:
   set loose on the page it would bury everything under it, so it is given a
   window of its own, a rail of subjects beside it, and headings that stay put
   while their own list runs past them. */
.catalog {
    display: grid;
    grid-template-columns: minmax(190px, 250px) 1fr;
    gap: 18px;
    padding: 18px;
    border-radius: calc(var(--radius) + 6px);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
    /* The glow that marks the panel as the centrepiece of the section rather
       than another card in a row of cards. */
    position: relative;
    overflow: hidden;
}
.catalog::before {
    content: '';
    position: absolute; inset-block-start: 0; inset-inline: 12%;
    height: 2px; border-radius: 999px;
    background: linear-gradient(90deg, transparent, var(--accent), var(--accent-2), transparent);
    opacity: 0.8;
}

/* The rail of subjects. Its own column on a wide screen, a row of chips that
   scrolls sideways on a narrow one. */
.catalog__railwrap { position: relative; min-width: 0; }
.catalog__rail {
    display: flex; flex-direction: column; gap: 6px;
    max-height: 62vh; overflow-y: auto;
    padding-inline-end: 4px;
}
/* The two arrows on the lying-down strip. Drawn, round, and over the ends of
   the strip rather than beside it - the strip is already as wide as the panel,
   and taking width from it to park a button would push a chip out of reach to
   announce that chips are out of reach. Hidden entirely on the wide layout,
   where the rail is a column and nothing is past an edge. */
.catalog__arrow { display: none; }
.catalog__arrow[hidden] { display: none !important; }
.catalog__chip {
    display: flex; align-items: center; gap: 10px;
    width: 100%; text-align: start;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: none; color: var(--muted);
    font-family: var(--font); font-size: 14px; font-weight: 600;
    cursor: pointer;
    transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.catalog__chip:hover { background: var(--surface-2); color: var(--text); }
.catalog__chip.is-on {
    background: linear-gradient(120deg, rgba(108, 99, 255, 0.22), rgba(34, 211, 238, 0.10));
    border-color: var(--border-lit);
    color: var(--text);
}
.catalog__chip-ico { display: inline-flex; color: var(--accent-3); flex-shrink: 0; }
.catalog__chip.is-on .catalog__chip-ico { color: var(--accent-2); }
.catalog__chip-t { flex: 1; min-width: 0; }
.catalog__chip-n {
    font-size: 11.5px; font-weight: 800; color: var(--faint);
    background: var(--surface-2); border-radius: 999px; padding: 1px 8px;
}

/* The window itself. */
.catalog__scroll {
    /* Positioned, so a group's offsetTop is measured against this frame - that
       is the number the rail scrolls to (see site.js). */
    position: relative;
    max-height: 62vh;
    overflow-y: auto;
    padding-inline: 6px 12px;
    /* A scroll of its own gets a scrollbar of its own, in the site's colours -
       the page-wide rule paints it the same way, this only makes the track
       visible so the panel reads as scrollable before it is touched. */
    scrollbar-color: var(--accent) var(--surface-2);
    /* Dragged with a finger on a touch screen: momentum, and the drag stops at
       the end of the list instead of carrying the whole page with it. */
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}
.catalog__scroll::-webkit-scrollbar-track { background: var(--surface-2); border-radius: 999px; }
.catalog__scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.catalog__group { scroll-margin-top: 8px; }
.catalog__group + .catalog__group { margin-top: 22px; }
.catalog__ghead {
    position: sticky; inset-block-start: 0; z-index: 2;
    display: flex; align-items: center; gap: 10px;
    margin: 0 0 12px;
    padding: 10px 4px;
    font-family: var(--font-head); font-size: 17px; font-weight: 800;
    /* Opaque enough that the lines scrolling under it do not show through. */
    background: linear-gradient(180deg, var(--bg-alt) 72%, transparent);
    border-block-end: 1px solid var(--border);
}
.catalog__gico { display: inline-flex; color: var(--accent-2); }
.catalog__gt { flex: 1; min-width: 0; }
.catalog__gn { font-size: 12px; font-weight: 700; color: var(--faint); }

.catalog__items { list-style: none; display: grid; gap: 10px; margin: 0; padding: 0; }
.catalog__item {
    display: flex; align-items: flex-start; gap: 11px;
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border: 1px solid transparent;
    transition: border-color 0.18s, transform 0.18s;
}
.catalog__item:hover { border-color: var(--border-lit); transform: translateX(-2px); }
[dir="ltr"] .catalog__item:hover { transform: translateX(2px); }
.catalog__tick { display: inline-flex; color: var(--accent); margin-block-start: 2px; flex-shrink: 0; }
.catalog__body { display: block; min-width: 0; }
.catalog__t { display: block; font-size: 15px; font-weight: 700; margin-block-end: 3px; }
.catalog__d { display: block; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

.catalog__foot {
    grid-column: 1 / -1;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    margin: 4px 0 0; padding-block-start: 12px;
    border-block-start: 1px solid var(--border);
    font-size: 12.5px; color: var(--faint);
}
.catalog__foot .gly { color: var(--accent-2); flex-shrink: 0; }

@media (max-width: 860px) {
    .catalog { grid-template-columns: 1fr; }
    /* On a phone the rail lies down and is dragged with a finger. Everything
       here is about that gesture: momentum on iOS, the drag staying inside the
       strip instead of pulling the page along with it once it runs out, and the
       chip it lands on coming to rest at the edge rather than half cut off. */
    .catalog__rail {
        flex-direction: row; max-height: none;
        overflow-x: auto; overflow-y: hidden;
        padding-block-end: 6px;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        touch-action: pan-x;
        /* The strip is a drag surface, so a slow drag must not select the words
           on the chips instead of moving them. */
        -webkit-user-select: none; user-select: none;
    }
    .catalog__chip { width: auto; flex-shrink: 0; scroll-snap-align: start; }
    .catalog__chip-n { display: none; }

    /* The arrows, once the strip really is a strip. Placed on the ends by
       logical properties, so "previous" is on the right in Hebrew and on the
       left in English without a second rule. */
    .catalog__arrow {
        display: inline-flex; align-items: center; justify-content: center;
        position: absolute; inset-block-start: 50%;
        transform: translateY(-50%);
        width: 34px; height: 34px; padding: 0;
        border-radius: 50%; cursor: pointer;
        border: 1px solid var(--border-lit);
        background: var(--surface-2);
        color: var(--text);
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
        z-index: 2;
        transition: background 0.18s, color 0.18s, border-color 0.18s, opacity 0.18s;
    }
    .catalog__arrow--prev { inset-inline-start: -4px; }
    .catalog__arrow--next { inset-inline-end: -4px; }
    .catalog__arrow:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
    /* At the end of its own travel it stays where it is and stops offering:
       a button that vanishes moves everything beside it. */
    .catalog__arrow:disabled { opacity: 0.35; cursor: default; box-shadow: none; }
    .catalog__arrow:disabled:hover { background: var(--surface-2); border-color: var(--border-lit); color: var(--text); }
    /* The arrow points the way the strip moves, which in an RTL page is the
       other way round from the glyph as drawn. */
    [dir="rtl"] .catalog__arrow .gly { transform: scaleX(-1); }
    /* Room for the two buttons at the ends of the strip, so a chip never sits
       under one. */
    .catalog__railwrap { padding-inline: 30px; }
    /* The panel keeps its own vertical drag - and only that one, so a slightly
       sideways finger scrolls the list rather than fighting the page. */
    .catalog__scroll {
        max-height: 70vh;
        touch-action: pan-y;
    }
}
@media (prefers-reduced-motion: reduce) {
    .catalog__item, .catalog__chip { transition: none; }
    .catalog__item:hover { transform: none; }
}

/* ── How it works ── */
.how-hero { display: flex; justify-content: center; margin: 8px auto -18px; }
.how-hero__img { width: min(300px, 62vw); height: auto; object-fit: contain;
    filter: drop-shadow(0 18px 44px rgba(108, 99, 255, 0.35)); animation: how-hero-float 6s ease-in-out infinite; }
@keyframes how-hero-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@media (prefers-reduced-motion: reduce) { .how-hero__img { animation: none; } }
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; counter-reset: step; }
.step { position: relative; padding: 26px 22px; border-radius: var(--radius);
    background: var(--surface); border: 1px solid var(--border); transition: transform 0.2s, border-color 0.2s; }
.step:hover { transform: translateY(-4px); border-color: var(--border-lit); }
.step__num { display: flex; align-items: center; justify-content: center; width: 46px; height: 46px;
    border-radius: 13px; margin-bottom: 16px; font-size: 20px; font-weight: 900; color: #fff;
    background: linear-gradient(135deg, #5d54f0, #4a42d4); box-shadow: 0 8px 22px rgba(108, 99, 255, 0.4); }
.step__title { font-size: 17px; font-weight: 800; margin-bottom: 8px; }
.step__desc { font-size: 14px; color: var(--muted); }
/* connector line between steps on wide screens */
.step:not(:last-child)::after { content: ''; position: absolute; top: 48px; inset-inline-end: -10px;
    width: 20px; height: 2px; background: linear-gradient(90deg, var(--border-lit), transparent); }
html[dir="rtl"] .step:not(:last-child)::after { background: linear-gradient(270deg, var(--border-lit), transparent); }

/* ── Favourites ── */
/* The mirror image of the taskbar band below it: words on the side the band puts
   its picture, so the two read as a pair rather than as the same slide twice. */
.favs { position: relative; padding: clamp(44px, 6vw, 80px) 0 0; }
.favs__inner {
    display: grid; grid-template-columns: 0.85fr 1.15fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.favs__copy { display: flex; flex-direction: column; gap: 14px; }
.favs__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(251, 191, 36, 0.38);
    background: rgba(251, 191, 36, 0.08);
    font-size: 12.5px; font-weight: 800; color: #fbbf24;
}
.favs__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.favs__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.favs__points { list-style: none; display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
.favs__points li { display: flex; align-items: flex-start; gap: 11px; font-size: 14px; line-height: 1.6; }
/* Gold, because that is the colour of the star this whole section is about. */
.favs__points .gly { flex-shrink: 0; margin-top: 3px; color: #fbbf24; }

/* The same window frame the gallery uses, so a drawing of a screen reads as a
   screen here too. */
.favs__shot { margin: 0; }
.favs__frame {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.favs__bar { display: flex; gap: 6px; padding: 10px 14px; background: rgba(255, 255, 255, 0.03); border-bottom: 1px solid var(--border); }
.favs__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.favs__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.favs__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.favs__frame img { display: block; width: 100%; height: auto; }

@media (max-width: 860px) { .favs__inner { grid-template-columns: 1fr; } }

/* ── The tools that are on every screen ── */
/* The picture leads and takes the wider column, the opposite way round to the
   favourites band further down, so a reader scrolling the page never meets the
   same arrangement twice in a row. It is framed like the gallery's screens
   because that is what it is: the app, seen from inside - and it carries the
   argument here, since three tools used at the same time on top of something
   else is a thing far easier to show than to write down. */
.tools { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.tools__inner {
    display: grid; grid-template-columns: 1.15fr 0.85fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.tools__copy { display: flex; flex-direction: column; gap: 14px; }
.tools__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(251, 191, 36, 0.38);
    background: rgba(251, 191, 36, 0.08);
    font-size: 12.5px; font-weight: 800; color: #fbbf24;
}
.tools__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.tools__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.tools__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.tools__points li {
    display: flex; align-items: flex-start; gap: 11px;
    font-size: 14px; line-height: 1.65; color: var(--muted);
}
/* The name of the tool leads its own line: three lines of running prose one
   under the other are read as a paragraph and skipped as one. */
.tools__points strong {
    display: block; margin-bottom: 2px;
    color: var(--text); font-size: 14.5px; font-weight: 800;
}
.tools__points .gly { flex-shrink: 0; margin-top: 2px; color: #fbbf24; }

.tools__shot { margin: 0; }
.tools__frame {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.tools__bar { display: flex; gap: 6px; padding: 10px 14px; background: rgba(255, 255, 255, 0.03); border-bottom: 1px solid var(--border); }
.tools__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.tools__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.tools__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.tools__frame img { display: block; width: 100%; height: auto; }

@media (max-width: 860px) { .tools__inner { grid-template-columns: 1fr; } }

/* ── Where it lives: the app on a real taskbar ── */
/* The picture is a dark photograph that fades to black at its edges, so it is not
   framed like the screens in the gallery - a border around it would draw a box
   around nothing. It bleeds into the page instead, and the light in it does the
   framing. */
.taskbar { position: relative; padding: clamp(48px, 7vw, 92px) 0; overflow: hidden; }
.taskbar::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(60% 70% at 50% 45%, rgba(34, 211, 238, 0.10), transparent 70%);
}
.taskbar__inner {
    position: relative;
    display: grid; grid-template-columns: 1.15fr 0.85fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}

.taskbar__shot { position: relative; margin: 0; }
.taskbar__shot img {
    display: block; width: 100%; height: auto;
    border-radius: 18px;
    /* The glow is the icon's own colour, thrown by the image rather than drawn on
       top of it - a hard border would cut off the light that makes the shot. */
    box-shadow: 0 26px 70px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
}
/* A soft cyan halo behind the picture, breathing slowly. It is the same glow the
   icon has in the shot, continued past its edge. */
.taskbar__shot::after {
    content: ''; position: absolute; inset: -8% -6%; z-index: -1; border-radius: 40px;
    background: radial-gradient(50% 55% at 38% 62%, rgba(34, 211, 238, 0.34), transparent 68%);
    filter: blur(26px);
    animation: taskbar-breathe 7s ease-in-out infinite;
}
@keyframes taskbar-breathe { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }

.taskbar__copy { display: flex; flex-direction: column; gap: 14px; }
.taskbar__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid var(--border-lit); background: var(--surface-2);
    font-size: 12.5px; font-weight: 800; color: var(--accent-3);
}
.taskbar__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.taskbar__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }

.taskbar__points { list-style: none; display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
.taskbar__points li {
    display: flex; align-items: flex-start; gap: 11px;
    font-size: 14px; line-height: 1.6; color: var(--text);
}
.taskbar__points .gly { flex-shrink: 0; margin-top: 3px; color: var(--accent-2); }

@media (max-width: 860px) {
    .taskbar__inner { grid-template-columns: 1fr; }
    .taskbar__copy { text-align: start; }
}
@media (prefers-reduced-motion: reduce) { .taskbar__shot::after { animation: none; } }

/* ── Gallery ── */
.shots { display: flex; flex-direction: column; gap: clamp(40px, 6vw, 72px); }
.shot { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 40px; align-items: center; }
.shot:nth-child(even) { direction: ltr; }
.shot:nth-child(even) .shot__cap { direction: inherit; }
html[dir="rtl"] .shot:nth-child(even) { direction: rtl; }
/* The caption beside each screen. It used to be a heading and a paragraph on empty
   space next to a detailed mockup, which read as unfinished. Now it has a subject
   behind it - the drawing that belongs to that screen, oversized and turned almost
   all the way down - and a rule that ties the block together. */
.shot__cap { position: relative; padding-inline-start: 22px; }
.shot__cap::before { content: ''; position: absolute; inset-block: 4px; inset-inline-start: 0;
    width: 2px; border-radius: 2px;
    background: linear-gradient(180deg, var(--accent), rgba(34, 211, 238, 0.5) 55%, transparent); }
.shot__wm { position: absolute; inset-inline-start: -18px; top: 50%; translate: 0 -50%;
    width: 244px; height: 244px; color: var(--accent-3); opacity: 0.12;
    pointer-events: none; z-index: 0;
    /* Faded out at the edges so it reads as atmosphere and never as a shape that
       somebody forgot to finish. */
    -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 74%);
    mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 74%); }
.shot__wm svg { width: 100%; height: 100%; display: block; }
:root[data-theme="light"] .shot__wm { color: var(--accent); opacity: 0.14; }

/* The badge above each caption. Its colour is editable from the admin, which
   arrives as --eb on the gallery (all screens) or on one .shot--ebN (that screen
   only) - see the nonced <style> index.php prints. Everything here is derived
   from that one value, so a single hex sets the text, the ring and the wash;
   with nothing set, the fallbacks reproduce the house purple exactly. */
.shot__eyebrow { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 7px;
    margin-bottom: 12px; padding: 5px 12px; border-radius: 999px;
    font-size: 11.5px; font-weight: 800; letter-spacing: 0.3px;
    color: var(--eb, var(--eb-text));
    border: 1px solid color-mix(in srgb, var(--eb, var(--accent)) 42%, transparent);
    background: color-mix(in srgb, var(--eb, var(--accent)) 10%, transparent); }
:root[data-theme="light"] .shot__eyebrow { background: color-mix(in srgb, var(--eb, var(--accent)) 8%, transparent); }

.shot__cap h3 { position: relative; z-index: 1; font-size: 24px; font-weight: 800; margin-bottom: 12px; }
.shot__cap p { position: relative; z-index: 1; font-size: 15.5px; color: var(--muted); }
.shot__frame { transition: transform 0.4s, box-shadow 0.4s; }
.shot__frame:hover { transform: translateY(-4px); box-shadow: var(--shadow), 0 0 50px rgba(34, 211, 238, 0.14); }

/* ── Services ── */
.svc { padding: 30px 26px; border-radius: var(--radius); text-align: center;
    background: linear-gradient(180deg, var(--surface), rgba(108, 99, 255, 0.05));
    border: 1px solid var(--border); transition: transform 0.2s, border-color 0.2s; }
.svc:hover { transform: translateY(-5px); border-color: var(--border-lit); }
.svc__icon { font-size: 42px; margin-bottom: 16px; line-height: 1; }
.svc__title { font-size: 20px; font-weight: 800; margin-bottom: 10px; }
.svc__desc { font-size: 14.5px; color: var(--muted); }

/* ── CTA ── */
.cta { padding-block: clamp(42px, 5vw, 68px); text-align: center; }
.cta__inner { max-width: 640px; padding: clamp(40px, 6vw, 64px); border-radius: 24px;
    background: radial-gradient(ellipse at 50% 0%, rgba(108, 99, 255, 0.22), var(--surface) 70%);
    border: 1px solid var(--border-lit); box-shadow: var(--shadow), 0 0 80px rgba(108, 99, 255, 0.16); }
.cta__title { font-size: clamp(28px, 4vw, 44px); font-weight: 900; margin-bottom: 14px; }
.cta__sub { font-size: 17px; color: var(--muted); margin-bottom: 30px; }
.cta__note { font-size: 13px; color: var(--faint); margin-top: 16px; line-height: 1.7; }
.cta__ver { display: inline-block; margin-top: 4px; padding: 3px 12px; border-radius: 999px;
    background: rgba(108, 99, 255, 0.14); border: 1px solid var(--border-lit); color: var(--accent-3); font-weight: 700; }

/* ── Footer ── */
.footer { border-top: 1px solid var(--border); background: rgba(5, 5, 11, 0.6);
    padding-top: 52px; margin-top: 40px; }
.footer__inner { display: flex; align-items: flex-start; justify-content: space-between; gap: 40px; flex-wrap: wrap; padding-bottom: 40px; }
.footer__col { padding-top: 4px; }
.footer__brand { font-size: 20px; font-weight: 800; margin-bottom: 8px; }
.footer__logo { width: 200px; max-width: 60vw; height: auto; margin-bottom: 6px; }
.footer__tag { color: var(--muted); font-size: 14px; }
.footer__col h3 { font-size: 15px; margin-bottom: 12px; color: var(--text); }
.footer__col p { color: var(--muted); font-size: 14px; margin-bottom: 6px; }
.footer__col a:hover { color: var(--accent-2); }
.footer__bottom { display: flex; justify-content: space-between; align-items: center;
    padding-block: 22px; border-top: 1px solid var(--border); color: var(--faint); font-size: 13px; flex-wrap: wrap; gap: 10px; }
.footer__admin { color: var(--faint); font-size: 12.5px; }
.footer__admin:hover { color: var(--muted); }

/* ── Legal / content page ── */
.legal-page { padding-block: clamp(40px, 7vw, 80px); min-height: 60vh; }
.legal-page__card { max-width: 820px; margin-inline: auto; padding: clamp(28px, 5vw, 52px);
    border-radius: 20px; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow); }
.legal-page__title { font-size: clamp(26px, 4vw, 38px); font-weight: 900; margin-bottom: 22px;
    padding-bottom: 18px; border-bottom: 1px solid var(--border); }
.legal-page__body { font-size: 16px; line-height: 1.9; color: var(--muted); }

/* ── Addresses inside document text ──
   Emails and links in the legal documents are rendered as real links (see
   e_rich_bidi in bootstrap.php). The contact address is the one line of an
   accessibility statement a reader is actually looking for - a law requires it to
   be there and a person in difficulty has to be able to act on it - so it is a
   button-sized target rather than a run of text they have to select and copy. */
.richlink { color: var(--accent-2); text-decoration: underline; text-underline-offset: 3px; font-weight: 600; }
.richlink:hover { color: var(--fg); }
.richlink--mail {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 5px 14px; margin: 2px 0;
    border-radius: 999px;
    border: 1px solid rgba(108, 99, 255, 0.45);
    background: rgba(108, 99, 255, 0.14);
    color: var(--fg);
    font-size: 1.02em; font-weight: 700;
    text-decoration: none;
    transition: background 0.16s ease, border-color 0.16s ease, transform 0.12s ease;
}
.richlink--mail:hover {
    background: rgba(108, 99, 255, 0.28);
    border-color: var(--accent);
    transform: translateY(-1px);
}
.richlink--mail:active { transform: none; }
.richlink--mail:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.richlink__ico { font-size: 0.95em; line-height: 1; opacity: 0.85; }

/* ── Legal document window (draggable; accessibility / terms / privacy) ── */
.lmodal { position: fixed; inset: 0; z-index: 9500; display: flex; align-items: center; justify-content: center; padding: 24px; }
.lmodal[hidden] { display: none; }
.lmodal__backdrop { position: absolute; inset: 0; background: rgba(4, 4, 10, 0.6);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); animation: lm-fade 0.22s ease; }
.lmodal__card { position: relative; display: flex; flex-direction: column; width: min(680px, 100%); max-height: min(70vh, 560px);
    border-radius: 20px; overflow: hidden; background: rgba(18, 18, 32, 0.97);
    border: 1px solid var(--border-lit); box-shadow: var(--shadow), 0 0 80px rgba(108, 99, 255, 0.18);
    animation: lm-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); }
.lmodal__card.is-dragging { animation: none; cursor: grabbing; user-select: none; box-shadow: var(--shadow), 0 0 110px rgba(108, 99, 255, 0.3); }
@keyframes lm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lm-in { from { opacity: 0; transform: translateY(18px) scale(0.97); } to { opacity: 1; transform: none; } }

.lmodal__head { position: relative; display: flex; align-items: center; gap: 12px;
    padding: 16px 22px; border-bottom: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(108, 99, 255, 0.14), transparent); flex-shrink: 0; }
.lmodal__head::before { content: ''; position: absolute; inset-inline: 0; top: 0; height: 3px;
    background: linear-gradient(90deg, transparent, var(--accent), var(--accent-2), transparent); }
/* The title bar doubles as the drag handle (pointer devices only). */
@media (min-width: 721px) and (pointer: fine) {
    .lmodal__head[data-ldrag] { cursor: grab; touch-action: none; }
    .lmodal__card.is-dragging .lmodal__head[data-ldrag] { cursor: grabbing; }
}
.lmodal__grip { display: none; flex-shrink: 0; color: var(--faint); }
@media (min-width: 721px) and (pointer: fine) { .lmodal__grip { display: inline-flex; } }
.lmodal__title { flex: 1; min-width: 0; font-family: var(--font-head); font-size: clamp(18px, 2.6vw, 23px); font-weight: 800; margin: 0; }
.lmodal__x { flex-shrink: 0; width: 40px; height: 40px; border-radius: 11px; cursor: pointer; font-size: 16px;
    background: var(--surface-2); border: 1px solid var(--border); color: var(--muted); transition: background 0.15s, color 0.15s, transform 0.06s; }
.lmodal__x:hover { background: rgba(248, 113, 113, 0.16); border-color: rgba(248, 113, 113, 0.4); color: #fca5a5; }
.lmodal__x:active { transform: scale(0.94); }
.lmodal__x:focus-visible, .lmodal__foot .btn:focus-visible,
.cookiebar__ok:focus-visible, .cookiebar__link:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.lmodal__body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 20px 24px;
    font-size: 15px; line-height: 1.85; color: var(--muted); }
.lmodal__body:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--border-lit); }
/* Styled scrollbar */
.lmodal__body { scrollbar-width: thin; scrollbar-color: rgba(108, 99, 255, 0.7) rgba(255, 255, 255, 0.05); }
.lmodal__body::-webkit-scrollbar { width: 12px; }
.lmodal__body::-webkit-scrollbar-track { margin: 10px 0; border-radius: 999px;
    background: rgba(255, 255, 255, 0.05); border: 4px solid transparent; background-clip: content-box; }
.lmodal__body::-webkit-scrollbar-thumb { border-radius: 999px; border: 3px solid transparent; background-clip: content-box;
    background-image: linear-gradient(180deg, var(--accent-3), var(--accent)); }
.lmodal__body::-webkit-scrollbar-thumb:hover { background-image: linear-gradient(180deg, var(--accent-2), var(--accent-3)); }

.lmodal__foot { display: flex; justify-content: center; padding: 16px 24px 20px; border-top: 1px solid var(--border); flex-shrink: 0; }
.lmodal__foot .btn { min-width: 180px; }

@media (max-width: 560px) {
    .lmodal { padding: 14px; }
    .lmodal__card { max-height: 85vh; }
    .lmodal__head, .lmodal__body, .lmodal__foot { padding-inline: 18px; }
}

/* ── Cookie / privacy notice (first visit only) ── */
.cookiebar { position: fixed; inset-inline: 0; bottom: 0; z-index: 9400; padding: 0 16px 16px;
    animation: cookiebar-in 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.cookiebar[hidden] { display: none; }
.cookiebar__inner { display: flex; align-items: center; gap: 18px; max-width: var(--maxw); margin-inline: auto;
    padding: 16px 22px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border-lit);
    box-shadow: var(--shadow), 0 0 60px rgba(108, 99, 255, 0.16);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
.cookiebar__ico { flex-shrink: 0; font-size: 26px; line-height: 1; }
.cookiebar__msg { flex: 1; min-width: 0; }
.cookiebar__text { margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--muted); }
.cookiebar__link { display: inline-block; margin-top: 4px; font-size: 14px; font-weight: 700;
    color: var(--accent-3); text-decoration: underline; text-underline-offset: 3px; }
.cookiebar__link:hover { color: var(--accent-2); }
.cookiebar__ok { flex-shrink: 0; padding: 11px 26px; font-size: 15px; }
@keyframes cookiebar-in { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* While the notice is up, lift the floating buttons so nothing is covered.
   The class sits on <html> - the accessibility widget is appended there, not
   to <body>, so a body-scoped selector would never reach it. */
html.has-cookiebar .fab--top.fab--bottom-end,
html.has-cookiebar .fab--top.fab--bottom-start,
html.has-cookiebar .a11y--bottom-start,
html.has-cookiebar .a11y--bottom-end { bottom: calc(20px + var(--cookiebar-h, 96px)); }

@media (max-width: 720px) {
    .cookiebar { padding: 0 10px 10px; }
    .cookiebar__inner { flex-wrap: wrap; gap: 12px; padding: 15px 18px; }
    .cookiebar__ico { font-size: 22px; }
    .cookiebar__text { font-size: 13.5px; }
    .cookiebar__ok { width: 100%; }
}

/* ── Downloads page ── */
.dl-page { padding-block: clamp(36px, 6vw, 64px); min-height: 60vh; }
.dl-head { text-align: center; max-width: 680px; margin: 0 auto clamp(28px, 4vw, 44px); }
.dl-title { font-family: var(--font-head); font-size: clamp(28px, 4vw, 42px); font-weight: 900; margin-bottom: 12px; }
.dl-sub { font-size: 16px; color: var(--muted); line-height: 1.6; }
.dl-empty { max-width: 560px; margin: 40px auto; padding: 40px; text-align: center; border-radius: 18px;
    background: var(--surface); border: 1px dashed var(--border); color: var(--muted); font-size: 16px; }
.dl-foot { text-align: center; margin-top: 22px; font-size: 13px; color: var(--faint); }

/* Latest-version hero */
.dl-hero { position: relative; max-width: 660px; margin: 0 auto clamp(40px, 6vw, 60px); padding: clamp(30px, 5vw, 54px); text-align: center;
    border-radius: 26px; overflow: hidden;
    background: radial-gradient(ellipse at 50% -10%, rgba(108, 99, 255, 0.26), var(--surface) 72%);
    border: 1px solid var(--border-lit); box-shadow: var(--shadow), 0 0 90px rgba(108, 99, 255, 0.18); }
.dl-hero::before { content: ''; position: absolute; inset: 0; pointer-events: none;
    background-image: linear-gradient(rgba(108, 99, 255, 0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(108, 99, 255, 0.06) 1px, transparent 1px);
    background-size: 40px 40px; mask-image: radial-gradient(ellipse 70% 60% at 50% 0%, #000, transparent 75%);
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 0%, #000, transparent 75%); }
.dl-hero > * { position: relative; }
.dl-hero__badge { display: inline-block; padding: 6px 16px; border-radius: 999px; font-size: 13px; font-weight: 800;
    background: rgba(108, 99, 255, 0.16); border: 1px solid var(--border-lit); color: var(--accent-3); margin-bottom: 16px; }
.dl-hero__ver { font-family: var(--font-head); font-size: clamp(42px, 8vw, 68px); font-weight: 900; line-height: 1;
    background: linear-gradient(135deg, var(--accent-3), var(--accent-2)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.dl-hero__os { margin-top: 10px; font-size: 14px; font-weight: 600; color: var(--muted); }
.dl-hero__badge { justify-content: center; }
.dl-hero__notes { margin: 22px auto 4px; max-width: 480px; text-align: start; padding: 16px 18px; border-radius: 14px;
    background: var(--surface-2); border: 1px solid var(--border); }
.dl-hero__notes-label { display: block; font-size: 12.5px; font-weight: 800; color: var(--accent-3); margin-bottom: 6px; letter-spacing: 0.02em; }
.dl-hero__notes p { font-size: 14.5px; color: var(--muted); line-height: 1.65; margin: 0; }
.dl-hero__btn { margin-top: 26px; padding: 16px 46px; font-size: 17px; }
.dl-hero__meta { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 22px; }
.dl-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px; font-size: 13px; font-weight: 600;
    color: var(--muted); background: var(--surface-2); border: 1px solid var(--border); }
.dl-trust { display: flex; flex-wrap: wrap; gap: 8px 18px; justify-content: center; margin-top: 20px;
    padding-top: 20px; border-top: 1px solid var(--border); }
.dl-trust__item { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.dl-sha { display: flex; align-items: center; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 16px; }
.dl-sha__label { font-size: 11px; font-weight: 800; letter-spacing: 0.06em; color: var(--faint); }
.dl-sha__val { font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace; font-size: 10.5px; color: var(--muted);
    background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 5px 9px; word-break: break-all; max-width: 100%;
    user-select: all; }

/* Previous versions - release cards */
/* How-to-install - step by step */
.dl-install { max-width: 760px; margin: 52px auto 8px; }
.dl-install__title { font-family: var(--font-head); font-size: 22px; font-weight: 800; text-align: center; margin: 0 0 6px; color: var(--text); }
.dl-install__sub { text-align: center; color: var(--muted); font-size: 14px; margin: 0 0 24px; }
.dl-install__steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.dl-install__step { display: flex; align-items: flex-start; gap: 16px;
    padding: 16px 20px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border);
    transition: border-color 0.16s, transform 0.16s, box-shadow 0.16s; }
.dl-install__step:hover { border-color: var(--border-lit); transform: translateY(-2px); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.22); }
.dl-install__num { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
    font-family: var(--font-head); font-weight: 900; font-size: 16px; color: #fff;
    background: linear-gradient(135deg, #5d54f0, #4a42d4); box-shadow: 0 6px 16px rgba(108, 99, 255, 0.4); }
.dl-install__body { flex: 1; min-width: 0; }
.dl-install__step-title { font-family: var(--font-head); font-size: 16px; font-weight: 800; color: var(--text); margin: 0 0 3px; }
.dl-install__step-text { font-size: 14px; line-height: 1.6; color: var(--muted); margin: 0; }
.dl-install__art { flex: 0 0 auto; width: 58px; height: 58px; align-self: center; }
.dl-install__art svg { width: 100%; height: 100%; display: block; }
@media (max-width: 560px) {
    .dl-install__step { gap: 12px; padding: 14px 16px; }
    .dl-install__art { width: 44px; height: 44px; }
}

/* ── System requirements ── */
.dl-req { max-width: 760px; margin: 46px auto 8px; }
.dl-req__title { font-family: var(--font-head); font-size: 22px; font-weight: 800; color: var(--text);
    display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 0 6px; }
.dl-req__title .gly { color: var(--accent); }
.dl-req__sub { max-width: 620px; margin: 0 auto 22px; text-align: center; color: var(--muted); font-size: 14px; line-height: 1.65; }
.dl-req__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.dl-req__item { display: flex; align-items: flex-start; gap: 13px;
    padding: 15px 18px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border);
    transition: border-color 0.16s, transform 0.16s, box-shadow 0.16s; }
.dl-req__item:hover { border-color: var(--border-lit); transform: translateY(-2px); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.22); }
.dl-req__ico { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center;
    color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); }
.dl-req__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dl-req__label { font-family: var(--font-head); font-size: 14.5px; font-weight: 800; color: var(--text); }
.dl-req__value { font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.dl-req__note { display: flex; align-items: center; justify-content: center; gap: 8px;
    margin: 18px auto 0; max-width: 620px; text-align: center;
    font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.dl-req__note .gly { color: var(--accent); flex-shrink: 0; }
@media (max-width: 640px) {
    .dl-req__grid { grid-template-columns: 1fr; }
}

/* ── The browser's warning, one panel per browser ── */
.dl-warn { max-width: 760px; margin: 46px auto 8px; }
.dl-warn__title { font-family: var(--font-head); font-size: 22px; font-weight: 800; color: var(--text);
    display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 0 6px; }
.dl-warn__title .gly { color: var(--accent-3); }
.dl-warn__sub { max-width: 620px; margin: 0 auto 22px; text-align: center; color: var(--muted); font-size: 14px; line-height: 1.65; }
.dl-warn__list { display: flex; flex-direction: column; gap: 12px; }
.dl-warn__item { border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border);
    overflow: hidden; transition: border-color 0.16s, box-shadow 0.16s; }
.dl-warn__item:hover { border-color: var(--border-lit); }
.dl-warn__item[open] { border-color: var(--border-lit); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.22); }
/* display:flex is what removes Chrome's marker triangle; list-style covers Firefox
   and the ::-webkit- rule covers Safari. All three, or one browser keeps its own
   arrow beside ours. */
.dl-warn__head { display: flex; align-items: center; gap: 12px; padding: 15px 20px; cursor: pointer; list-style: none;
    font-family: var(--font-head); font-size: 16px; font-weight: 800; color: var(--text); }
.dl-warn__head::-webkit-details-marker { display: none; }
/* The direct child is the browser mark, which is the accent one. The chevron is a
   .gly too, one level deeper, and had been swept up by a plain descendant rule. */
.dl-warn__head > .gly { flex: 0 0 auto; color: var(--accent-3); }
.dl-warn__chev .gly { color: var(--muted); }
.dl-warn__name { flex: 1; min-width: 0; }
/* The chevron is an element of its own rather than a mark inside the name: bidi
   both places and mirrors anything sitting in the text, so an arrow written into
   the label lands on the wrong side of a Hebrew line. A flex item is placed by the
   layout instead, which is the same end whichever way the page runs. */
.dl-warn__chev { flex: 0 0 auto; display: flex; color: var(--muted); transition: transform 0.18s ease; }
.dl-warn__item[open] .dl-warn__chev { transform: rotate(180deg); }
.dl-warn__body { padding: 0 20px 18px; }
.dl-warn__quote { margin: 0 0 12px; font-size: 13.5px; line-height: 1.6; color: var(--faint); }
.dl-warn__quote q { color: var(--text); }
.dl-warn__steps { margin: 0; padding-inline-start: 20px; display: flex; flex-direction: column; gap: 7px;
    font-size: 14px; line-height: 1.65; color: var(--muted); }
.dl-warn__foot { max-width: 660px; margin: 18px auto 0; text-align: center; font-size: 13.5px; line-height: 1.7; color: var(--faint); }
.dl-warn__foot .gly { color: var(--accent-2); vertical-align: -3px; margin-inline-end: 5px; }
@media (max-width: 560px) {
    .dl-warn__head { padding: 13px 16px; font-size: 15px; }
    .dl-warn__body { padding: 0 16px 15px; }
}

.dl-prev-title { font-family: var(--font-head); font-size: 22px; font-weight: 800; text-align: center; margin: 8px 0 20px; color: var(--text); }
.dl-releases { max-width: 820px; margin-inline: auto; display: flex; flex-direction: column; gap: 12px; }
.dl-rel { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    padding: 18px 22px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border);
    transition: border-color 0.16s, transform 0.16s, box-shadow 0.16s; }
.dl-rel:hover { border-color: var(--border-lit); transform: translateY(-2px); box-shadow: 0 14px 40px rgba(0, 0, 0, 0.28); }
.dl-rel__main { flex: 1 1 320px; min-width: 0; }
.dl-rel__top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.dl-rel__ver { font-family: var(--font-head); font-size: 18px; font-weight: 900; color: var(--text); }
.dl-rel__date, .dl-rel__size { font-size: 12.5px; font-weight: 600; color: var(--faint); }
.dl-rel__notes { margin: 8px 0 0; font-size: 13.5px; color: var(--muted); line-height: 1.55; }
.dl-rel__action { flex-shrink: 0; }
.dl-rel__gone { font-size: 12.5px; color: var(--faint); font-style: italic; }

/* ── Scroll reveal ── */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s ease, transform 0.7s ease; }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .bg__grid, .bg__glow { animation: none; }
}

/* ── Responsive ── */
@media (max-width: 900px) {
    .hero { grid-template-columns: 1fr; gap: 40px; text-align: center; }
    .hero__subtitle { margin-inline: auto; }
    .hero__cta, .hero__stats { justify-content: center; }
    .grid--3 { grid-template-columns: 1fr 1fr; }
    .steps { grid-template-columns: 1fr 1fr; }
    .step:not(:last-child)::after { display: none; }
    .shot, .shot:nth-child(even) { grid-template-columns: 1fr; direction: inherit; }
    .nav__links { display: none; }
    .nav__inner { gap: 12px; }
    .nav__brand { min-width: 0; flex: 1 1 auto; }
    .nav__name { white-space: nowrap; font-size: 16px; overflow: hidden; text-overflow: ellipsis; }
    .nav__actions { flex: none; }
}
@media (max-width: 560px) {
    .grid--3 { grid-template-columns: 1fr; }
    .steps { grid-template-columns: 1fr; }
    .hero__stats { gap: 22px; }
    /* free up room so the brand name fits on one line */
    .nav__actions .btn--primary { display: none; }
    .nav__logo { width: 32px; height: 32px; }
    .nav__name { font-size: 15px; }
    .nav__actions { gap: 8px; }
}

/* ── A word before the download ──────────────────────────────────────────────
   Sits over the download page from the moment the file is asked for. Deliberately
   quiet in tone: this is a note from the publisher, not a warning, so it takes the
   page's own card language rather than an alert palette. */
/* Above the cookie bar (9400) and the floating buttons (8000), which were both
   painting over the checkbox and the download button, and below the legal windows
   (9500) so an agreement opened from inside this dialog still lands on top. */
.dln { position: fixed; inset: 0; z-index: 9450; display: flex; align-items: center; justify-content: center; padding: 22px; }
.dln[hidden] { display: none; }
.dln__backdrop { position: absolute; inset: 0; background: rgba(6, 8, 18, .72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.dln__card {
    position: relative;
    width: min(520px, 100%);
    /* Never taller than the space it is given. The dialog's own padding is part
       of that space, hence 100% of the flex line rather than a viewport unit. */
    max-height: 100%;
    display: flex; flex-direction: column;
    border-radius: 20px; text-align: center; overflow: hidden;
    background: radial-gradient(120% 90% at 50% 0%, rgba(108, 99, 255, .14), transparent 60%), var(--surface, #14161f);
    border: 1px solid var(--border-strong, rgba(255, 255, 255, .12));
    box-shadow: 0 28px 80px rgba(0, 0, 0, .55);
    animation: dln-in .24s cubic-bezier(.22, 1, .36, 1) both;
}
/* Pinned. A long notice on a short screen used to scroll the title away and push
   the checkbox and the button out of sight - the two things the screen is for. */
.dln__head { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 28px 28px 14px; }
.dln__foot { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 14px 28px 22px; }
/* A hairline that appears only when the message actually scrolls under it. */
.dln__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 28px 4px; }
@keyframes dln-in { from { opacity: 0; transform: translateY(14px) scale(.98); } to { opacity: 1; transform: none; } }

.dln__ico {
    width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
    font-size: 27px; background: rgba(108, 99, 255, .14); border: 1px solid rgba(108, 99, 255, .32);
}
.dln__title { margin: 0; font-size: 1.28rem; font-weight: 800; color: var(--txt, #eef1f7); }
/* The card is centred but the message is not: a notice can run to several lines,
   and centred prose forces the eye to find the start of each one. Aligned to the
   reading edge it scans like text. A single short line still looks centred,
   because the block itself is. */
.dln__body { font-size: .95rem; line-height: 1.75; color: var(--txt-2, #aeb6c6); text-align: start; }
.dln__body > * { max-width: 42ch; margin-inline: auto; }
.dln__body a { color: var(--accent, #8b85ff); }

/* The checkbox. A real input, visually hidden, with the box drawn beside it - so
   it keeps native keyboard behaviour and the label stays clickable. */
.dln__agree { display: flex; align-items: center; gap: 11px; cursor: pointer; padding: 9px 15px; border-radius: 12px; border: 1px solid transparent; transition: background .15s ease, border-color .15s ease; }
.dln__agree:hover { background: rgba(255, 255, 255, .04); }
.dln__agree input { position: absolute; opacity: 0; width: 0; height: 0; }
.dln__box {
    flex-shrink: 0; width: 22px; height: 22px; border-radius: 7px;
    display: grid; place-items: center;
    border: 1.6px solid var(--border-strong, rgba(255, 255, 255, .22));
    background: rgba(255, 255, 255, .04);
    color: transparent;
    transition: background .16s ease, border-color .16s ease, color .16s ease, transform .12s ease;
}
.dln__agree:hover .dln__box { border-color: var(--accent, #6c63ff); }
.dln__agree input:checked + .dln__box { background: var(--accent, #6c63ff); border-color: var(--accent, #6c63ff); color: #fff; }
.dln__agree input:focus-visible + .dln__box { outline: 2px solid var(--accent, #6c63ff); outline-offset: 3px; }
.dln__agree input:active + .dln__box { transform: scale(.92); }
.dln__agree-txt { font-size: .93rem; font-weight: 600; color: var(--txt, #eef1f7); }

.dln__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 2px; }
/* Not `disabled`: an anchor cannot be, and a real button here would lose the
   browser's own download handling. It is inert until the box is ticked, and says
   so to assistive technology through aria-disabled. */
.dln__go { pointer-events: none; opacity: .45; filter: saturate(.5); transition: opacity .18s ease, filter .18s ease; }
.dln__go.is-ready { pointer-events: auto; opacity: 1; filter: none; }

@media (max-width: 560px) {
    .dln { padding: 12px; }
    .dln__head { padding: 22px 18px 12px; }
    .dln__body { padding: 0 18px 4px; }
    .dln__foot { padding: 12px 18px 18px; }
    .dln__title { font-size: 1.12rem; }
}
/* A short window - a laptop with the browser's toolbars, or a rotated tablet.
   The icon is the first thing to go: it is decoration, and the message is not. */
@media (max-height: 640px) {
    .dln { padding: 10px; }
    .dln__ico { display: none; }
    .dln__head { padding: 18px 22px 10px; }
    .dln__foot { padding: 10px 22px 16px; gap: 9px; }
    .dln__title { font-size: 1.08rem; }
    .dln__body { font-size: .9rem; line-height: 1.65; }
}
@media (prefers-reduced-motion: reduce) {
    .dln__card { animation: none; }
}

/* The agreements, offered at the moment consent is asked for. Quiet by design -
   they are a reference the reader may want, not a second call to action
   competing with the download button below them. */
.dln__legal {
    display: flex; align-items: center; justify-content: center; gap: 4px 10px; flex-wrap: wrap;
    padding: 6px 10px; border-radius: 9px;
    background: rgba(255, 255, 255, .025);
    border: 1px solid var(--border, rgba(255, 255, 255, .08));
}
.dln__legal-lead { font-size: .72rem; font-weight: 700; color: var(--txt-3, #7c869b); }
.dln__legal-link {
    font-size: .76rem; font-weight: 600; color: var(--accent, #8b85ff);
    text-decoration: none; border-bottom: 1px solid transparent;
    transition: border-color .15s ease, color .15s ease;
}
.dln__legal-link:hover, .dln__legal-link:focus-visible { border-bottom-color: currentColor; }
@media (max-height: 640px) {
    .dln__legal { padding: 5px 8px; gap: 3px 9px; }
    .dln__legal-link, .dln__legal-lead { font-size: .72rem; }
}

/* ===== Fault finding: the sweep that says what is wrong =====
   The first two-column band on the page, so it sets the rhythm the tools band
   and the bell then alternate against: words on the start edge, the drawing on
   the end edge.

   Rose rather than the purple of the bell or the cyan of the internet band,
   because this is the section about something being broken - and the one colour
   inside the card that is NOT rose is the green on the line that says the repair
   was verified, which is the whole argument of the section in one contrast.

   Everything here is drawn from elements. See the note over the section in
   index.php for why an SVG would be wrong. */
.docband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.docband__inner {
    /* The card is a compact result panel rather than a wide screenshot, so the
       words take the larger share - the same split as the internet band. */
    display: grid; grid-template-columns: 1.1fr 0.9fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.docband__copy { display: flex; flex-direction: column; gap: 14px; }
.docband__art { margin: 0; }
.docband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(248, 113, 113, 0.42);
    background: rgba(248, 113, 113, 0.10);
    font-size: 12.5px; font-weight: 800; color: var(--danger);
}
.docband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.docband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.docband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.docband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.docband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.docband__points .gly { flex-shrink: 0; margin-top: 2px; color: var(--danger); }

.docband__card {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: var(--shadow);
}
.docband__bar { display: flex; gap: 6px; padding: 10px 14px; background: var(--surface-2); border-bottom: 1px solid var(--border); }
.docband__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.docband__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.docband__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.docband__body { padding: 18px; display: flex; flex-direction: column; gap: 15px; }

/* ── The verdict ── */
.docband__verdict { display: flex; align-items: center; gap: 14px; }
.docband__score { position: relative; width: 64px; height: 64px; flex-shrink: 0; display: grid; place-items: center; }
/* The ring is drawn from the top and clockwise in both directions of the page:
   a score is a quantity, not a sentence, and mirroring it would make the same
   number look like a different one. */
.docband__ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.docband__ring-track { fill: none; stroke: var(--surface-2); stroke-width: 7; }
.docband__ring-arc {
    fill: none; stroke: #fbbf24; stroke-width: 7; stroke-linecap: round;
    /* r=34, so the circumference is 213.6. 67 of it is 143.1. */
    stroke-dasharray: 143.1 213.6;
}
.docband__score-num { position: relative; font-size: 21px; font-weight: 900; color: #fbbf24; }
.docband__verdict-txt { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.docband__verdict-txt strong { font-size: 15px; font-weight: 800; color: var(--text); }
.docband__vchips { display: flex; flex-wrap: wrap; gap: 6px; }
.docband__vchip {
    padding: 3px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
    border: 1px solid var(--border); color: var(--muted);
}
.docband__vchip--crit { border-color: rgba(248, 113, 113, 0.4); background: rgba(248, 113, 113, 0.10); color: var(--danger); }
.docband__vchip--warn { border-color: rgba(251, 191, 36, 0.4); background: rgba(251, 191, 36, 0.10); color: #fbbf24; }

/* ── The findings ── */
.docband__finds { display: flex; flex-direction: column; }
.docband__find {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 2px; border-top: 1px solid var(--border);
}
.docband__find:first-child { border-top: 0; }
.docband__dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 6px; background: var(--faint); }
.docband__find--crit .docband__dot { background: var(--danger); box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.16); }
.docband__find--warn .docband__dot { background: #fbbf24; box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.14); }
/* Full width, not shrink-to-fit. Left to itself the block took the width of
   whichever of its two lines was longer, so a short sentence and a long reading
   ended up hugging opposite edges of a box only as wide as the reading -
   staggered, for no reason a reader could see. */
.docband__find-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.docband__find-txt strong { font-size: 13.5px; font-weight: 700; color: var(--text); line-height: 1.45; }
/* The reading sits under the sentence it belongs to and starts where that
   sentence starts - so the element keeps the PAGE's direction and the value
   inside it carries its own, as a <bdi dir="ltr">. Forcing the element itself to
   left-to-right would align it against the far edge on a Hebrew page, which is
   the one place a reader is not looking. */
.docband__ev {
    font-size: 12px; color: var(--faint);
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
    text-align: start;
}

/* ── The line the screen exists for ── */
.docband__done {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 12px; border-radius: var(--radius-sm);
    border: 1px solid rgba(74, 222, 128, 0.36); background: rgba(74, 222, 128, 0.10);
    font-size: 12.5px; font-weight: 700; color: #4ade80;
}
.docband__done .gly { flex-shrink: 0; }

.docband__chips { display: flex; flex-wrap: wrap; gap: 7px; }
.docband__chip {
    padding: 4px 11px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
    border: 1px solid var(--border); color: var(--muted);
}
.docband__chip--more { border-style: dashed; color: var(--faint); }

@media (max-width: 860px) {
    .docband__inner { grid-template-columns: 1fr; }
}

/* On a light page the green of the verified line goes pale against white, and
   the ring's amber with it - both are stated again a shade deeper rather than
   left to the dark-theme values. */
:root[data-theme="light"] .docband__done { color: #15803d; border-color: rgba(21, 128, 61, 0.34); background: rgba(21, 128, 61, 0.08); }
:root[data-theme="light"] .docband__ring-arc,
:root[data-theme="light"] .docband__score-num { stroke: #b45309; color: #b45309; }
:root[data-theme="light"] .docband__vchip--warn { color: #b45309; border-color: rgba(180, 83, 9, 0.38); background: rgba(180, 83, 9, 0.08); }
:root[data-theme="light"] .docband__find--warn .docband__dot { background: #b45309; }
:root[data-theme="light"] .docband__eyebrow,
:root[data-theme="light"] .docband__points .gly { color: #b91c1c; }
:root[data-theme="light"] .docband__vchip--crit { color: #b91c1c; border-color: rgba(185, 28, 28, 0.36); background: rgba(185, 28, 28, 0.07); }
:root[data-theme="light"] .docband__find--crit .docband__dot { background: #b91c1c; }

/* ── The assistant carries things out ──────────────────────────────────────
   Built to the same shape as the fault-finding band above it, and for the same
   reason: the two are one argument in two halves - here is what is wrong, here
   is the thing that goes and fixes it - so they should not look like two
   different kinds of block. Drawn from elements, never an SVG; see the note
   over the section in index.php.

   The accent is the app's own primary rather than the fault band's red: this
   one is not a warning about anything. */
.askband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.askband__inner {
    /* The conversation card is a phone-shaped panel, not a screenshot, so the
       words take the larger share - the same split as the band above. */
    display: grid; grid-template-columns: 1.1fr 0.9fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.askband__copy { display: flex; flex-direction: column; gap: 14px; }
.askband__art { margin: 0; }
.askband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(108, 99, 255, 0.42);
    background: rgba(108, 99, 255, 0.10);
    font-size: 12.5px; font-weight: 800; color: var(--accent);
}
.askband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.askband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }

/* ── What people actually say ──
   Four sentences in somebody's own words, sized so they read as speech rather
   than as a feature list - which is the whole claim being made. */
.askband__says { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.askband__quote {
    display: inline-block;
    padding: 7px 13px; border-radius: 999px;
    border: 1px solid var(--border-lit); background: var(--surface-2);
    font-size: 13px; font-weight: 600; color: var(--text);
}

.askband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.askband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.askband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.askband__points .gly { flex-shrink: 0; margin-top: 2px; color: var(--accent); }

.askband__card {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: var(--shadow);
}
.askband__bar { display: flex; gap: 6px; padding: 10px 14px; background: var(--surface-2); border-bottom: 1px solid var(--border); }
.askband__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.askband__bar span:first-child { background: rgba(108, 99, 255, 0.7); }
.askband__bar span:nth-child(2) { background: rgba(74, 222, 128, 0.6); }
.askband__body { padding: 18px; display: flex; flex-direction: column; gap: 12px; }

/* ── The two bubbles ──
   Aligned to the start and end edges of the page rather than to left and right,
   so the person speaks from the side they read from in both directions. */
.askband__msg { display: flex; }
.askband__msg--me { justify-content: flex-end; }
.askband__msg--ai { justify-content: flex-start; }
.askband__bubble {
    max-width: 82%;
    padding: 9px 13px; border-radius: 14px;
    font-size: 13.5px; line-height: 1.55;
}
.askband__msg--me .askband__bubble {
    background: var(--accent); color: #fff; font-weight: 600;
    border-end-end-radius: 5px;
}
.askband__msg--ai .askband__bubble {
    background: var(--surface-2); color: var(--text);
    border: 1px solid var(--border);
    border-end-start-radius: 5px;
}

/* ── What is about to happen, named in full ──
   The card the app really puts up, and the point of the whole section: the
   program is identified before anything is done to it. */
.askband__confirm {
    display: flex; align-items: center; gap: 11px;
    padding: 11px 13px; border-radius: var(--radius-sm);
    border: 1px solid var(--border-lit); background: var(--surface-2);
}
.askband__confirm-ico { font-size: 20px; line-height: 1; flex-shrink: 0; }
.askband__confirm-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.askband__confirm-txt strong { font-size: 13.5px; font-weight: 800; color: var(--text); text-align: start; }
/* The line keeps the PAGE's direction and the values inside carry their own -
   the same rule as the readings in the band above, and for the same reason. */
.askband__confirm-meta {
    font-size: 11.5px; color: var(--faint); text-align: start;
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
}

.askband__acts { display: flex; gap: 8px; }
.askband__act {
    flex: 1; text-align: center;
    padding: 8px 12px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface-2);
    font-size: 12.5px; font-weight: 700; color: var(--muted);
}
.askband__act--go { border-color: transparent; background: var(--accent); color: #fff; }

.askband__chips { display: flex; flex-wrap: wrap; gap: 7px; padding-top: 2px; }
.askband__chip {
    padding: 4px 11px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
    border: 1px solid var(--border); color: var(--muted);
}
.askband__chip--more { border-style: dashed; color: var(--faint); }

@media (max-width: 860px) {
    .askband__inner { grid-template-columns: 1fr; }
}

/* On a light page the brand violet holds up, but the muted greys behind the
   quotes go flat against white - both are stated again a shade deeper, the same
   way the band above states its amber and green. */
:root[data-theme="light"] .askband__quote { border-color: rgba(17, 24, 39, 0.14); }
:root[data-theme="light"] .askband__eyebrow,
:root[data-theme="light"] .askband__points .gly { color: #4f46e5; }
:root[data-theme="light"] .askband__eyebrow { border-color: rgba(79, 70, 229, 0.34); background: rgba(79, 70, 229, 0.07); }


/* ── Numbers that do not lie ────────────────────────────────────
   Built to the shape of the two bands above it, and reversed: the drawing leads
   on this one. What it shows cannot be said in a sentence - that "empty" and
   "nobody looked" are two different things - but it can be drawn in one glance,
   which is exactly why the strip is here and the argument is beside it.

   Green rather than the fault band's red or the assistant's violet. It is the
   only band on the page that is not about something being wrong. */
.truthband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.truthband__inner {
    display: grid; grid-template-columns: 0.95fr 1.05fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
/* The drawing first in the source, so a phone meets the picture before the
   argument about it - and second on a wide page, where the eye starts from the
   copy. */
.truthband__art { margin: 0; order: 2; }
.truthband__copy { display: flex; flex-direction: column; gap: 14px; order: 1; }
.truthband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(52, 211, 153, 0.42);
    background: rgba(52, 211, 153, 0.10);
    font-size: 12.5px; font-weight: 800; color: #34d399;
}
.truthband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.truthband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.truthband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.truthband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.truthband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.truthband__points .gly { flex-shrink: 0; margin-top: 2px; color: #34d399; }

.truthband__card {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: var(--shadow);
    padding: 18px;
    display: flex; flex-direction: column; gap: 14px;
}
.truthband__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.truthband__head-t { font-size: 13.5px; font-weight: 800; color: var(--text); }
.truthband__pill {
    padding: 4px 12px; border-radius: 999px;
    border: 1px solid rgba(108, 99, 255, 0.45);
    background: rgba(108, 99, 255, 0.12);
    font-size: 11.5px; font-weight: 800; color: var(--accent);
}

/* ── The strip ──
   One column per day. A day with faults draws a bar; a day without draws an
   empty channel; a day the log does not reach draws a hatch - and the hatch is
   the whole point of the picture, because everywhere else it is drawn as the
   empty channel and counted as good news. */
.truthband__strip { display: flex; align-items: flex-end; gap: 5px; height: 92px; }
.truthband__day {
    flex: 1; height: 100%; border-radius: 5px;
    display: flex; align-items: flex-end;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.truthband__bar {
    display: block; width: 100%; border-radius: 4px;
    background: linear-gradient(180deg, #f87171, #ef4444);
}
/* Three heights as three classes. The site's policy blocks a style attribute,
   so a bar whose height is data has to have that data named here. */
.truthband__bar--h1 { height: 34%; }
.truthband__bar--h2 { height: 58%; }
.truthband__bar--h3 { height: 82%; }
.truthband__day--unread {
    border-style: dashed;
    background: repeating-linear-gradient(
        45deg,
        transparent 0 4px,
        rgba(148, 163, 184, 0.22) 4px 8px
    );
}

.truthband__legend {
    display: flex; flex-wrap: wrap; gap: 14px;
    font-size: 11.5px; color: var(--faint);
}
.truthband__legend span { display: inline-flex; align-items: center; gap: 6px; }
.truthband__key {
    width: 12px; height: 12px; border-radius: 4px; flex-shrink: 0;
    border: 1px solid var(--border); background: var(--surface-2);
}
.truthband__key--bad { background: #ef4444; border-color: transparent; }
.truthband__key--unread {
    border-style: dashed;
    background: repeating-linear-gradient(45deg, transparent 0 3px, rgba(148, 163, 184, 0.3) 3px 6px);
}

/* ── The two readings ──
   The same week counted the two ways, one over the other. The wrong one is not
   struck out or coloured red: it is simply quieter, because it is what every
   other tool would tell you and it looks perfectly reasonable until you know
   what is missing from it. */
.truthband__rows { display: flex; flex-direction: column; gap: 7px; }
.truthband__row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 9px 12px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface-2);
    font-size: 12.5px;
}
.truthband__row-l { color: var(--muted); text-align: start; }
.truthband__row-v {
    flex-shrink: 0; font-weight: 800; font-size: 13.5px;
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
}
.truthband__row--wrong { opacity: 0.62; }
.truthband__row--wrong .truthband__row-v { color: var(--faint); text-decoration: line-through; }
.truthband__row--right {
    border-color: rgba(52, 211, 153, 0.42);
    background: rgba(52, 211, 153, 0.09);
}
.truthband__row--right .truthband__row-l { color: var(--text); }
.truthband__row--right .truthband__row-v { color: #34d399; }
.truthband__note { font-size: 11.5px; line-height: 1.6; color: var(--faint); }

@media (max-width: 860px) {
    .truthband__inner { grid-template-columns: 1fr; }
    .truthband__art { order: 1; }
    .truthband__copy { order: 2; }
}

/* On a white page the mint reads as a highlighter, so the green is stated again
   a shade deeper - the same move the bands above make with their own accents. */
:root[data-theme="light"] .truthband__eyebrow,
:root[data-theme="light"] .truthband__points .gly,
:root[data-theme="light"] .truthband__row--right .truthband__row-v { color: #047857; }
:root[data-theme="light"] .truthband__eyebrow { border-color: rgba(4, 120, 87, 0.34); background: rgba(4, 120, 87, 0.07); }
:root[data-theme="light"] .truthband__row--right { border-color: rgba(4, 120, 87, 0.32); background: rgba(4, 120, 87, 0.06); }
:root[data-theme="light"] .truthband__day--unread {
    background: repeating-linear-gradient(45deg, transparent 0 4px, rgba(71, 85, 105, 0.18) 4px 8px);
}

/* ===== The drive sheet: what the drive says about itself ===== */
/* Cyan, and the only band on the page in it. The two beside it are the app
   talking about the machine; this one is a component talking about itself, and
   giving it the accent of neither neighbour is what says so at a glance.

   The sheet is a table of left-to-right values in right-to-left rows, so every
   value is a <bdi> in the markup and nothing here may set a direction. */
.driveband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.driveband__inner {
    /* The sheet is dense and wants room; the copy still leads, so the split is
       gentler than the bands with a picture beside them. */
    display: grid; grid-template-columns: 1fr 1fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.driveband__copy { display: flex; flex-direction: column; gap: 14px; }
.driveband__art { margin: 0; }
.driveband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(34, 211, 238, 0.42);
    background: rgba(34, 211, 238, 0.10);
    font-size: 12.5px; font-weight: 800; color: #22d3ee;
}
.driveband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.driveband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.driveband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.driveband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.driveband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.driveband__points .gly { flex-shrink: 0; margin-top: 2px; color: #22d3ee; }

.driveband__sheet {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: var(--shadow);
    display: flex; flex-direction: column;
}
.driveband__head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 13px 16px; background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.driveband__name { font-size: 13.5px; font-weight: 800; color: var(--text); }
.driveband__role {
    padding: 4px 11px; border-radius: 999px;
    border: 1px solid rgba(34, 211, 238, 0.42);
    background: rgba(34, 211, 238, 0.10);
    font-size: 11px; font-weight: 800; color: #22d3ee;
    white-space: nowrap;
}
/* Two columns of rows, the way the sheet itself is laid out - what the drive is
   on one side, what it has been through on the other. */
.driveband__cols { display: grid; grid-template-columns: 1fr 1fr; }
.driveband__col { padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; }
.driveband__col + .driveband__col { border-inline-start: 1px solid var(--border); }
.driveband__cap {
    font-size: 11px; font-weight: 800; letter-spacing: 0.02em;
    color: var(--faint); margin-bottom: 8px;
}
.driveband__row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    padding: 6px 0; border-top: 1px solid var(--border);
}
.driveband__row:first-of-type { border-top: 0; }
.driveband__k { font-size: 12px; color: var(--muted); }
.driveband__val { font-size: 12.5px; font-weight: 800; color: var(--text); }
/* The row the drawing exists for: a drive linked at half its lanes. */
.driveband__row--flag {
    margin: 4px -8px 0; padding: 7px 8px; border-radius: var(--radius-sm);
    border-top: 0;
    border: 1px solid rgba(251, 191, 36, 0.38);
    background: rgba(251, 191, 36, 0.09);
}
.driveband__val--warn { color: #fbbf24; }
/* A counter the drive refused. It is words, not a figure, so it is set as words
   - lighter and unemphasised, which is the whole point of not printing a zero. */
.driveband__val--said { font-size: 11.5px; font-weight: 600; color: var(--faint); }
.driveband__note {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 16px; border-top: 1px solid var(--border);
    font-size: 12px; line-height: 1.6; color: #fbbf24;
    background: rgba(251, 191, 36, 0.07);
}
.driveband__note .gly { flex-shrink: 0; margin-top: 1px; }
.driveband__foot {
    padding: 10px 16px; border-top: 1px solid var(--border);
    font-size: 11.5px; line-height: 1.6; color: var(--faint);
    background: var(--surface-2);
}

@media (max-width: 860px) {
    .driveband__inner { grid-template-columns: 1fr; }
}
/* Narrow enough and the two halves of the sheet stop being two columns: a key
   and its value on one line is the point, and 130px of column will not hold
   both. */
@media (max-width: 520px) {
    .driveband__cols { grid-template-columns: 1fr; }
    .driveband__col + .driveband__col { border-inline-start: 0; border-top: 1px solid var(--border); }
}

/* On a white page the cyan is a marker pen and the amber vanishes, so both are
   restated deeper - the same move every band above makes with its own accent. */
:root[data-theme="light"] .driveband__eyebrow,
:root[data-theme="light"] .driveband__points .gly,
:root[data-theme="light"] .driveband__role { color: #0e7490; }
:root[data-theme="light"] .driveband__eyebrow,
:root[data-theme="light"] .driveband__role { border-color: rgba(14, 116, 144, 0.34); background: rgba(14, 116, 144, 0.07); }
:root[data-theme="light"] .driveband__val--warn,
:root[data-theme="light"] .driveband__note { color: #b45309; }
:root[data-theme="light"] .driveband__row--flag { border-color: rgba(180, 83, 9, 0.34); background: rgba(180, 83, 9, 0.07); }
:root[data-theme="light"] .driveband__note { background: rgba(180, 83, 9, 0.06); }

/* ===== The bell: what the app finds without being asked ===== */
/* The same band as the tools above it, turned round - copy on one side and the
   screen on the other, alternating down the page. The accent is the app's own
   purple rather than the tools band's amber, because this is a screen you can
   open and not a set of things that float over one. */
.alertsband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.alertsband__inner {
    display: grid; grid-template-columns: 0.85fr 1.15fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
.alertsband__copy { display: flex; flex-direction: column; gap: 14px; }
.alertsband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(108, 99, 255, 0.42);
    background: rgba(108, 99, 255, 0.10);
    font-size: 12.5px; font-weight: 800; color: #a78bfa;
}
.alertsband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.alertsband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.alertsband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.alertsband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.alertsband__points strong {
    display: block; color: var(--text); font-weight: 800; margin-bottom: 2px;
}
.alertsband__points .gly { flex-shrink: 0; margin-top: 2px; color: #a78bfa; }

.alertsband__shot { margin: 0; }
.alertsband__frame {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.alertsband__bar { display: flex; gap: 6px; padding: 10px 14px; background: rgba(255, 255, 255, 0.03); border-bottom: 1px solid var(--border); }
.alertsband__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.alertsband__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.alertsband__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.alertsband__frame img { display: block; width: 100%; height: auto; }

@media (max-width: 860px) { .alertsband__inner { grid-template-columns: 1fr; } }

/* ── The entry code ─────────────────────────────────────────────────────────
   Centred, and the only band on the page that is. Its neighbours are a mirrored
   two-column pair; a third identical split between them would read as a stutter,
   so this one changes shape instead of side.

   The lock is drawn from elements rather than shipped as an SVG. An SVG's base
   direction is left to right, and the two words inside this one are Hebrew on a
   right-to-left page - the same reason the internet band's card is built this
   way. It also follows the light theme for nothing. */
.lockband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.lockband__inner {
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(24px, 3vw, 38px);
}
.lockband__copy {
    display: flex; flex-direction: column; align-items: center; gap: 14px;
    max-width: 62ch; text-align: center;
}
.lockband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(108, 99, 255, 0.42);
    background: rgba(108, 99, 255, 0.10);
    font-size: 12.5px; font-weight: 800; color: #a78bfa;
}
.lockband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.lockband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }

.lockband__mock { display: flex; justify-content: center; }
.lockband__card {
    display: flex; flex-direction: column; align-items: center; gap: 11px;
    width: min(268px, 100%);
    padding: 26px 24px 22px;
    border-radius: 18px;
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.42);
}
/* The padlock: a shackle sitting on a body, both drawn as boxes.
   The shackle has to OVERLAP the body, not rest above it - a hoop with daylight
   under it reads as an open padlock, which is the opposite of what this whole
   section is about. Narrower than the body and pushed down into it, which is
   what makes the two read as one object. */
.lockband__shackle {
    width: 28px; height: 20px;
    border: 3.5px solid #a78bfa; border-bottom: 0;
    border-radius: 14px 14px 0 0;
    margin-bottom: -6px;
}
.lockband__body {
    position: relative;
    width: 46px; height: 34px;
    border-radius: 8px;
    border: 2px solid #a78bfa;
    background: rgba(108, 99, 255, 0.16);
}
.lockband__body i {
    position: absolute; inset-inline-start: 50%; top: 9px;
    width: 5px; height: 5px; margin-inline-start: -2.5px;
    border-radius: 50%; background: #a78bfa;
    box-shadow: 0 6px 0 -1px #a78bfa;   /* the keyhole's tail, without a second element */
}
.lockband__heading { font-size: 13.5px; font-weight: 800; color: var(--text); }
/* Four dots in a field - a code being typed, without typing anything. */
.lockband__field {
    display: flex; align-items: center; justify-content: center; gap: 11px;
    width: 100%; height: 40px;
    border-radius: 10px;
    border: 1px solid var(--border-lit);
    background: rgba(255, 255, 255, 0.03);
}
.lockband__field b { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.lockband__go {
    display: flex; align-items: center; justify-content: center;
    width: 100%; height: 36px;
    border-radius: 10px;
    border: 1px solid rgba(108, 99, 255, 0.6);
    background: rgba(108, 99, 255, 0.18);
    font-size: 12.5px; font-weight: 800; color: var(--text);
}

.lockband__points {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: clamp(18px, 2.6vw, 34px);
    width: 100%; max-width: 1000px;
}
.lockband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.lockband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.lockband__points .gly { flex-shrink: 0; margin-top: 2px; color: #a78bfa; }

@media (max-width: 860px) { .lockband__points { grid-template-columns: 1fr; } }

/* ── Past the local network ─────────────────────────────────────────────────
   Built on the alerts band's proportions so the page keeps one rhythm, and
   mirrored: the drawing takes the start edge here and the copy the end, which
   is the opposite of the band above it. Cyan rather than purple, because this
   is the section about somewhere else - the other bands are about this machine.

   The card is drawn from elements rather than shipped as an SVG. Every value in
   it reads left to right - a domain, a status code, an address, a count of days
   - and an SVG re-orders exactly those when it sits in a right-to-left page.
   Elements let the browser's own bidi do it, and the card follows the light
   theme for free. */
.inetband { position: relative; padding: clamp(44px, 6vw, 80px) 0; }
.inetband__inner {
    /* The card is a compact result panel, not a wide screenshot like the band
       above - so the words get the larger share here, which is the opposite
       split from the alerts band and reads correctly for what each holds. */
    display: grid; grid-template-columns: 0.88fr 1.12fr;
    gap: clamp(28px, 4vw, 56px); align-items: center;
}
/* The copy sits second in the source so a screen reader and a narrow screen
   both get the words before the picture; the grid puts it back on the end. */
.inetband__copy { display: flex; flex-direction: column; gap: 14px; order: 2; }
.inetband__art { order: 1; margin: 0; }
.inetband__eyebrow {
    display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
    padding: 6px 13px; border-radius: 999px;
    border: 1px solid rgba(34, 211, 238, 0.42);
    background: rgba(34, 211, 238, 0.10);
    font-size: 12.5px; font-weight: 800; color: var(--accent-2);
}
.inetband__title { font-size: clamp(24px, 3.2vw, 34px); font-weight: 900; line-height: 1.25; }
.inetband__sub { font-size: 15px; line-height: 1.75; color: var(--muted); }
.inetband__points { list-style: none; display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.inetband__points li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: 14px; line-height: 1.7; color: var(--muted);
}
.inetband__points strong { display: block; color: var(--text); font-weight: 800; margin-bottom: 2px; }
.inetband__points .gly { flex-shrink: 0; margin-top: 2px; color: var(--accent-2); }

.inetband__card {
    border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.inetband__bar { display: flex; gap: 6px; padding: 10px 14px; background: rgba(255, 255, 255, 0.03); border-bottom: 1px solid var(--border); }
.inetband__bar span { width: 10px; height: 10px; border-radius: 50%; background: var(--border-lit); }
.inetband__bar span:first-child { background: rgba(248, 113, 113, 0.65); }
.inetband__bar span:nth-child(2) { background: rgba(251, 191, 36, 0.65); }
.inetband__body { padding: 18px; display: flex; flex-direction: column; gap: 14px; }

/* The address field, as the screen actually shows it: the box is left to right
   whatever the page is, because what goes in it is a domain. */
.inetband__query {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px 9px 12px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: rgba(0, 0, 0, 0.25);
    direction: ltr;
}
.inetband__qico { display: inline-flex; color: var(--accent-2); flex-shrink: 0; }
.inetband__qtext {
    flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: var(--text);
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inetband__qgo {
    flex-shrink: 0; padding: 6px 14px; border-radius: 999px;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    color: #0b0b16; font-size: 12.5px; font-weight: 800;
}

.inetband__rows { display: flex; flex-direction: column; }
.inetband__row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 9px 2px; border-top: 1px solid var(--border);
}
.inetband__row:first-child { border-top: 0; }
.inetband__k { font-size: 12.5px; color: var(--faint); }
/* Every value here is technical and reads left to right. As a flex item with
   its own direction it cannot be re-placed by the line around it. */
.inetband__v {
    font-size: 13px; font-weight: 700; color: var(--text);
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
    direction: ltr; text-align: left;
}
.inetband__v--ok { color: #4ade80; }
.inetband__v--warn { color: #fbbf24; }

.inetband__chips { display: flex; flex-wrap: wrap; gap: 7px; padding-top: 2px; }
.inetband__chip {
    padding: 4px 11px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
    border: 1px solid var(--border); color: var(--muted);
    direction: ltr;
}
.inetband__chip--ok { border-color: rgba(74, 222, 128, 0.4); background: rgba(74, 222, 128, 0.10); color: #4ade80; }
.inetband__chip--warn { border-color: rgba(251, 191, 36, 0.4); background: rgba(251, 191, 36, 0.10); color: #fbbf24; }

@media (max-width: 860px) {
    .inetband__inner { grid-template-columns: 1fr; }
    /* Stacked, the words come first - a picture of a result means nothing
       before the sentence that says what is being measured. */
    .inetband__copy { order: 1; }
    .inetband__art { order: 2; }
}

/* ── The vocabulary of a legal document ──────────────────────────────────────
   Written in the admin's HTML editor and whitelisted by sanitize_legal_html(),
   so this stylesheet and legal_html_classes() describe the same short list. It
   is a short list on purpose: the site's Content-Security-Policy carries no
   'unsafe-inline', which means a style attribute never survives to the page -
   so every visual choice the editor offers has to be a class defined here.

   The same rules serve the modal on the home page, which is why .lmodal__body
   also carries .legal-page__body.
   ──────────────────────────────────────────────────────────────────────────── */

.legal-page__body h2 { margin: 34px 0 12px; padding-bottom: 9px; border-bottom: 1px solid var(--border);
    font-family: var(--font-head); font-size: clamp(19px, 2.4vw, 23px); font-weight: 900;
    line-height: 1.35; color: var(--text); }
.legal-page__body h3 { margin: 26px 0 9px; font-size: clamp(16.5px, 2vw, 18.5px); font-weight: 800; color: var(--text); }
.legal-page__body h4 { margin: 20px 0 7px; font-size: 15.5px; font-weight: 800; color: var(--text); }
.legal-page__body > :first-child { margin-top: 0; }
.legal-page__body > :last-child { margin-bottom: 0; }
.legal-page__body p { margin: 0 0 14px; }
.legal-page__body ul, .legal-page__body ol { margin: 0 0 16px; padding-inline-start: 26px; }
.legal-page__body li { margin-bottom: 7px; }
.legal-page__body li::marker { color: var(--accent); }
.legal-page__body strong, .legal-page__body b { color: var(--text); font-weight: 800; }
.legal-page__body hr { margin: 30px 0; border: 0; border-top: 1px solid var(--border); }
.legal-page__body code { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.9em; direction: ltr; unicode-bidi: isolate;
    background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; padding: 1px 6px; }
.legal-page__body blockquote { margin: 18px 0; padding: 14px 20px;
    border-inline-start: 3px solid var(--accent); border-radius: 0 12px 12px 0;
    background: rgba(108, 99, 255, 0.07); color: var(--muted); }
.legal-page__body blockquote > :last-child { margin-bottom: 0; }

/* ── Tables ──
   A retention schedule or a list of processors is a table, and reading it as a
   paragraph is how those sections stop being read at all. On a narrow screen it
   scrolls sideways inside its own box rather than pushing the page out of shape. */
.legal-page__body table { width: 100%; margin: 20px 0; border-collapse: collapse; font-size: 15px; }
.legal-page__body th, .legal-page__body td { padding: 11px 14px; border: 1px solid var(--border);
    text-align: start; vertical-align: top; }
.legal-page__body th { background: rgba(108, 99, 255, 0.13); color: var(--text); font-weight: 800; font-size: 14px; }
.legal-page__body tbody tr:nth-child(even) td { background: var(--surface-2); }

/* ── Callout boxes ── */
.legal-page__body .lgl-note,
.legal-page__body .lgl-info,
.legal-page__body .lgl-ok,
.legal-page__body .lgl-warn { margin: 22px 0; padding: 16px 20px; border-radius: 14px;
    border: 1px solid var(--border); border-inline-start-width: 4px; background: var(--surface-2); }
.legal-page__body .lgl-note > :last-child,
.legal-page__body .lgl-info > :last-child,
.legal-page__body .lgl-ok > :last-child,
.legal-page__body .lgl-warn > :last-child { margin-bottom: 0; }
.legal-page__body .lgl-note { border-inline-start-color: #a78bfa; background: rgba(167, 139, 250, 0.09); }
.legal-page__body .lgl-info { border-inline-start-color: var(--accent-2); background: rgba(34, 211, 238, 0.08); }
.legal-page__body .lgl-ok   { border-inline-start-color: #34d399; background: rgba(52, 211, 153, 0.09); }
.legal-page__body .lgl-warn { border-inline-start-color: #fbbf24; background: rgba(251, 191, 36, 0.10); }

/* ── Emphasis and alignment ── */
.legal-page__body .lgl-lead { font-size: 1.09em; line-height: 1.85; color: var(--text); }
.legal-page__body .lgl-small { font-size: 0.9em; color: var(--faint); }
.legal-page__body .is-start  { text-align: start; }
.legal-page__body .is-center { text-align: center; }
.legal-page__body .is-end    { text-align: end; }

/* The palette. Five colours and no picker: a document that can be any colour
   ends up being several, and none of them legible in both themes. */
.legal-page__body .c-accent { color: #8b7cf6; }
.legal-page__body .c-ok     { color: #10b981; }
.legal-page__body .c-warn   { color: #d97706; }
.legal-page__body .c-danger { color: #ef4444; }
.legal-page__body .c-muted  { color: var(--faint); }
:root:not([data-theme="light"]) .legal-page__body .c-accent { color: #a78bfa; }
:root:not([data-theme="light"]) .legal-page__body .c-ok     { color: #34d399; }
:root:not([data-theme="light"]) .legal-page__body .c-warn   { color: #fbbf24; }
:root:not([data-theme="light"]) .legal-page__body .c-danger { color: #f87171; }

@media (max-width: 620px) {
    .legal-page__body table { display: block; overflow-x: auto; }
    .legal-page__body th, .legal-page__body td { padding: 9px 11px; }
}
