/* ==========================================================================
   FLOWSENSE — components.css  [DESIGN]  v3
   Znovupoužitelné komponenty. Používají výhradně tokeny z base.css.
   Přehled a ukázky: dev/styleguide.php · Kontrakt tříd: docs/DESIGN.md

   Obsah:
    1. Tlačítka (+ text roll, magnetic, loading)
    2. Odkazy
    3. Formuláře (field, label, input, input-group, select, check, switch)
    4. Karty a panely
    5. Badge, status pill, UID
    6. Alerty
    7. Tabulka
    8. Tabs, segmented control
    9. Dialog (modal) a drawer
   10. Toast
   11. Empty state, skeleton
   12. Progress, kbd/code, keycode
   13. Stat tile, definition list, avatar
   14. Stránkování
   15. Deck (sticky „slide“ prezentace)
   16. Reveal + scroll-driven efekty
   17. FAQ (<details>), word reveal, kroky, timeline, scroll hint
   18. Ilustrace (radar, HUD) — CSS/SVG kompozice místo chybějících screenshotů
   — v4 —
   19. Dashboard layout (.dash — profil i admin)
   20. Command palette (<dialog class="cmdk">, Flowsense.cmdk)
   21. Grafy (Flowsense.chart) a uptime pruh
   22. Notifikace (zvoneček v nav, notifications.js)
   23. Ticket thread, composer, stavy ticketu
   24. Chips (filtry), segmented s počty
   25. Stepper (2FA setup), OTP input, QR rámeček
   26. Sessions list, connection card, referral card
   27. Upload dropzone
   28. Secret (klíč / kódy zobrazené jen jednou)
   29. Prose (vyrenderované HTML: changelog, legal), release
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tlačítka
   .btn               — secondary (výchozí): plocha + hairline
   .btn--secondary    — totéž, explicitně
   .btn--primary      — akcent (hlavní CTA, max. 1 na obrazovku)
   .btn--ghost        — bez rámečku (terciární akce, nav)
   .btn--danger       — destruktivní; s .btn--primary plná červená
   .btn--icon         — čtvercové ikonové tlačítko (vždy aria-label)
   .btn--sm / --lg, .btn--block, .is-loading (+ aria-busy="true")
   Mikrointerakce: data-roll (text roll po písmenech), data-magnetic (main.js)
   -------------------------------------------------------------------------- */
.btn {
    --btn-h: 40px;
    --btn-px: 1rem;
    --btn-fs: var(--text-sm);
    --btn-bg: var(--surface-2);
    --btn-bg-hover: var(--surface-3);
    --btn-fg: var(--text);
    --btn-border: var(--line-2);
    --btn-border-hover: var(--line-3);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--btn-h);
    padding: 0 var(--btn-px);
    border: 1px solid var(--btn-border);
    border-radius: var(--radius-md);
    background-color: var(--btn-bg);
    color: var(--btn-fg);
    font-family: var(--font-sans);
    font-size: var(--btn-fs);
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -0.005em;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    /* magnetic posun nastavuje main.js přes --mx / --my */
    translate: var(--mx, 0px) var(--my, 0px);
    transition: background-color var(--dur) ease, border-color var(--dur) ease,
                color var(--dur) ease, box-shadow var(--dur) ease,
                translate 0.6s var(--ease-spring), scale var(--dur-fast) ease;
}

.btn:hover {
    background-color: var(--btn-bg-hover);
    border-color: var(--btn-border-hover);
    color: var(--btn-fg);
}

.btn:active {
    scale: 0.98;
}

/* během magnetic sledování bez zpoždění */
.btn.is-magnetic {
    transition: background-color var(--dur) ease, border-color var(--dur) ease,
                color var(--dur) ease, box-shadow var(--dur) ease,
                translate 0.18s var(--ease-out), scale var(--dur-fast) ease;
}

.btn .icon {
    width: 1.05em;
    height: 1.05em;
}

.btn--secondary {
    /* = výchozí .btn */
}

.btn--primary {
    --btn-bg: var(--accent);
    --btn-bg-hover: rgb(150, 255, 233);
    --btn-fg: var(--on-accent);
    --btn-border: transparent;
    --btn-border-hover: transparent;
    font-weight: 600;
}

.btn--primary:focus-visible {
    outline-color: var(--text);
}

.btn--ghost {
    --btn-bg: transparent;
    --btn-bg-hover: var(--surface-2);
    --btn-fg: var(--text-2);
    --btn-border: transparent;
    --btn-border-hover: transparent;
}

.btn--ghost:hover {
    --btn-fg: var(--text);
}

.btn--danger {
    --btn-bg: rgba(var(--danger-rgb), 0.06);
    --btn-bg-hover: rgba(var(--danger-rgb), 0.12);
    --btn-fg: var(--danger);
    --btn-border: rgba(var(--danger-rgb), 0.28);
    --btn-border-hover: rgba(var(--danger-rgb), 0.5);
}

.btn--danger.btn--primary {
    --btn-bg: var(--danger);
    --btn-bg-hover: rgb(255, 135, 128);
    --btn-fg: rgb(30, 6, 5);
    --btn-border: transparent;
    --btn-border-hover: transparent;
}

.btn--sm {
    --btn-h: 32px;
    --btn-px: 0.75rem;
    --btn-fs: 0.8125rem;
    border-radius: var(--radius-sm);
}

.btn--lg {
    --btn-h: 48px;
    --btn-px: 1.375rem;
    --btn-fs: 0.9375rem;
}

.btn--icon {
    --btn-px: 0;
    width: var(--btn-h);
    flex-shrink: 0;
}

.btn--block {
    display: flex;
    width: 100%;
}

/* šipka/ikona na konci, která při hoveru poodjede */
.btn__arrow {
    transition: translate var(--dur) var(--ease-out);
}

.btn:hover .btn__arrow {
    translate: 2px 0;
}

.btn--primary:disabled,
.btn--primary[aria-disabled="true"] {
    --btn-bg: var(--surface-2);
    --btn-fg: var(--text-3);
    --btn-border: var(--line-2);
    opacity: 1 !important;
}

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

/* Loading: <button class="btn is-loading" aria-busy="true"> — text zmizí, spinner uprostřed */
.btn.is-loading {
    color: transparent !important;
    pointer-events: none;
}

.btn.is-loading > * {
    visibility: hidden;
}

.btn.is-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 1em;
    height: 1em;
    margin: auto;
    border: 1.5px solid var(--btn-fg);
    border-right-color: transparent;
    border-radius: 50%;
    animation: btnSpin 0.7s linear infinite;
}

@keyframes btnSpin {
    to { transform: rotate(360deg); }
}

/* Text roll — main.js rozdělí popisek [data-roll] na znaky:
   <span class="btn__label-sr">Label</span><span class="btn__roll" aria-hidden="true"><span class="btn__char" style="--i:0">L</span>…</span>
   Každý znak nese svou kopii jako text-shadow 1 řádek pod sebou; při hoveru
   se znaky postupně (stagger) posunou o řádek nahoru. */
.btn__roll {
    display: inline-flex;
    height: 1.25em;
    line-height: 1.25;
    overflow: hidden;
    /* rezerva pro diakritiku/descendery, ať je ořez neusekne */
    padding-block: 0.06em;
    margin-block: -0.06em;
    box-sizing: content-box;
}

.btn__char {
    display: inline-block;
    white-space: pre;
    text-shadow: 0 1.25em 0 currentColor;
    transition: translate 0.5s var(--ease-out);
    transition-delay: calc(var(--i, 0) * 16ms);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .btn:hover .btn__char,
    .btn:focus-visible .btn__char {
        translate: 0 -1.25em;
    }
}

/* --------------------------------------------------------------------------
   2. Odkazy
   -------------------------------------------------------------------------- */
.link {
    color: var(--text);
    font-weight: 500;
    text-decoration-line: underline;
    text-decoration-color: var(--line-3);
}

.link:hover {
    text-decoration-color: var(--accent);
}

.link--accent {
    color: var(--accent);
    text-decoration-color: var(--accent-line);
}

/* Odkaz se šipkou bez podtržení: "Read more →" */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
    text-decoration: none;
}

.link-arrow .icon {
    transition: translate var(--dur) var(--ease-out);
}

.link-arrow:hover .icon {
    translate: 3px 0;
}

/* --------------------------------------------------------------------------
   3. Formuláře
   <div class="field">
     <label class="label" for="x">Label <span class="label__optional">Optional</span></label>
     <input class="input" id="x">
     <p class="field__hint">…</p>
     <p class="field__error" data-error-for="x"></p>
   </div>
   Chyba: .field.is-invalid nebo input[aria-invalid="true"]
   -------------------------------------------------------------------------- */
.form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    width: 100%;
}

.form--narrow {
    max-width: 420px;
    margin-inline: auto;
}

.form__title {
    font-size: var(--text-xl);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
    color: var(--text);
}

.form__actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
    margin-top: var(--space-1);
}

.form__footer {
    text-align: center;
    font-size: var(--text-sm);
    color: var(--text-2);
}

.form__row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
    gap: var(--space-4);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.3;
    color: var(--text-2);
}

.label__optional {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.02em;
    color: var(--text-3);
}

.input {
    width: 100%;
    min-height: 40px;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background-color: var(--surface-1);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: 0.9375rem;
    line-height: 1.4;
    transition: border-color var(--dur) ease, box-shadow var(--dur) ease,
                background-color var(--dur) ease;
}

.input::placeholder {
    color: var(--text-3);
    opacity: 1;
}

.input:hover {
    border-color: var(--line-3);
}

.input:focus,
.input:focus-visible {
    outline: none;
    border-color: var(--focus-line);
    background-color: var(--surface-2);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

.input:disabled,
.input[readonly] {
    color: var(--text-2);
    background-color: var(--bg);
}

.input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.input[aria-invalid="true"],
.field.is-invalid .input {
    border-color: rgba(var(--danger-rgb), 0.6);
    box-shadow: 0 0 0 3px rgba(var(--danger-rgb), 0.12);
}

/* Monospace vstup (licenční klíč, UID, HWID) */
.input--mono {
    font-family: var(--font-mono);
    font-size: 0.875rem;
    letter-spacing: 0.06em;
}

.input--lg {
    min-height: 48px;
    font-size: 1rem;
}

textarea.input {
    min-height: 7rem;
    resize: vertical;
}

select.input {
    appearance: none;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23a3a5a8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
    background-position: right 0.625rem center;
    background-size: 16px 16px;
    background-repeat: no-repeat;
}

.field__hint {
    font-size: 0.8125rem;
    color: var(--text-3);
}

.field__error {
    display: flex;
    gap: var(--space-2);
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--danger);
}

.field__error:empty {
    display: none;
}

/* Input s připojeným tlačítkem/addonem: [ FLOW-XXXX… ][ Redeem ] */
.input-group {
    display: flex;
    align-items: stretch;
    min-width: 0;
}

.input-group > .input {
    flex: 1 1 auto;
    min-width: 0;
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.input-group > .btn,
.input-group > .input-group__addon {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
    margin-left: -1px;
}

.input-group__addon {
    display: inline-flex;
    align-items: center;
    padding-inline: var(--space-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
}

.input-group__addon .icon {
    width: 16px;
    height: 16px;
}

.input-group--prefix > .input-group__addon {
    order: -1;
    margin-left: 0;
    margin-right: -1px;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
}

.input-group--prefix > .input {
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

@media (max-width: 30rem) {
    .input-group--stack {
        flex-direction: column;
        gap: var(--space-2);
    }

    .input-group--stack > .input,
    .input-group--stack > .btn {
        margin: 0;
        border-radius: var(--radius-md);
    }
}

/* Checkbox / radio: <label class="check"><input type="checkbox"> Remember me</label> */
.check {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-2);
    cursor: pointer;
}

.check input {
    appearance: none;
    flex-shrink: 0;
    display: grid;
    place-content: center;
    width: 16px;
    height: 16px;
    margin: 0;
    border: 1px solid var(--line-3);
    border-radius: var(--radius-xs);
    background: var(--surface-1);
    cursor: pointer;
    transition: background-color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.check input[type="radio"] {
    border-radius: 50%;
}

.check input::before {
    content: "";
    width: 10px;
    height: 10px;
    background: var(--on-accent);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M1.5 5.2 4 7.5l4.5-5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M1.5 5.2 4 7.5l4.5-5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    scale: 0;
    transition: scale var(--dur-fast) var(--ease-out);
}

.check input[type="radio"]::before {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    -webkit-mask: none;
    mask: none;
}

.check input:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.check input:checked::before {
    scale: 1;
}

.check:hover input:not(:checked) {
    border-color: var(--text-3);
}

/* Přepínač: <label class="switch"><input type="checkbox" role="switch"> Label</label> */
.switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-2);
    cursor: pointer;
}

.switch input {
    appearance: none;
    position: relative;
    flex-shrink: 0;
    width: 32px;
    height: 18px;
    margin: 0;
    border: 1px solid var(--line-3);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    cursor: pointer;
    transition: background-color var(--dur) ease, border-color var(--dur) ease;
}

.switch input::before {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--text-2);
    transition: translate var(--dur) var(--ease-out), background-color var(--dur) ease;
}

.switch input:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.switch input:checked::before {
    translate: 14px 0;
    background: var(--on-accent);
}

/* --------------------------------------------------------------------------
   4. Karty a panely — ploché, hairline, žádné stíny
   -------------------------------------------------------------------------- */
.card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: clamp(var(--space-5), 2.5vw, var(--space-6));
    background-color: var(--surface-1);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    color: var(--text);
    transition: border-color var(--dur) ease, background-color var(--dur) ease;
}

/* klikatelná karta (celá je odkaz nebo obsahuje hlavní odkaz) */
.card--interactive {
    cursor: pointer;
}

@media (hover: hover) {
    .card--interactive:hover {
        border-color: var(--line-3);
        background-color: var(--surface-2);
    }
}

/* karta bez výplně, jen hairline */
.card--outline {
    background-color: transparent;
}

/* karta bez paddingu (média, tabulky) */
.card--flush {
    padding: 0;
    overflow: hidden;
}

.card--center {
    align-items: center;
    text-align: center;
}

.card__eyebrow {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.card__title {
    font-size: var(--text-lg);
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: var(--tracking-snug);
    color: var(--text);
    margin: 0;
}

.card__text {
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--text-2);
}

.card__text--mono {
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    line-height: 1.65;
}

/* ikonový „čip“ v kartě: <span class="card__glyph"><svg class="icon">…</svg></span> */
.card__glyph {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    color: var(--text);
    font-size: 18px;
}

.card__footer {
    margin-top: auto;
    padding-top: var(--space-3);
}

/* Panel — sekce s hlavičkou a oddělenými částmi (profil, admin) */
.panel {
    background: var(--surface-1);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    min-width: 0;
}

.panel__header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--line);
}

.panel__title {
    font-size: var(--text-base);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.panel__desc {
    font-size: var(--text-sm);
    color: var(--text-3);
}

.panel__body {
    padding: var(--space-5);
}

.panel__body--flush {
    padding: 0;
}

.panel__section + .panel__section {
    border-top: 1px solid var(--line);
}

.panel__footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border-top: 1px solid var(--line);
    background: rgba(255, 255, 255, 0.012);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.panel__footer--between {
    justify-content: space-between;
}

/* --------------------------------------------------------------------------
   5. Badge, status pill, UID
   -------------------------------------------------------------------------- */
.badge {
    --badge-rgb: 237, 238, 240;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 22px;
    padding: 0 7px;
    border: 1px solid rgba(var(--badge-rgb), 0.16);
    border-radius: var(--radius-xs);
    background: rgba(var(--badge-rgb), 0.06);
    color: rgba(var(--badge-rgb), 0.85);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.04em;
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
}

.badge--neutral { --badge-rgb: 237, 238, 240; }
.badge--accent,
.badge--success { --badge-rgb: var(--accent-rgb); }
.badge--warning { --badge-rgb: var(--warning-rgb); }
.badge--danger  { --badge-rgb: var(--danger-rgb); }
.badge--info    { --badge-rgb: var(--info-rgb); }

/* tečka v badge: <span class="badge badge--success"><span class="badge__dot"></span>Active</span> */
.badge__dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
}

/* Status pill produktu — <span class="status status--undetected">…</span>
   Stavy: undetected | updating | detected | maintenance */
.status {
    --status-rgb: var(--info-rgb);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 26px;
    padding: 0 10px 0 9px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-pill);
    background: rgba(var(--bg-rgb), 0.55);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-mono);
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
    text-decoration: none;
}

a.status:hover {
    border-color: var(--line-3);
}

.status__label-key {
    color: var(--text-3);
}

.status__dot {
    position: relative;
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgb(var(--status-rgb));
}

/* pulzující prstenec */
.status__dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: rgb(var(--status-rgb));
    opacity: 0;
    animation: statusPulse 2.4s var(--ease-out) infinite;
}

.status--undetected  { --status-rgb: var(--accent-rgb); }
.status--updating    { --status-rgb: var(--warning-rgb); }
.status--detected    { --status-rgb: var(--danger-rgb); }
.status--maintenance { --status-rgb: var(--info-rgb); }

/* updating = rychlejší puls, maintenance = bez pulsu */
.status--updating .status__dot::after { animation-duration: 1.2s; }
.status--maintenance .status__dot::after { animation: none; }

.status--lg {
    height: 32px;
    padding: 0 14px 0 12px;
    font-size: 12px;
}

@keyframes statusPulse {
    0%   { opacity: 0.7; scale: 1; }
    70%  { opacity: 0; scale: 3; }
    100% { opacity: 0; scale: 3; }
}

/* UID — pořadové číslo uživatele, monospace: <span class="uid"><span class="uid__label">UID</span><span class="uid__value">#0042</span></span> */
.uid {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.uid__label {
    font-size: 11px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.uid__value {
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--text);
}

.uid--none .uid__value {
    color: var(--text-3);
}

/* velké UID v hlavičce profilu */
.uid--xl {
    flex-direction: column;
    gap: var(--space-1);
}

.uid--xl .uid__value {
    font-size: var(--text-3xl);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.04em;
}

/* --------------------------------------------------------------------------
   6. Alerty — <div class="alert alert--success" role="status"><span class="alert__text">…</span></div>
   Typy: success | error | info | warning. Ikona je maska (::before).
   -------------------------------------------------------------------------- */
.alert {
    --alert-rgb: var(--info-rgb);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.3'/%3E%3Cpath d='M8 7.2v3.6M8 5.2v.01'/%3E%3C/svg%3E");
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid rgba(var(--alert-rgb), 0.22);
    border-radius: var(--radius-md);
    background: rgba(var(--alert-rgb), 0.05);
    color: var(--text);
    font-size: var(--text-sm);
    line-height: 1.55;
}

.alert::before {
    content: "";
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    margin-top: 0.15em;
    background: rgb(var(--alert-rgb));
    -webkit-mask: var(--alert-icon) center / contain no-repeat;
    mask: var(--alert-icon) center / contain no-repeat;
}

.alert--success {
    --alert-rgb: var(--success-rgb);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6.3'/%3E%3Cpath d='m5.4 8.2 1.8 1.8 3.4-3.6'/%3E%3C/svg%3E");
}

.alert--error {
    --alert-rgb: var(--danger-rgb);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.3'/%3E%3Cpath d='M8 4.8v3.8M8 10.9v.01'/%3E%3C/svg%3E");
}

.alert--info {
    --alert-rgb: var(--info-rgb);
}

.alert--warning {
    --alert-rgb: var(--warning-rgb);
    --alert-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2.2 14.3 13H1.7z'/%3E%3Cpath d='M8 6.5v3M8 11.3v.01'/%3E%3C/svg%3E");
}

.alert__text {
    flex: 1;
    min-width: 0;
    color: var(--text);
}

.alert__title {
    display: block;
    font-weight: 600;
    margin-bottom: 2px;
}

.alert__text p + p {
    margin-top: var(--space-2);
}

.alerts {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

.alerts:empty {
    margin-bottom: 0;
}

/* Oznámení přes celou šířku (announcement ze site_settings) — nad lištou, zavírací křížek
   (main.js: data-announcement-dismiss, pamatuje si hash textu v localStorage) */
.announcement {
    position: relative;
    z-index: calc(var(--z-nav) + 1);
    border-bottom: 1px solid var(--line);
    background: var(--surface-1);
    font-size: var(--text-sm);
    color: var(--text-2);
}

.announcement__inner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    min-height: 40px;
    padding-block: var(--space-2);
    text-align: center;
}

.announcement__text {
    flex: 1;
    min-width: 0;
}

.announcement__close {
    flex-shrink: 0;
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text-3);
    font-size: 1.1rem;
    line-height: 1;
}

.announcement__close:hover {
    color: var(--text);
    background: var(--surface-2);
}

/* --------------------------------------------------------------------------
   7. Tabulka (admin)
   <div class="table-wrap"><table class="table">…</table></div>
   Řazení: <th aria-sort="ascending"><button class="table__sort">UID</button></th>
   -------------------------------------------------------------------------- */
.table-wrap {
    position: relative;
    width: 100%;
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    -webkit-overflow-scrolling: touch;
}

.panel .table-wrap,
.table-wrap--flush {
    border: 0;
    border-radius: 0;
    background: transparent;
}

.table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--text-sm);
    line-height: 1.4;
}

.table th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line);
    background: var(--surface-1);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-mono);
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}

.table td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line);
    color: var(--text-2);
    vertical-align: middle;
}

.table tbody tr:last-child td {
    border-bottom: 0;
}

.table tbody tr {
    transition: background-color var(--dur-fast) ease;
}

.table tbody tr:hover {
    background-color: rgba(255, 255, 255, 0.022);
}

/* klikatelný řádek (otevře drawer) */
.table tr[data-href],
.table tr.is-clickable {
    cursor: pointer;
}

.table tr.is-selected,
.table tr[aria-selected="true"] {
    background-color: rgba(var(--accent-rgb), 0.045);
}

.table td.num,
.table td.mono {
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

.table .num {
    text-align: right;
}

.table__strong {
    color: var(--text);
    font-weight: 500;
}

.table__actions {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

/* buňka s uživatelem: avatar + jméno + e-mail */
.table__user {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 12rem;
}

.table__user-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.table__user-name {
    color: var(--text);
    font-weight: 500;
}

.table__user-email {
    font-size: var(--text-xs);
    color: var(--text-3);
}

.table__sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
}

.table__sort:hover,
th[aria-sort] .table__sort {
    color: var(--text);
}

.table__sort::after {
    content: "";
    width: 8px;
    height: 8px;
    opacity: 0.6;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath d='M2 3l2-2 2 2M2 5l2 2 2-2' fill='none' stroke='%23000' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath d='M2 3l2-2 2 2M2 5l2 2 2-2' fill='none' stroke='%23000' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

th[aria-sort="ascending"] .table__sort::after { rotate: 0deg; opacity: 1; }
th[aria-sort="descending"] .table__sort::after { rotate: 180deg; opacity: 1; }

.table--compact th,
.table--compact td {
    padding: var(--space-2) var(--space-3);
}

/* toolbar nad tabulkou: hledání + filtry */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

.toolbar__grow {
    flex: 1 1 14rem;
    min-width: 0;
}

/* --------------------------------------------------------------------------
   8. Tabs (data-tabs v main.js) a segmented control
   <div data-tabs>
     <div class="tabs" role="tablist" aria-label="…">
       <button class="tabs__tab" role="tab" id="t1" aria-controls="p1" aria-selected="true">Overview</button> …
     </div>
     <div class="tabs__panel" role="tabpanel" id="p1" aria-labelledby="t1">…</div> …
   </div>
   -------------------------------------------------------------------------- */
.tabs {
    position: relative;
    display: flex;
    gap: var(--space-1);
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
    display: none;
}

.tabs__tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 40px;
    padding: 0 var(--space-3);
    border: 0;
    background: none;
    color: var(--text-3);
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
    transition: color var(--dur) ease;
}

.tabs__tab:hover {
    color: var(--text-2);
}

.tabs__tab[aria-selected="true"] {
    color: var(--text);
}

/* bez JS / před inicializací: podtržení pod aktivní záložkou */
.tabs__tab[aria-selected="true"]::after {
    content: "";
    position: absolute;
    left: var(--space-3);
    right: var(--space-3);
    bottom: -1px;
    height: 1px;
    background: var(--text);
}

/* s JS: jeden posuvný indikátor (--tab-x, --tab-w nastavuje main.js) */
.tabs.has-indicator .tabs__tab::after {
    display: none;
}

.tabs__indicator {
    position: absolute;
    left: 0;
    bottom: 0;
    width: var(--tab-w, 0px);
    height: 1px;
    background: var(--text);
    translate: var(--tab-x, 0px) 0;
    transition: translate 0.4s var(--ease-out), width 0.4s var(--ease-out);
    pointer-events: none;
}

.tabs__count {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-3);
}

.tabs__panel {
    padding-top: var(--space-5);
}

.tabs__panel:focus-visible {
    outline-offset: 4px;
}

/* Segmented control (rádia, bez JS)
   <div class="segmented" role="radiogroup" aria-label="Filter">
     <label class="segmented__item"><input type="radio" name="f" value="all" checked><span>All</span></label> … */
.segmented {
    display: inline-flex;
    width: fit-content;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface-1);
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
}

.segmented__item {
    position: relative;
    flex-shrink: 0;
}

.segmented__item input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.segmented__item span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--text-3);
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--dur) ease, background-color var(--dur) ease, box-shadow var(--dur) ease;
}

.segmented__item span:hover {
    color: var(--text-2);
}

.segmented__item input:checked + span {
    background: var(--surface-3);
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--line-2);
}

.segmented__item input:focus-visible + span {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* --------------------------------------------------------------------------
   9. Dialog (<dialog class="modal">) a drawer (<dialog class="drawer">)
   Otevírání: [data-modal-open="id"], zavírání: [data-modal-close] (main.js),
   nebo Flowsense.openDialog(id). Klik na backdrop a Escape zavře.
   -------------------------------------------------------------------------- */
.modal,
.drawer {
    padding: 0;
    border: 1px solid var(--line-2);
    background: var(--surface-overlay);
    color: var(--text);
    box-shadow: var(--shadow-float);
    overflow: auto;
    overscroll-behavior: contain;
}

.modal::backdrop,
.drawer::backdrop {
    background-color: rgba(0, 0, 0, 0.62);
}

.modal {
    width: min(calc(100vw - 2rem), 480px);
    max-height: min(calc(100dvh - 2rem), 760px);
    margin: auto;
    border-radius: var(--radius-xl);
}

.modal--lg {
    width: min(calc(100vw - 2rem), 720px);
}

/* Animace otevření/zavření (Chrome/Edge/Safari 17.5+; jinde se jen zobrazí) */
.modal,
.modal::backdrop,
.drawer,
.drawer::backdrop {
    transition: opacity var(--dur) ease, translate var(--dur-slow) var(--ease-out),
                scale var(--dur-slow) var(--ease-out),
                overlay var(--dur) allow-discrete, display var(--dur) allow-discrete;
}

.modal:not([open]),
.modal:not([open])::backdrop,
.drawer:not([open]),
.drawer:not([open])::backdrop {
    opacity: 0;
}

.modal:not([open]) {
    scale: 0.97;
    translate: 0 8px;
}

@starting-style {
    .modal[open],
    .modal[open]::backdrop,
    .drawer[open],
    .drawer[open]::backdrop {
        opacity: 0;
    }

    .modal[open] {
        scale: 0.97;
        translate: 0 8px;
    }

    .drawer[open] {
        translate: 100% 0;
    }
}

.modal__inner {
    display: flex;
    flex-direction: column;
}

.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-5) var(--space-5) 0;
}

.modal__title {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
    color: var(--text);
    margin: 0;
    padding-top: 4px;
}

.modal__close,
.drawer__close {
    flex-shrink: 0;
    display: inline-grid;
    place-items: center;
    width: 32px;
    height: 32px;
    margin: -2px -6px 0 0;
    padding: 0;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-3);
    font-size: 1.375rem;
    line-height: 1;
    transition: color var(--dur) ease, background-color var(--dur) ease;
}

.modal__close:hover,
.drawer__close:hover {
    color: var(--text);
    background: var(--surface-2);
}

.modal__body {
    padding: var(--space-4) var(--space-5) var(--space-5);
    font-size: var(--text-sm);
    line-height: 1.6;
    color: var(--text-2);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.modal__body .alerts {
    margin-bottom: 0;
}

.modal__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--line);
}

@media (max-width: 30rem) {
    .modal__actions > .btn {
        flex: 1 1 8rem;
    }
}

/* Drawer — pravý panel (detail uživatele v adminu) */
.drawer {
    /* [AUDIT V4] 100 % místo 100vw: 100vw zahrnuje klasický scrollbar → panel přetékal 15 px doleva
       (úzké okno / zoom 200–400 %, WCAG 1.4.10) */
    width: min(100%, 520px);
    max-width: 100%;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0 0 0 auto;
    border-width: 0 0 0 1px;
    border-radius: 0;
    overflow: hidden;
}

.drawer--wide {
    width: min(100%, 720px);
}

.drawer:not([open]) {
    translate: 100% 0;
}

.drawer[open] {
    display: flex;
    flex-direction: column;
}

.drawer__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-5);
    border-bottom: 1px solid var(--line);
}

.drawer__title {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
}

.drawer__subtitle {
    margin-top: 2px;
    font-size: var(--text-sm);
    color: var(--text-3);
}

.drawer__body {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-5);
}

.drawer__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

.drawer__footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--line);
}

/* zabránit scrollu stránky pod otevřeným dialogem */
html:has(.modal[open], .drawer[open]) {
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   10. Toast — vytváří main.js: Flowsense.toast('Saved', {type: 'success'})
   -------------------------------------------------------------------------- */
.toast-region {
    position: fixed;
    right: var(--space-5);
    bottom: var(--space-5);
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-end;
    gap: var(--space-2);
    width: min(calc(100vw - 2rem), 380px);
    pointer-events: none;
}

@media (max-width: 30rem) {
    .toast-region {
        right: 1rem;
        left: 1rem;
        bottom: max(1rem, env(safe-area-inset-bottom));
        width: auto;
    }
}

.toast {
    --toast-rgb: var(--info-rgb);
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    background: var(--surface-overlay);
    box-shadow: var(--shadow-float);
    color: var(--text);
    font-size: var(--text-sm);
    line-height: 1.45;
    pointer-events: auto;
    transition: opacity var(--dur) ease, translate var(--dur-slow) var(--ease-out),
                scale var(--dur-slow) var(--ease-out);
}

@starting-style {
    .toast {
        opacity: 0;
        translate: 0 12px;
        scale: 0.98;
    }
}

.toast.is-leaving {
    opacity: 0;
    translate: 0 6px;
    transition-duration: var(--dur), var(--dur), var(--dur);
}

.toast--success { --toast-rgb: var(--success-rgb); }
.toast--error   { --toast-rgb: var(--danger-rgb); }
.toast--warning { --toast-rgb: var(--warning-rgb); }

.toast__dot {
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    margin-top: 0.5em;
    border-radius: 50%;
    background: rgb(var(--toast-rgb));
}

.toast__text {
    flex: 1;
    min-width: 0;
    padding-block: 2px;
}

.toast__close {
    flex-shrink: 0;
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text-3);
    font-size: 1.1rem;
    line-height: 1;
}

.toast__close:hover {
    color: var(--text);
    background: var(--surface-2);
}

/* --------------------------------------------------------------------------
   11. Empty state a skeleton
   -------------------------------------------------------------------------- */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: clamp(var(--space-7), 6vw, var(--space-9)) var(--space-5);
    border: 1px dashed var(--line-2);
    border-radius: var(--radius-lg);
    text-align: center;
}

.empty--plain {
    border: 0;
}

.empty__icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    color: var(--text-2);
    font-size: 20px;
}

.empty__title {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text);
}

.empty__text {
    max-width: 40ch;
    font-size: var(--text-sm);
    color: var(--text-3);
}

.empty__actions {
    margin-top: var(--space-3);
}

/* Skeleton: <span class="skeleton skeleton--text" style="width: 60%"></span> */
.skeleton {
    display: block;
    border-radius: var(--radius-sm);
    background:
        linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.045) 50%, transparent 100%) 0 0 / 200% 100% no-repeat,
        var(--surface-2);
    animation: skeleton 1.6s ease-in-out infinite;
}

.skeleton--text {
    height: 0.75em;
    margin-block: 0.4em;
}

.skeleton--title {
    height: 1.25em;
    width: 40%;
}

.skeleton--circle {
    width: 32px;
    height: 32px;
    border-radius: 50%;
}

.skeleton--block {
    height: 120px;
    border-radius: var(--radius-lg);
}

@keyframes skeleton {
    from { background-position: 150% 0, 0 0; }
    to   { background-position: -50% 0, 0 0; }
}

/* --------------------------------------------------------------------------
   12. Progress, kbd/code, keycode (licenční klíč)
   <div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="30" aria-valuenow="18"
        aria-label="Days left" style="--value: 0.6"><span class="progress__bar"></span></div>
   .progress--ticks = segmentovaný (např. 30 dní, --ticks: 30)
   .progress--warning / --danger = barva podle zbývajících dní
   -------------------------------------------------------------------------- */
.progress {
    --value: 0;
    --progress-c: var(--accent);
    position: relative;
    width: 100%;
    height: 4px;
    border-radius: var(--radius-pill);
    background: var(--line-2);
    overflow: hidden;
}

.progress__bar {
    display: block;
    height: 100%;
    width: 100%;
    border-radius: inherit;
    background: var(--progress-c);
    transform-origin: left center;
    transform: scaleX(var(--value));
    transition: transform 1.2s var(--ease-out);
}

@starting-style {
    .progress__bar {
        transform: scaleX(0);
    }
}

.progress--warning { --progress-c: var(--warning); }
.progress--danger  { --progress-c: var(--danger); }

.progress--lg {
    height: 8px;
}

.progress--ticks {
    --ticks: 30;
    --gap: 3px;
    height: 20px;
    border-radius: 0;
    background: transparent;
    -webkit-mask: repeating-linear-gradient(to right, #000 0, #000 calc(100% / var(--ticks) - var(--gap)),
                  transparent calc(100% / var(--ticks) - var(--gap)), transparent calc(100% / var(--ticks)));
    mask: repeating-linear-gradient(to right, #000 0, #000 calc(100% / var(--ticks) - var(--gap)),
          transparent calc(100% / var(--ticks) - var(--gap)), transparent calc(100% / var(--ticks)));
}

.progress--ticks::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--line-2);
}

.progress--ticks .progress__bar {
    position: relative;
    border-radius: 0;
}

/* popisky nad progress barem */
.progress-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: 0.03em;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

.progress-meta strong {
    color: var(--text);
    font-weight: 500;
}

/* Klávesa: <kbd class="kbd">Esc</kbd> */
.kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6em;
    height: 1.6em;
    padding: 0 0.4em;
    border: 1px solid var(--line-2);
    border-bottom-width: 2px;
    border-radius: var(--radius-xs);
    background: var(--surface-2);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 0.75em;
    line-height: 1;
    vertical-align: 0.1em;
}

/* Inline kód */
:not(pre) > code,
.code {
    padding: 0.12em 0.4em;
    border: 1px solid var(--line);
    border-radius: var(--radius-xs);
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.85em;
}

pre.code-block {
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    color: var(--text-2);
    font-size: 0.8125rem;
    line-height: 1.7;
    overflow-x: auto;
}

/* Licenční klíč / kopírovatelná hodnota
   <div class="keycode"><code class="keycode__value">FLOW-7KQ2-…</code>
     <button class="btn btn--ghost btn--icon btn--sm keycode__copy" data-copy="FLOW-…" aria-label="Copy key">…</button></div> */
.keycode {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    max-width: 100%;
    padding: var(--space-1) var(--space-1) var(--space-1) var(--space-4);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-1);
}

.keycode__value {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.9375rem;
    letter-spacing: 0.08em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.keycode--used .keycode__value {
    color: var(--text-3);
    text-decoration: line-through;
    text-decoration-color: var(--line-3);
}

/* tlačítko po zkopírování: ikona kopírovat → fajfka (main.js přidá .is-copied) */
[data-copy] .copy-done,
[data-copy-target] .copy-done {
    display: none;
}

.is-copied .copy-idle {
    display: none;
}

.is-copied .copy-done {
    display: block;
    color: var(--accent);
}

/* --------------------------------------------------------------------------
   13. Stat tile, definition list, avatar
   <div class="stats">
     <div class="stat"><span class="stat__label">Active subs</span>
       <span class="stat__value" data-count-to="1284">1,284</span>
       <span class="stat__delta stat__delta--up">+12.4%</span></div> …
   </div>
   -------------------------------------------------------------------------- */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
    gap: 1px;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--line);
    overflow: hidden;
}

.stat {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
    padding: var(--space-5);
    background: var(--surface-1);
}

/* samostatná dlaždice mimo .stats */
.stat--card {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}

.stat__label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.stat__value {
    font-size: var(--text-2xl);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.035em;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.stat__unit {
    margin-left: 2px;
    font-size: 0.5em;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--text-3);
}

.stat__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    color: var(--text-3);
}

.stat__delta {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--text-2);
}

.stat__delta--up   { color: var(--accent); }
.stat__delta--down { color: var(--danger); }

/* Definition list — klíč / hodnota s hairline řádky
   <dl class="dl"><div class="dl__row"><dt>Email</dt><dd>…</dd></div>…</dl> */
.dl {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.dl__row {
    display: grid;
    grid-template-columns: minmax(7rem, 2fr) 5fr;
    gap: var(--space-4);
    align-items: baseline;
    padding-block: var(--space-3);
    border-bottom: 1px solid var(--line);
}

.dl__row:first-child {
    padding-top: 0;
}

.dl__row:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.dl dt {
    font-size: var(--text-sm);
    color: var(--text-3);
}

.dl dd {
    margin: 0;
    min-width: 0;
    font-size: var(--text-sm);
    color: var(--text);
    overflow-wrap: anywhere;
}

.dl dd.mono {
    font-size: 0.8125rem;
}

@media (max-width: 30rem) {
    .dl__row {
        grid-template-columns: 1fr;
        gap: var(--space-1);
    }
}

/* Avatar — iniciála: <span class="avatar" aria-hidden="true">X</span> */
.avatar {
    display: inline-grid;
    place-items: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-weight: 500;
    text-transform: uppercase;
    user-select: none;
}

.avatar--sm { width: 24px; height: 24px; font-size: 11px; border-radius: var(--radius-sm); }
.avatar--lg { width: 56px; height: 56px; font-size: 1.25rem; border-radius: var(--radius-lg); }

/* --------------------------------------------------------------------------
   14. Stránkování
   <nav class="pagination" aria-label="Pagination">
     <span class="pagination__info">1–25 of 312</span>
     <ul class="pagination__list">
       <li><a class="pagination__link" href="?page=1" aria-label="Previous page">‹</a></li>
       <li><a class="pagination__link" aria-current="page">1</a></li> …
   -------------------------------------------------------------------------- */
.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.pagination__info {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

.pagination__list {
    display: flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pagination__link {
    display: inline-grid;
    place-items: center;
    min-width: 32px;
    height: 32px;
    padding: 0 var(--space-2);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    transition: background-color var(--dur-fast) ease, color var(--dur-fast) ease;
}

.pagination__link:hover {
    background: var(--surface-2);
    color: var(--text);
}

.pagination__link[aria-current="page"] {
    border-color: var(--line-2);
    background: var(--surface-2);
    color: var(--text);
}

.pagination__link:disabled,
.pagination__link[aria-disabled="true"] {
    opacity: 0.35;
    pointer-events: none;
}

.pagination__gap {
    padding: 0 var(--space-1);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   15. Deck — sticky „slide“ prezentace řízená scrollem (main.js: data-deck)
   <section class="deck" data-deck aria-label="Features">
     <ol class="deck__slides">
       <li class="deck__slide" data-deck-slide>
         <figure class="deck__media"><img …></figure>
         <div class="deck__copy"><p class="eyebrow">…</p><h3 class="deck__title">…</h3><p class="deck__text">…</p></div>
       </li> …
     </ol>
   </section>
   Výchozí stav (bez JS, mobil, reduced-motion): slidy pod sebou.
   .is-enhanced (main.js, ≥ 60rem a bez reduced-motion): sekce N×100svh,
   sticky stage, slidy přes sebe, crossfade + scale, HUD s průběhem.
   -------------------------------------------------------------------------- */
.deck {
    position: relative;
    padding-block: var(--section-y);
}

/* záhlaví decku (volitelné) — v enhanced režimu zůstává ve sticky stage nad slidy */
.deck__head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
    margin-bottom: clamp(var(--space-7), 5vw, var(--space-8));
}

.deck__heading {
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: var(--tracking-tight);
}

.deck__stage {
    position: relative;
}

.deck__slides {
    display: flex;
    flex-direction: column;
    gap: clamp(var(--space-8), 8vw, var(--space-10));
    margin: 0;
    padding: 0;
    list-style: none;
}

.deck__slide {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    align-items: center;
}

@media (min-width: 48rem) {
    .deck__slide {
        grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
        gap: clamp(var(--space-6), 5vw, var(--space-9));
    }
}

.deck__media {
    position: relative;
    margin: 0;
    aspect-ratio: 16 / 10;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    overflow: hidden;
}

.deck__media img,
.deck__media video {
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
}

.deck__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
}

.deck__title {
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.08;
    letter-spacing: var(--tracking-tight);
}

.deck__text {
    font-size: var(--text-md);
    line-height: 1.55;
    color: var(--text-2);
    max-width: 40ch;
}

.deck__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 100%;
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--line);
}

.deck__list li {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    padding-block: var(--space-2);
    border-bottom: 1px solid var(--line);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: 0.03em;
    color: var(--text-2);
}

.deck__hud {
    display: none;
}

/* --- Enhanced: sticky stage --- */
.deck.is-enhanced {
    height: calc(var(--deck-count, 3) * 100svh);
    padding-block: 0;
}

.deck.is-enhanced .deck__head {
    margin-bottom: clamp(var(--space-5), 4vh, var(--space-7));
}

/* média nesmí přerůst výšku okna (notebooky 768 px) */
.deck.is-enhanced .deck__media {
    max-height: 56svh;
    aspect-ratio: auto;
    height: min(56svh, calc((min(100vw, var(--container-wide)) - 2 * var(--gutter)) * 0.58 * 10 / 16));
}

.deck.is-enhanced .deck__stage {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100svh;
    padding-top: var(--header-h);
    overflow: hidden;
}

.deck.is-enhanced .deck__slides {
    display: grid;
    gap: 0;
}

.deck.is-enhanced .deck__slide {
    grid-area: 1 / 1;
    pointer-events: none;
}

.deck.is-enhanced .deck__slide.is-active {
    pointer-events: auto;
}

/* média: crossfade + scale; aktivní slide se při scrollu jemně „oddaluje“ (--deck-p 0→1) */
.deck.is-enhanced .deck__media {
    opacity: 0;
    transition: opacity 0.7s var(--ease-out);
}

.deck.is-enhanced .deck__media img,
.deck.is-enhanced .deck__media video {
    scale: 1.08;
    transition: scale 1.1s var(--ease-out);
}

.deck.is-enhanced .deck__slide.is-active .deck__media {
    opacity: 1;
}

.deck.is-enhanced .deck__slide.is-active .deck__media img,
.deck.is-enhanced .deck__slide.is-active .deck__media video {
    scale: calc(1.06 - var(--deck-p, 0) * 0.06);
    transition: scale 0.25s linear;
}

/* text: odjíždí nahoru/dolů podle směru scrollu (data-dir na .deck) */
.deck.is-enhanced .deck__copy > * {
    opacity: 0;
    translate: 0 28px;
    transition: opacity 0.35s ease, translate 0.6s var(--ease-out);
}

.deck.is-enhanced[data-dir="up"] .deck__copy > * {
    translate: 0 -28px;
}

.deck.is-enhanced .deck__slide.is-active .deck__copy > * {
    opacity: 1;
    translate: none;
    transition: opacity 0.6s var(--ease-out), translate 0.8s var(--ease-out);
    transition-delay: calc(var(--i, 0) * 70ms + 120ms);
}

/* HUD: počítadlo + tick bary (generuje main.js) */
.deck.is-enhanced .deck__hud {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    margin-top: clamp(var(--space-5), 4vh, var(--space-7));
}

.deck__count {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-mono);
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

.deck__count-current {
    color: var(--text);
}

.deck__ticks {
    display: flex;
    flex: 1;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.deck__ticks li {
    flex: 1;
}

.deck__tick {
    display: block;
    width: 100%;
    padding: 10px 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.deck__tick-track {
    display: block;
    height: 2px;
    background: var(--line-2);
    overflow: hidden;
}

.deck__tick-fill {
    display: block;
    height: 100%;
    background: var(--text);
    transform-origin: left center;
    transform: scaleX(var(--tick-p, 0));
}

.deck__tick:hover .deck__tick-track {
    background: var(--line-3);
}

/* --------------------------------------------------------------------------
   16. Reveal (data-reveal) + scroll-driven efekty
   data-reveal="up" (výchozí) | "fade" | "scale" | "clip"
   data-reveal-delay="120" (ms) · data-reveal-stagger="80" na rodiči
   Bez JS je obsah vždy vidět (pravidla platí jen s .js na <html>).
   Pozn.: animace vlastností opacity/translate/clip-path přes keyframes —
   nekoliduje s transitions komponent (hover apod.).
   -------------------------------------------------------------------------- */
.js [data-reveal]:not(.is-in) {
    opacity: 0;
}

.js [data-reveal].is-in {
    animation: revealUp var(--dur-reveal) var(--ease-out) var(--reveal-delay, 0ms) both;
}

.js [data-reveal="fade"].is-in  { animation-name: revealFade; }
.js [data-reveal="scale"].is-in { animation-name: revealScale; }
.js [data-reveal="clip"].is-in  { animation-name: revealClip; animation-duration: 1.2s; }

@keyframes revealUp {
    from { opacity: 0; translate: 0 28px; }
    to   { opacity: 1; translate: none; }
}

@keyframes revealFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes revealScale {
    from { opacity: 0; scale: 0.96; }
    to   { opacity: 1; scale: 1; }
}

@keyframes revealClip {
    from { opacity: 0; clip-path: inset(0 0 100% 0); translate: 0 16px; }
    30%  { opacity: 1; }
    to   { opacity: 1; clip-path: inset(0 0 0 0); translate: none; }
}

/* Scroll-driven (čisté CSS, jen kde je animation-timeline; jinde statické)
   data-scroll="parallax" (--parallax: 48px) | "zoom" | "fade-out" */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        [data-scroll="parallax"] {
            animation: scrollParallax linear both;
            animation-timeline: view();
            animation-range: cover;
        }

        [data-scroll="zoom"] {
            animation: scrollZoom linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 45%;
        }

        [data-scroll="fade-out"] {
            animation: scrollFadeOut linear both;
            animation-timeline: view();
            animation-range: exit 0% exit 80%;
        }
    }
}

@keyframes scrollParallax {
    from { translate: 0 var(--parallax, 48px); }
    to   { translate: 0 calc(var(--parallax, 48px) * -1); }
}

@keyframes scrollZoom {
    from { scale: 0.9; opacity: 0.4; }
    to   { scale: 1; opacity: 1; }
}

@keyframes scrollFadeOut {
    to { opacity: 0; }
}

/* Counter (data-count-to) — cifry stejně široké, ať text „neskáče“ */
[data-count-to] {
    font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
    .js [data-reveal],
    .js [data-reveal].is-in {
        opacity: 1;
        animation: none;
    }

    .status__dot::after,
    .skeleton {
        animation: none;
    }

    .btn {
        translate: none;
    }
}

/* --------------------------------------------------------------------------
   17. FAQ — nativní <details> s plynulým rozbalením
   <div class="faq">
     <details class="faq__item" name="faq">
       <summary class="faq__q"><span class="faq__index">01</span><span class="faq__title">Question?</span><span class="faq__icon" aria-hidden="true"></span></summary>
       <div class="faq__a"><p>Answer.</p></div>
     </details> …
   Animace výšky: ::details-content + interpolate-size (Chromium); jinde se rozbalí hned.
   -------------------------------------------------------------------------- */
.faq {
    border-top: 1px solid var(--line);
    interpolate-size: allow-keywords;
}

.faq__item {
    border-bottom: 1px solid var(--line);
}

.faq__q {
    display: grid;
    grid-template-columns: 2.5rem 1fr auto;
    align-items: baseline;
    gap: var(--space-3);
    padding-block: var(--space-5);
    list-style: none;
    cursor: pointer;
    color: var(--text);
    font-size: var(--text-lg);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: -0.01em;
    transition: color var(--dur) ease;
}

.faq__q::-webkit-details-marker {
    display: none;
}

.faq__q::marker {
    content: "";
}

.faq__q:hover .faq__title {
    color: var(--text);
}

.faq__index {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 400;
    letter-spacing: var(--tracking-mono);
    color: var(--text-3);
}

.faq__title {
    color: var(--text-2);
    transition: color var(--dur) ease;
}

.faq__item[open] .faq__title {
    color: var(--text);
}

/* plus → minus */
.faq__icon {
    position: relative;
    align-self: center;
    width: 14px;
    height: 14px;
}

.faq__icon::before,
.faq__icon::after {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 100%;
    height: 1.5px;
    margin-top: -0.75px;
    border-radius: 1px;
    background: var(--text-2);
    transition: rotate 0.4s var(--ease-out), background-color var(--dur) ease;
}

.faq__icon::after {
    rotate: 90deg;
}

.faq__item[open] .faq__icon::after {
    rotate: 0deg;
}

.faq__item[open] .faq__icon::before,
.faq__item[open] .faq__icon::after {
    background: var(--text);
}

.faq__item::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size 0.5s var(--ease-out), content-visibility 0.5s allow-discrete;
}

.faq__item[open]::details-content {
    block-size: auto;
}

.faq__a {
    padding: 0 0 var(--space-6) calc(2.5rem + var(--space-3));
    max-width: calc(64ch + 2.5rem);
    color: var(--text-2);
    line-height: 1.65;
    opacity: 0;
    translate: 0 -6px;
    transition: opacity 0.4s ease, translate 0.5s var(--ease-out);
}

.faq__item[open] .faq__a {
    opacity: 1;
    translate: none;
    transition-delay: 0.08s;
}

.faq__a p + p {
    margin-top: var(--space-3);
}

@media (max-width: 40rem) {
    .faq__q {
        grid-template-columns: 1fr auto;
        font-size: var(--text-base);
    }

    .faq__index {
        display: none;
    }

    .faq__a {
        padding-left: 0;
    }
}

/* Word reveal — data-words (main.js rozdělí text na .word se --i)
   Kde je animation-timeline: slova se rozsvěcují podle scrollu (scrub, krok --word-step).
   Jinde, nebo s data-words="time" (.words--time — pro text nad ohybem stránky, kam se
   nedá doscrollovat): po vstupu do viewportu (.is-in) postupně s transition-delay. */
.words .word {
    display: inline-block;
}

.js .words .word {
    opacity: 0.14;
    transition: opacity 0.7s var(--ease-out), translate 0.7s var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--word-delay, 90ms));
}

.js .words.is-in .word {
    opacity: 1;
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .js .words:not(.words--time) {
            view-timeline: --words block;
        }

        .js .words:not(.words--time) .word,
        .js .words.is-in:not(.words--time) .word {
            opacity: 1;
            transition: none;
            animation: wordLight linear both;
            animation-timeline: --words;
            /* [AUDIT A6] dřív 12 % → 26 % + i × 4 %: nadpis byl celý čitelný až v horní polovině okna
               (ve spodní polovině slova 1,4:1). Teď je dosvícený, než vystoupá nad ~70 % výšky okna. */
            animation-range: cover calc(2% + var(--i, 0) * var(--word-step, 2.5%)) cover calc(14% + var(--i, 0) * var(--word-step, 2.5%));
        }
    }
}

@keyframes wordLight {
    from { opacity: 0.14; translate: 0 0.12em; }
    to   { opacity: 1; translate: none; }
}

/* Kroky s propojovací čarou, která se „kreslí“ při scrollu
   <ol class="steps" data-steps><li class="steps__item"><span class="steps__node">01</span><div class="steps__body">…</div></li>…</ol>
   Kde je animation-timeline: čára i uzly podle scrollu; jinde .is-in (main.js) + transition. */
.steps {
    --steps-node: 40px;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* kolejnice + výplň */
.steps::before,
.steps::after {
    content: "";
    position: absolute;
    left: calc(var(--steps-node) / 2 - 0.5px);
    top: calc(var(--steps-node) / 2);
    bottom: calc(var(--steps-node) / 2);
    width: 1px;
    background: var(--line-2);
}

.steps::after {
    background: linear-gradient(to bottom, var(--accent), rgba(var(--accent-rgb), 0.4));
    transform-origin: top center;
    transform: scaleY(0);
    transition: transform 1.4s var(--ease-out);
}

.steps.is-in::after {
    transform: scaleY(1);
}

.steps__item {
    position: relative;
    display: grid;
    grid-template-columns: var(--steps-node) 1fr;
    gap: var(--space-5);
    align-items: start;
}

.steps__node {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: var(--steps-node);
    height: var(--steps-node);
    border: 1px solid var(--line-2);
    border-radius: 50%;
    background: var(--bg);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    transition: border-color 0.5s ease, color 0.5s ease, box-shadow 0.5s ease;
    transition-delay: calc(var(--i, 0) * 450ms);
}

.steps.is-in .steps__node {
    border-color: var(--accent-line);
    color: var(--text);
}

.steps__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: 0.45rem;
}

.steps__title {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
}

.steps__text {
    color: var(--text-2);
    max-width: 46ch;
}

.steps__meta {
    margin-top: var(--space-2);
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .js .steps {
            view-timeline: --steps block;
        }

        .js .steps::after,
        .js .steps.is-in::after {
            transition: none;
            animation: stepsLine linear both;
            animation-timeline: --steps;
            animation-range: cover 12% cover 48%;
        }

        .js .steps__node,
        .js .steps.is-in .steps__node {
            transition: none;
            animation: stepsNode linear both;
            animation-timeline: --steps;
            animation-range: cover calc(12% + var(--i, 0) * 17%) cover calc(16% + var(--i, 0) * 17%);
        }
    }
}

@keyframes stepsLine {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
}

@keyframes stepsNode {
    from { border-color: var(--line-2); color: var(--text-3); }
    to   { border-color: var(--accent-line); color: var(--text); }
}

/* Timeline — veřejná historie stavu produktu (status_history())
   <ol class="timeline"><li class="timeline__item status--undetected">
     <span class="status__dot timeline__dot"></span><div class="timeline__body">…</div><time class="timeline__time">…</time></li></ol> */
.timeline {
    position: relative;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.timeline::before {
    content: "";
    position: absolute;
    left: 3px;
    top: 0.9rem;
    bottom: 0.9rem;
    width: 1px;
    background: var(--line-2);
}

.timeline__item {
    position: relative;
    display: grid;
    grid-template-columns: 7px 1fr auto;
    gap: var(--space-4);
    align-items: baseline;
    padding-block: var(--space-3);
}

.timeline__dot {
    position: relative;
    top: -1px;
    width: 7px;
    height: 7px;
    box-shadow: 0 0 0 4px var(--bg);
}

/* puls jen u aktuálního (prvního) záznamu */
.timeline__item:not(:first-child) .timeline__dot::after {
    animation: none;
}

.timeline__item:not(:first-child) .timeline__dot {
    opacity: 0.6;
}

.timeline__label {
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text);
}

.timeline__note {
    font-size: var(--text-sm);
    color: var(--text-3);
}

.timeline__time {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--text-3);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 30rem) {
    .timeline__item {
        grid-template-columns: 7px 1fr;
    }

    .timeline__time {
        grid-column: 2;
    }
}

/* Checklist — seznam s fajfkou: <ul class="checklist"><li>…</li></ul> */
.checklist {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.checklist > li {
    position: relative;
    padding-left: 1.625rem;
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--text-2);
}

.checklist > li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.3em;
    width: 14px;
    height: 14px;
    background: var(--accent);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 7.3 2.6 2.5L11 4.3'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 7.3 2.6 2.5L11 4.3'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Scroll hint pod CTA v hero */
.scroll-hint {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.scroll-hint::after {
    content: "";
    width: 1px;
    height: 28px;
    background: linear-gradient(to bottom, var(--text-2), transparent);
    transform-origin: top center;
    animation: scrollHint 2.2s var(--ease-in-out) infinite;
}

@keyframes scrollHint {
    0%   { transform: scaleY(0); opacity: 1; }
    60%  { transform: scaleY(1); opacity: 1; }
    100% { transform: scaleY(1); opacity: 0; }
}

/* --------------------------------------------------------------------------
   18. Ilustrace — CSS/SVG kompozice (includes/layout/art-radar.php, art-hud.php)
   Vyplní rodiče (např. .deck__media). Jen dekorace → aria-hidden nebo role="img" + aria-label.
   -------------------------------------------------------------------------- */
.art {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background:
        linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 48px 48px,
        linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 48px 48px,
        radial-gradient(120% 90% at 50% 50%, var(--surface-2), var(--surface-1) 70%);
    color: var(--text-2);
}

/* mřížka mizí k okrajům */
.art::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(80% 70% at 50% 50%, transparent 40%, var(--surface-1) 100%);
    pointer-events: none;
}

.art__label {
    position: absolute;
    z-index: 2;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.art__label--tl { top: var(--space-4); left: var(--space-4); }
.art__label--tr { top: var(--space-4); right: var(--space-4); }
.art__label--bl { bottom: var(--space-4); left: var(--space-4); }
.art__label--br { bottom: var(--space-4); right: var(--space-4); }

/* Radar */
.art-radar__scope {
    position: absolute;
    z-index: 1;
    top: 50%;
    left: 50%;
    width: min(78%, calc(100% - 3rem));
    aspect-ratio: 1;
    max-height: 86%;
    translate: -50% -50%;
}

.art-radar__scope svg {
    width: 100%;
    height: 100%;
    overflow: visible;
}

.art-radar__sweep {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    /* světlá náběžná hrana (360°) a dohasínající stopa za ní */
    background: conic-gradient(from 0deg, transparent 0deg 280deg, rgba(237, 238, 240, 0.18) 360deg);
    -webkit-mask: radial-gradient(circle, #000 69.5%, transparent 70%);
    mask: radial-gradient(circle, #000 69.5%, transparent 70%);
    animation: radarSweep 5s linear infinite;
}

.art-radar .ring { fill: none; stroke: var(--line-2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.art-radar .ring--outer { stroke: var(--line-3); }
.art-radar .axis { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.art-radar .you { fill: var(--text); }
.art-radar .you-fov { fill: rgba(237, 238, 240, 0.08); stroke: rgba(237, 238, 240, 0.25); stroke-width: 1; vector-effect: non-scaling-stroke; }
.art-radar .enemy { fill: var(--danger); }
.art-radar .enemy-fov { fill: rgba(var(--danger-rgb), 0.14); }
.art-radar .mate { fill: var(--info); }
.art-radar .mate-fov { fill: rgba(var(--info-rgb), 0.12); }
.art-radar .bomb { fill: none; stroke: var(--warning); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.art-radar .tag { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.06em; fill: var(--text-3); }

/* „ping“ nepřátel, když přes ně přejede sweep (zpoždění podle úhlu --a v sekundách) */
.art-radar .ping {
    fill: none;
    stroke: var(--danger);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    transform-box: fill-box;
    transform-origin: center;
    opacity: 0;
    animation: radarPing 5s var(--ease-out) infinite;
    animation-delay: var(--a, 0s);
}

@keyframes radarSweep {
    to { rotate: 360deg; }
}

@keyframes radarPing {
    0%   { opacity: 0.9; scale: 1; }
    30%  { opacity: 0; scale: 3.2; }
    100% { opacity: 0; scale: 3.2; }
}

/* HUD — malé info prvky (bomb timer, spectators, bomb carrier, granát) */
.art-hud__grid {
    position: absolute;
    z-index: 1;
    inset: clamp(1.25rem, 6%, 3rem);
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: clamp(0.5rem, 2.5%, 1rem);
}

.art-hud__panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
    padding: clamp(0.75rem, 3%, 1.25rem);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: rgba(var(--bg-rgb), 0.72);
    font-family: var(--font-mono);
    font-size: clamp(9px, 1.1vw, 11px);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-3);
    overflow: hidden;
}

.art-hud__panel--tall {
    grid-row: span 2;
}

.art-hud__big {
    font-family: var(--font-sans);
    font-size: clamp(1.75rem, 4.6vw, 3.5rem);
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--text);
    text-transform: none;
    font-variant-numeric: tabular-nums;
}

.art-hud__big small {
    font-size: 0.4em;
    letter-spacing: 0;
    color: var(--text-3);
}

.art-hud__bar {
    height: 3px;
    margin-top: auto;
    border-radius: 2px;
    background: var(--line-2);
    overflow: hidden;
}

.art-hud__bar span {
    display: block;
    height: 100%;
    background: var(--warning);
    transform-origin: left center;
    animation: hudTimer 40s linear infinite;
}

@keyframes hudTimer {
    from { transform: scaleX(0.81); }
    to   { transform: scaleX(0); }
}

.art-hud__row {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    padding-block: 6px;
    border-top: 1px solid var(--line);
    color: var(--text-2);
    text-transform: none;
    letter-spacing: 0.02em;
}

.art-hud__tag {
    align-self: flex-start;
    padding: 4px 7px;
    border: 1px solid rgba(var(--warning-rgb), 0.45);
    border-radius: var(--radius-xs);
    color: var(--warning);
}

.art-hud__player {
    position: relative;
    flex: 1 1 0;
    min-height: 0;
    aspect-ratio: 1 / 1.9;
    align-self: center;
    margin-top: var(--space-2);
    border: 1px solid rgba(var(--danger-rgb), 0.7);
}

.art-hud__player::after {
    content: "";
    position: absolute;
    left: -7px;
    top: 0;
    bottom: 0;
    width: 3px;
    background: linear-gradient(to top, var(--accent) 64%, var(--line-2) 64%);
}

.art-hud__arc {
    flex: 1;
    min-height: 0;
    width: 100%;
}

.art-hud__arc path {
    fill: none;
    stroke: var(--text-2);
    stroke-width: 1.5;
    stroke-dasharray: 4 5;
    vector-effect: non-scaling-stroke;
}

.art-hud__arc circle {
    fill: rgba(var(--accent-rgb), 0.12);
    stroke: var(--accent);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    transform-box: fill-box;
    transform-origin: center;
    animation: hudLand 2.4s var(--ease-out) infinite;
}

@keyframes hudLand {
    0%, 40% { scale: 0.4; opacity: 0; }
    55%     { scale: 1; opacity: 1; }
    100%    { scale: 1.15; opacity: 0.2; }
}

@media (prefers-reduced-motion: reduce) {
    .art-radar__sweep,
    .art-radar .ping,
    .art-hud__bar span,
    .art-hud__arc circle,
    .scroll-hint::after {
        animation: none;
    }

    .art-hud__arc circle {
        opacity: 1;
    }
}

/* Na úzkých displejích potřebují ilustrace víc výšky než 16:10 */
@media (max-width: 47.99rem) {
    .deck__media--art,
    .feature-cat__media:has(> .art) {
        aspect-ratio: 1 / 1;
    }
}

/* ==========================================================================
   v4 — komponenty pro dashboard, admin, podporu a účet
   Kontrakt tříd/atributů: docs/DESIGN.md (sekce v4) · ukázky: dev/styleguide.php
   ========================================================================== */

/* --------------------------------------------------------------------------
   19. Dashboard layout — sdílený pro profil i admin
   <div class="dash" data-dash>
     <nav class="dash__nav" aria-label="Account">
       <p class="dash__group">Account</p>                      (volitelné, jen desktop)
       <ul class="dash__list">
         <li><a class="dash__item" href="#overview" aria-current="page">
               <svg class="icon">…</svg><span class="dash__label">Overview</span>
               <span class="dash__count">3</span></a></li> …
     </nav>
     <div class="dash__main">
       <section class="dash__panel is-active" id="overview">…</section> …
   ≥ 60rem: sidebar vlevo (sticky). Pod 60rem: horizontální taby (scroll), skupiny skryté.
   Aktivní položka = aria-current (page | true | location). data-dash = přepínání panelů
   podle #hash (main.js); bez JS jsou všechny panely pod sebou a odkazy fungují jako kotvy.
   -------------------------------------------------------------------------- */
.dash {
    --dash-nav-w: 15rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
}

.dash__nav {
    position: sticky;
    top: var(--header-h);
    z-index: 2;
    min-width: 0;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    border-bottom: 1px solid var(--line);
    background: rgba(var(--bg-rgb), 0.92);
}

.dash__list {
    display: flex;
    gap: var(--space-1);
    margin: 0;
    padding: var(--space-2) 0;
    list-style: none;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    /* jemné ztmavení okrajů naznačí, že se dá posouvat */
    -webkit-mask: linear-gradient(to right, transparent 0, #000 var(--space-3), #000 calc(100% - var(--space-5)), transparent 100%);
    mask: linear-gradient(to right, transparent 0, #000 var(--space-3), #000 calc(100% - var(--space-5)), transparent 100%);
}

.dash__list::-webkit-scrollbar {
    display: none;
}

.dash__list > li {
    flex-shrink: 0;
    scroll-snap-align: start;
}

.dash__group {
    display: none;
}

.dash__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 36px;
    padding: 0 var(--space-3);
    border-radius: var(--radius-md);
    color: var(--text-2);
    font-size: var(--text-sm);
    font-weight: 450;
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--dur) ease, background-color var(--dur) ease;
}

.dash__item .icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--text-3);
    transition: color var(--dur) ease;
}

.dash__item:hover {
    color: var(--text);
    background: var(--surface-1);
}

.dash__item[aria-current]:not([aria-current="false"]) {
    color: var(--text);
    background: var(--surface-2);
}

.dash__item[aria-current]:not([aria-current="false"]) .icon {
    color: var(--accent);
}

.dash__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash__count {
    margin-left: auto;
    min-width: 20px;
    padding: 1px 6px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-pill);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: 16px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* počet, který čeká na akci (nové tickety…) */
.dash__count--attention {
    border-color: var(--accent-line);
    color: var(--accent);
}

.dash__main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.dash__panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    min-width: 0;
    scroll-margin-top: calc(var(--header-h) + 64px);
}

.dash__panel:focus {
    outline: none;
}

/* záhlaví panelu: nadpis + akce */
.dash__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-3) var(--space-5);
}

.dash__title {
    font-size: clamp(1.375rem, 1.2rem + 0.5vw, 1.625rem);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: var(--tracking-snug);
}

.dash__desc {
    margin-top: var(--space-1);
    font-size: var(--text-sm);
    color: var(--text-3);
}

/* s JS: viditelný jen aktivní panel (výchozí aktivní vykreslí server s .is-active) */
.js .dash[data-dash] .dash__panel:not(.is-active) {
    display: none;
}

@media (min-width: 60rem) {
    .dash {
        grid-template-columns: var(--dash-nav-w) minmax(0, 1fr);
        gap: clamp(var(--space-6), 3vw, var(--space-8));
    }

    .dash__nav {
        top: calc(var(--header-h) + var(--space-5));
        margin: 0;
        padding: 0;
        border: 0;
        background: none;
        max-height: calc(100dvh - var(--header-h) - var(--space-7));
        overflow-y: auto;
        scrollbar-width: thin;
    }

    .dash__list {
        flex-direction: column;
        gap: 2px;
        padding: 0;
        overflow: visible;
        -webkit-mask: none;
        mask: none;
    }

    .dash__group {
        display: block;
        margin: var(--space-5) 0 var(--space-2);
        padding-inline: var(--space-3);
        font-family: var(--font-mono);
        font-size: 11px;
        letter-spacing: var(--tracking-mono);
        text-transform: uppercase;
        color: var(--text-3);
    }

    .dash__group:first-child {
        margin-top: 0;
    }

    /* aktivní položka: tenká linka vlevo */
    .dash__item[aria-current]:not([aria-current="false"])::before {
        content: "";
        position: absolute;
        left: 0;
        top: 9px;
        bottom: 9px;
        width: 2px;
        border-radius: 2px;
        background: var(--accent);
    }
}

/* --------------------------------------------------------------------------
   20. Command palette — <dialog class="cmdk"> vytváří main.js (Flowsense.cmdk)
   Stránka dodá zdroj: Flowsense.cmdk.setSource(async q => [{type, id, label, sub, href}]).
   Ctrl/Cmd+K otevře (jen když je zdroj nastavený), ↑↓ výběr, Enter otevře, Esc zavře.
   Spouštěč v UI: <button data-cmdk-open>Search <kbd class="kbd">Ctrl K</kbd></button>
   -------------------------------------------------------------------------- */
.cmdk {
    width: min(calc(100vw - 2rem), 640px);
    max-height: min(calc(100dvh - 4rem), 560px);
    margin: min(12vh, 120px) auto auto;
    padding: 0;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-xl);
    background: var(--surface-overlay);
    color: var(--text);
    box-shadow: var(--shadow-float);
    overflow: hidden;
    transition: opacity var(--dur) ease, translate var(--dur-slow) var(--ease-out), scale var(--dur-slow) var(--ease-out),
                overlay var(--dur) allow-discrete, display var(--dur) allow-discrete;
}

.cmdk[open] {
    display: flex;
    flex-direction: column;
}

.cmdk::backdrop {
    background: rgba(0, 0, 0, 0.62);
    transition: opacity var(--dur) ease, overlay var(--dur) allow-discrete, display var(--dur) allow-discrete;
}

.cmdk:not([open]),
.cmdk:not([open])::backdrop {
    opacity: 0;
}

@starting-style {
    .cmdk[open],
    .cmdk[open]::backdrop {
        opacity: 0;
    }

    .cmdk[open] {
        scale: 0.98;
        translate: 0 -6px;
    }
}

html:has(.cmdk[open]) {
    overflow: hidden;
}

.cmdk__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-4);
    border-bottom: 1px solid var(--line);
}

.cmdk__head > .icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    color: var(--text-3);
}

.cmdk__input {
    flex: 1;
    min-width: 0;
    height: 56px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--text);
    font-size: var(--text-md);
    letter-spacing: -0.01em;
}

.cmdk__input::placeholder {
    color: var(--text-3);
    opacity: 1;
}

.cmdk__input:focus,
.cmdk__input:focus-visible {
    outline: none;
}

/* focus je vidět na celé hlavičce (input nemá vlastní rámeček) */
.cmdk__head:focus-within {
    box-shadow: inset 0 -2px 0 var(--focus-line);
}

.cmdk__spinner {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    border: 1.5px solid var(--text-3);
    border-right-color: transparent;
    border-radius: 50%;
    animation: btnSpin 0.7s linear infinite;
}

.cmdk__spinner[hidden] {
    display: none;
}

.cmdk__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-2);
    scroll-padding-block: var(--space-6) var(--space-2);
}

.cmdk__list,
.cmdk__options {
    margin: 0;
    padding: 0;
    list-style: none;
}

.cmdk__group + .cmdk__group {
    margin-top: var(--space-2);
}

.cmdk__group-label {
    padding: var(--space-2) var(--space-3) var(--space-1);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.cmdk__item {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    min-height: 48px;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    color: var(--text-2);
    cursor: pointer;
    user-select: none;
}

.cmdk__item[aria-selected="true"] {
    background: var(--surface-3);
    color: var(--text);
}

.cmdk__icon {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    color: var(--text-3);
}

.cmdk__icon .icon {
    width: 14px;
    height: 14px;
}

.cmdk__item[aria-selected="true"] .cmdk__icon {
    border-color: var(--line-3);
    color: var(--text);
}

.cmdk__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cmdk__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
}

.cmdk__sub {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.02em;
}

.cmdk__mark {
    background: none;
    color: var(--accent);
}

.cmdk__enter {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    opacity: 0;
}

.cmdk__item[aria-selected="true"] .cmdk__enter {
    opacity: 1;
}

.cmdk__empty {
    padding: var(--space-7) var(--space-4);
    text-align: center;
    color: var(--text-3);
    font-size: var(--text-sm);
}

.cmdk__empty[hidden] {
    display: none;
}

.cmdk__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-2) var(--space-4);
    border-top: 1px solid var(--line);
    color: var(--text-3);
    font-size: var(--text-xs);
}

.cmdk__foot .kbd {
    margin-right: 2px;
}

@media (max-width: 30rem) {
    .cmdk {
        margin-top: var(--space-4);
    }

    .cmdk__foot {
        display: none;
    }
}

/* tlačítko „Search… Ctrl K“ v hlavičce adminu */
.cmdk-trigger {
    justify-content: flex-start;
    min-width: 12rem;
    color: var(--text-3);
}

.cmdk-trigger .kbd {
    margin-left: auto;
}

/* --------------------------------------------------------------------------
   21. Grafy — <div class="chart" data-chart-title="Registrations"></div>
   Flowsense.chart(el, {type: 'bar'|'line', labels: [...], series: [{name, values}], format})
   JS vykreslí inline SVG (osy, mřížka), tooltip, legendu (2+ řady) a skrytou tabulku dat.
   -------------------------------------------------------------------------- */
.chart {
    --chart-h: 220px;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
}

.chart__plot {
    position: relative;
    height: var(--chart-h);
    min-width: 0;
    border-radius: var(--radius-sm);
    touch-action: pan-y;
}

.chart__plot:focus-visible {
    outline-offset: 4px;
}

.chart__svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.chart__grid {
    stroke: var(--chart-grid);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.chart__baseline {
    stroke: var(--line-3);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.chart__tick {
    fill: var(--text-3);
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
}

.chart__bar {
    transition: opacity var(--dur-fast) ease;
}

.chart__plot.is-hovering .chart__bar:not(.is-active) {
    opacity: 0.45;
}

.chart__line {
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.chart__area {
    opacity: 0.1;
}

.chart__dot {
    stroke: var(--surface-1);
    stroke-width: 2;
}

.chart__cross {
    stroke: var(--line-3);
    stroke-width: 1;
    shape-rendering: crispEdges;
}

/* vstupní animace (vypnutá při reduced-motion — JS ji vůbec nepřidá) */
.chart.is-animating .chart__bar {
    transform-box: fill-box;
    transform-origin: 50% 100%;
    animation: chartGrow 0.7s var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 18ms);
}

.chart.is-animating .chart__line {
    stroke-dasharray: var(--len) var(--len);
    animation: chartDraw 1s var(--ease-out) both;
}

.chart.is-animating .chart__area {
    animation: chartFade 1s ease both;
}

@keyframes chartGrow {
    from { transform: scaleY(0); }
}

@keyframes chartDraw {
    from { stroke-dashoffset: var(--len); }
    to   { stroke-dashoffset: 0; }
}

@keyframes chartFade {
    from { opacity: 0; }
}

.chart__tooltip {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 3;
    min-width: 8rem;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-overlay);
    box-shadow: var(--shadow-float);
    pointer-events: none;
    font-size: var(--text-xs);
    line-height: 1.5;
    white-space: nowrap;
    transition: opacity var(--dur-fast) ease;
}

.chart__tooltip[hidden] {
    display: block;
    opacity: 0;
    visibility: hidden;
}

.chart__tooltip-title {
    margin-bottom: 2px;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
}

.chart__tooltip-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.chart__tooltip-value {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.chart__tooltip-name {
    color: var(--text-3);
}

/* klíč řady: krátká linka (tooltip) / obdélník (legenda u sloupců) */
.chart__key {
    display: inline-block;
    flex-shrink: 0;
    width: 10px;
    height: 2px;
    border-radius: 1px;
    background: var(--key, var(--accent));
}

.chart__legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--text-2);
    font-size: var(--text-xs);
}

.chart__legend li {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.chart--bar .chart__legend .chart__key {
    width: 8px;
    height: 8px;
    border-radius: 2px;
}

.chart__empty {
    display: grid;
    place-items: center;
    height: var(--chart-h);
    border: 1px dashed var(--line-2);
    border-radius: var(--radius-md);
    color: var(--text-3);
    font-size: var(--text-sm);
}

/* Uptime pruh (status.php) — N denních segmentů; barva = nejhorší stav dne
   <ol class="uptime" aria-hidden="true"><li class="uptime__day status--updating" title="…"></li>…</ol> */
.uptime {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 2px;
    height: 36px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* barvu dodá třída stavu (.status--… nastavuje --status-rgb) */
.uptime__day {
    border-radius: 2px;
    background: rgba(var(--status-rgb, var(--accent-rgb)), 0.9);
    transition: opacity var(--dur-fast) ease;
}

.uptime__day.status--undetected { background: rgba(var(--accent-rgb), 0.7); }
.uptime__day.is-empty { background: var(--surface-3); }

.uptime:hover .uptime__day:not(:hover) {
    opacity: 0.55;
}

.uptime-meta {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-2);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.uptime-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--text-3);
    font-size: var(--text-xs);
}

.uptime-legend li {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.uptime-legend .uptime__day {
    display: inline-block;
    width: 8px;
    height: 12px;
}

@media (max-width: 40rem) {
    /* na mobilu 30 dní místo 90 — starší segmenty skryje třída na položce */
    .uptime__day.is-older {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   22. Notifikace — zvoneček v nav (includes/layout/nav.php + assets/js/notifications.js)
   <div class="notif" data-notifications data-api="…/api/account.php" hidden>
     <button class="notif__btn" aria-expanded="false" aria-controls="notif-panel">…<span class="notif__count"></span></button>
     <div class="notif__panel" id="notif-panel" hidden> header + <ul class="notif__list"> + empty
   JS ho odkryje až po úspěšném notifications_list; při chybě/404 zůstane skrytý.
   -------------------------------------------------------------------------- */
.notif {
    position: relative;
    display: flex;
}

.notif[hidden] {
    display: none;
}

.notif__btn {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-2);
    transition: color var(--dur) ease, background-color var(--dur) ease, border-color var(--dur) ease;
}

.notif__btn:hover,
.notif__btn[aria-expanded="true"] {
    color: var(--text);
    background: var(--surface-2);
}

.notif__btn .icon {
    width: 17px;
    height: 17px;
}

/* text tlačítka je na desktopu jen pro čtečky, v mobilním panelu viditelný */
.notif__btn-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.notif__count {
    position: absolute;
    top: 1px;
    right: 0;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: var(--on-accent);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    line-height: 16px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 0 0 2px var(--bg);
}

.notif__count:empty,
.notif__count[hidden] {
    display: none;
}

.notif__panel {
    position: absolute;
    top: calc(100% + var(--space-2));
    right: 0;
    z-index: var(--z-overlay);
    display: flex;
    flex-direction: column;
    width: min(calc(100vw - 2rem), 380px);
    max-height: min(70dvh, 520px);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    background: var(--surface-overlay);
    box-shadow: var(--shadow-float);
    overflow: hidden;
    transition: opacity var(--dur) ease, translate var(--dur) var(--ease-out), display var(--dur) allow-discrete;
}

.notif__panel[hidden] {
    display: none;
    opacity: 0;
    translate: 0 -4px;
}

@starting-style {
    .notif__panel:not([hidden]) {
        opacity: 0;
        translate: 0 -4px;
    }
}

.notif__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line);
}

.notif__title {
    font-size: var(--text-sm);
    font-weight: 600;
}

.notif__list {
    flex: 1 1 auto;
    min-height: 0;
    margin: 0;
    padding: var(--space-1);
    list-style: none;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.notif__item {
    position: relative;
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr);
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-3);
    border: 0;
    border-radius: var(--radius-md);
    background: none;
    color: var(--text-2);
    font-size: var(--text-sm);
    line-height: 1.45;
    text-align: left;
    text-decoration: none;
}

a.notif__item:hover,
button.notif__item:hover {
    background: var(--surface-2);
    color: var(--text-2);
}

.notif__dot {
    width: 6px;
    height: 6px;
    margin-top: 0.5em;
    border-radius: 50%;
    background: transparent;
}

.notif__item.is-unread .notif__dot {
    background: var(--accent);
}

.notif__item-title {
    display: block;
    color: var(--text);
    font-weight: 500;
}

.notif__item:not(.is-unread) .notif__item-title {
    color: var(--text-2);
}

.notif__item-body {
    display: block;
    margin-top: 1px;
    color: var(--text-3);
    overflow-wrap: anywhere;
}

.notif__item-time {
    display: block;
    margin-top: var(--space-1);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
}

.notif__empty {
    padding: var(--space-7) var(--space-4);
    text-align: center;
    color: var(--text-3);
    font-size: var(--text-sm);
}

/* mobilní nav: zvoneček je v celoplošném panelu jako řádek; nepřečtené = tečka na hamburgeru */
@media (max-width: 59.99rem) {
    .js .nav__auth .notif {
        flex-direction: column;
    }

    .js .nav__auth .notif__btn {
        display: flex;
        justify-content: center;
        gap: var(--space-2);
        width: 100%;
        height: 48px;
        border-color: var(--line-2);
        color: var(--text);
        font-size: var(--text-sm);
        font-weight: 500;
    }

    .js .nav__auth .notif__btn-text {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip-path: none;
    }

    .js .nav__auth .notif__count {
        position: static;
        box-shadow: none;
    }

    .js .nav__auth .notif__panel {
        position: static;
        width: 100%;
        max-height: none;
        margin-top: var(--space-2);
        box-shadow: none;
    }

    .js .nav__auth .notif__panel .btn {
        width: auto;
        height: auto;
        min-height: 32px;
        --btn-border: transparent;
    }

    .nav__toggle.has-unread::after {
        content: "";
        position: absolute;
        top: 9px;
        right: 8px;
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: var(--accent);
        box-shadow: 0 0 0 2px var(--bg);
    }
}

/* --------------------------------------------------------------------------
   23. Ticket thread, composer, stavy ticketu
   <ol class="thread">
     <li class="msg msg--user|msg--staff|msg--internal">
       <div class="msg__head"><span class="avatar avatar--sm">P</span><span class="msg__author">proteinik</span>
         <span class="msg__role">Staff</span><time class="msg__time">…</time></div>
       <div class="msg__body">Text (white-space: pre-wrap; vkládat textContent)</div></li>
     <li class="msg msg--system"><p class="msg__body">Ticket closed · 4 Oct</p></li>
   </ol>
   -------------------------------------------------------------------------- */
.thread {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.msg {
    --msg-line: var(--line);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--msg-line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    min-width: 0;
}

/* odpověď podpory: akcentová linka vlevo */
.msg--staff {
    --msg-line: var(--line-2);
    box-shadow: inset 2px 0 0 var(--accent);
}

/* interní poznámka (vidí jen staff) */
.msg--internal {
    --msg-line: rgba(var(--warning-rgb), 0.3);
    border-style: dashed;
    background: rgba(var(--warning-rgb), 0.035);
}

.msg__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    min-width: 0;
}

.msg__author {
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 600;
}

.msg__role {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-3);
}

.msg--staff .msg__role {
    color: var(--accent);
}

.msg--internal .msg__role {
    color: var(--warning);
}

.msg__time {
    margin-left: auto;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.msg__body {
    color: var(--text-2);
    font-size: 0.9375rem;
    line-height: 1.65;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* systémová událost: řádek uprostřed mezi hairlines */
.msg--system {
    flex-direction: row;
    align-items: center;
    gap: var(--space-3);
    padding: 0;
    border: 0;
    background: none;
}

.msg--system::before,
.msg--system::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

.msg--system .msg__body {
    flex: 0 1 auto;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    text-align: center;
    white-space: normal;
}

/* Composer — <form class="composer"><label class="visually-hidden" for="r">Reply</label>
   <textarea class="input composer__input" id="r"></textarea>
   <div class="composer__bar"><span class="composer__hint">…</span><div class="composer__actions">…</div></div></form> */
.composer {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}

.composer:focus-within {
    border-color: var(--focus-line);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

.composer.is-internal {
    border-color: rgba(var(--warning-rgb), 0.45);
    border-style: dashed;
}

.composer__input,
.composer__input:focus,
.composer__input:hover {
    min-height: 6.5rem;
    padding: var(--space-4);
    border: 0;
    background: transparent;
    box-shadow: none;
    resize: vertical;
}

.composer__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
    border-top: 1px solid var(--line);
}

.composer__hint {
    color: var(--text-3);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
}

.composer__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-left: auto;
}

/* Stav ticketu — <span class="ticket-state ticket-state--open">Open</span>
   open = čeká na podporu (akcent), waiting = čeká na uživatele (warning), closed = neutrální.
   3 segmenty ukazují posun open → waiting → closed. */
.ticket-state {
    --ts-rgb: var(--accent-rgb);
    --ts-fill: 1;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 22px;
    padding: 0 8px 0 7px;
    border: 1px solid rgba(var(--ts-rgb), 0.28);
    border-radius: var(--radius-xs);
    background: rgba(var(--ts-rgb), 0.06);
    color: rgba(var(--ts-rgb), 0.95);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.04em;
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
}

.ticket-state::before {
    content: "";
    flex-shrink: 0;
    width: 14px;
    height: 6px;
    /* 3 segmenty po 4 px s mezerou 1 px; vyplněné podle --ts-fill */
    background:
        linear-gradient(to right, currentColor calc(var(--ts-fill) * 5px - 1px), transparent 0) 0 0 / 100% 100% no-repeat,
        rgba(var(--ts-rgb), 0.25);
    -webkit-mask: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 5px);
    mask: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 5px);
}

.ticket-state--open    { --ts-rgb: var(--accent-rgb); --ts-fill: 1; }
.ticket-state--waiting,
.ticket-state--awaiting_user { --ts-rgb: var(--warning-rgb); --ts-fill: 2; }
.ticket-state--closed  { --ts-rgb: 237, 238, 240; --ts-fill: 3; color: var(--text-2); }

/* Seznam ticketů (profil i admin) — řádek = odkaz/tlačítko
   <ul class="ticket-list"><li><a class="ticket-row" href="…">
     <span class="ticket-row__id">#128</span><span class="ticket-row__main"><span class="ticket-row__subject">…</span>
     <span class="ticket-row__meta">Billing · 2h ago</span></span><span class="ticket-state …">…</span></a></li></ul> */
.ticket-list {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    overflow: hidden;
}

.ticket-list > li + li {
    border-top: 1px solid var(--line);
}

.ticket-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    color: var(--text-2);
    text-decoration: none;
    transition: background-color var(--dur-fast) ease;
}

a.ticket-row:hover,
button.ticket-row:hover {
    background: var(--surface-2);
}

button.ticket-row {
    width: 100%;
    border: 0;
    background: none;
    text-align: left;
}

.ticket-row__id {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
}

.ticket-row__main {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ticket-row__subject {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
}

.ticket-row__meta {
    color: var(--text-3);
    font-size: var(--text-xs);
}

@media (max-width: 30rem) {
    .ticket-row {
        grid-template-columns: auto minmax(0, 1fr);
        row-gap: var(--space-2);
    }

    .ticket-row > .ticket-state {
        grid-column: 2;
        justify-self: start;
    }
}

.ticket-row.is-unread .ticket-row__subject::after {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: var(--space-2);
    border-radius: 50%;
    background: var(--accent);
    vertical-align: 0.15em;
}

/* --------------------------------------------------------------------------
   24. Chips (filtry jako odkazy nebo tlačítka) a segmented s počty
   <nav class="chips" aria-label="Filter"><a class="chip" href="?c=all" aria-current="page">All <span class="chip__count">24</span></a>…</nav>
   Tlačítka: <button class="chip" aria-pressed="true">
   -------------------------------------------------------------------------- */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 32px;
    padding: 0 var(--space-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-2);
    font-size: 0.8125rem;
    font-weight: 450;
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--dur) ease, background-color var(--dur) ease, border-color var(--dur) ease;
}

.chip:hover {
    border-color: var(--line-3);
    color: var(--text);
}

.chip[aria-current]:not([aria-current="false"]),
.chip[aria-pressed="true"] {
    border-color: var(--text-2);
    background: var(--surface-2);
    color: var(--text);
}

.chip__count {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.chip__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--chip-dot, var(--text-3));
}

/* počet v segmented controlu: <span>Open <span class="segmented__count">4</span></span> */
.segmented__count {
    margin-left: 6px;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   25. Stepper (2FA setup), OTP input, QR rámeček
   <ol class="stepper">
     <li class="stepper__step is-done"><span class="stepper__node">1</span><span class="stepper__label">Scan</span></li>
     <li class="stepper__step" aria-current="step"><span class="stepper__node">2</span><span class="stepper__label">Verify</span></li>
     <li class="stepper__step"><span class="stepper__node">3</span><span class="stepper__label">Backup codes</span></li>
   </ol>
   Hotový krok: .is-done (uzel ukáže fajfku; přidej <span class="visually-hidden">completed</span>).
   -------------------------------------------------------------------------- */
.stepper {
    display: flex;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: none;
}

.stepper__step {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1 1 0;
    min-width: 0;
    color: var(--text-3);
    font-size: var(--text-sm);
}

/* spojovací čára za uzlem */
.stepper__step:not(:last-child)::after {
    content: "";
    flex: 1 1 auto;
    min-width: var(--space-3);
    height: 1px;
    margin-left: var(--space-1);
    background: var(--line-2);
}

.stepper__step.is-done:not(:last-child)::after {
    background: var(--accent-line);
}

.stepper__node {
    position: relative;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border: 1px solid var(--line-2);
    border-radius: 50%;
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    transition: border-color var(--dur) ease, color var(--dur) ease, background-color var(--dur) ease;
}

.stepper__label {
    flex-shrink: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stepper__step[aria-current="step"] {
    color: var(--text);
    font-weight: 500;
}

.stepper__step[aria-current="step"] .stepper__node {
    border-color: var(--accent);
    color: var(--text);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

.stepper__step.is-done {
    color: var(--text-2);
}

.stepper__step.is-done .stepper__node {
    border-color: var(--accent-line);
    background: var(--accent-soft);
    color: transparent;
}

.stepper__step.is-done .stepper__node::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 12px;
    height: 12px;
    background: var(--accent);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 7.3 2.6 2.5L11 4.3'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 7.3 2.6 2.5L11 4.3'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* úzké displeje: popisky jen u aktuálního kroku */
@media (max-width: 30rem) {
    .stepper__step:not([aria-current="step"]) {
        flex: 0 1 auto;
    }

    .stepper__step:not([aria-current="step"]) .stepper__label {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* OTP — jedno skutečné pole (paste, autofill one-time-code, čtečky), main.js přidá vizuální buňky
   <div class="otp" data-otp>
     <input class="input input--mono otp__input" id="code" inputmode="numeric" autocomplete="one-time-code"
            pattern="[0-9]{6}" maxlength="6" aria-describedby="code-hint">
   </div>
   Událost 'otp:complete' {value} na .otp; data-otp-autosubmit = po 6. číslici odešle formulář. */
.otp {
    --otp-n: 6;
    --otp-cell: 48px;
    --otp-gap: 8px;
    position: relative;
    display: inline-block;
    max-width: 100%;
}

.otp__input {
    width: calc(var(--otp-n) * var(--otp-cell) + (var(--otp-n) - 1) * var(--otp-gap));
    max-width: 100%;
    height: 56px;
    font-size: 1.375rem;
    letter-spacing: 0.4em;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.otp__cells {
    display: none;
}

.otp.is-enhanced .otp__cells {
    display: grid;
    grid-template-columns: repeat(var(--otp-n), var(--otp-cell));
    gap: var(--otp-gap);
    pointer-events: none;
}

/* vylepšený režim: pole je průhledné a leží přes buňky (klik, focus, paste jdou do něj) */
.otp.is-enhanced .otp__input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    color: transparent;
    caret-color: transparent;
    letter-spacing: 0;
    -webkit-text-fill-color: transparent;
}

.otp.is-enhanced .otp__input::selection {
    background: transparent;
}

.otp__cell {
    position: relative;
    display: grid;
    place-items: center;
    height: 56px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-1);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 1.375rem;
    font-variant-numeric: tabular-nums;
    transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease, background-color var(--dur-fast) ease;
}

.otp__cell.is-filled {
    border-color: var(--line-3);
}

.otp.is-focused .otp__cell.is-active {
    border-color: var(--focus-line);
    background: var(--surface-2);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

/* blikající kurzor v aktivní prázdné buňce */
.otp.is-focused .otp__cell.is-active:not(.is-filled)::after {
    content: "";
    width: 1.5px;
    height: 22px;
    background: var(--accent);
    animation: otpCaret 1s steps(1) infinite;
}

@keyframes otpCaret {
    50% { opacity: 0; }
}

.otp.is-invalid .otp__cell,
.otp:has(.otp__input[aria-invalid="true"]) .otp__cell {
    border-color: rgba(var(--danger-rgb), 0.6);
}

.otp.is-invalid .otp__cells {
    animation: otpShake 0.4s var(--ease-out);
}

@keyframes otpShake {
    20%, 60% { translate: -4px 0; }
    40%, 80% { translate: 4px 0; }
}

.otp:has(.otp__input:disabled) {
    opacity: 0.55;
}

@media (max-width: 24rem) {
    .otp {
        --otp-cell: 40px;
        --otp-gap: 6px;
    }
}

/* QR rámeček pro TOTP: <figure class="qr"><img|svg …><figcaption>…</figcaption></figure>
   QR musí mít světlé pozadí kvůli čtečkám → bílá plocha uvnitř hairline rámu. */
.qr {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    margin: 0;
}

.qr__code {
    display: grid;
    place-items: center;
    width: 176px;
    height: 176px;
    padding: 12px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    background: #fff;
}

.qr__code > img,
.qr__code > svg {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
}

.qr figcaption {
    color: var(--text-3);
    font-size: var(--text-xs);
    text-align: center;
}

/* --------------------------------------------------------------------------
   26. Sessions list, connection card, referral card
   <ul class="sessions">
     <li class="session is-current">
       <span class="session__icon"><svg class="icon">…</svg></span>
       <div class="session__main"><p class="session__device">Chrome on Windows <span class="badge badge--success">This device</span></p>
         <p class="session__meta"><span class="mono">185.23.•••.12</span> · Active now</p></div>
       <div class="session__actions"><button class="btn btn--sm btn--ghost">Sign out</button></div></li>
   </ul>
   -------------------------------------------------------------------------- */
.sessions {
    margin: 0;
    padding: 0;
    list-style: none;
}

.session {
    display: grid;
    grid-template-columns: 36px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-4);
    padding-block: var(--space-4);
    border-bottom: 1px solid var(--line);
}

.session:first-child {
    padding-top: 0;
}

.session:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.session__icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    color: var(--text-2);
}

.session__icon .icon {
    width: 18px;
    height: 18px;
}

.session.is-current .session__icon {
    border-color: var(--accent-line);
    color: var(--accent);
}

.session__main {
    min-width: 0;
}

.session__device {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
}

.session__meta {
    margin-top: 2px;
    color: var(--text-3);
    font-size: var(--text-xs);
    overflow-wrap: anywhere;
}

.session__meta .mono {
    font-size: 11px;
}

@media (max-width: 30rem) {
    .session {
        grid-template-columns: 36px minmax(0, 1fr);
    }

    .session__actions {
        grid-column: 2;
    }
}

/* Connection card — propojení účtu (Discord)
   <div class="connection is-linked">
     <span class="connection__logo"><svg class="icon">…</svg></span>
     <div class="connection__body"><p class="connection__name">Discord <span class="badge badge--success">…</span></p>
       <p class="connection__meta">…</p></div>
     <div class="connection__account"><span class="connection__avatar"><img alt="" …><span aria-hidden="true">P</span></span>…</div>
     <div class="connection__actions">…</div></div> */
.connection {
    display: grid;
    min-width: 0;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
}

.connection__logo {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-2);
}

.connection__logo .icon {
    width: 20px;
    height: 20px;
}

.connection.is-linked .connection__logo {
    color: var(--text);
}

.connection__body {
    min-width: 0;
}

.connection__name {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 600;
}

.connection__meta {
    margin-top: 2px;
    color: var(--text-3);
    font-size: var(--text-xs);
    overflow-wrap: anywhere;
}

.connection__account {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--text);
    font-size: var(--text-sm);
}

/* avatar z Discordu leží přes iniciálu — když se obrázek nenačte (CSP, 404), zůstane iniciála */
.connection__avatar {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border: 1px solid var(--line-2);
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    overflow: hidden;
}

.connection__avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.connection__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
}

.connection__actions form {
    display: flex;
    margin: 0;
}

@media (max-width: 40rem) {
    .connection {
        grid-template-columns: 40px minmax(0, 1fr);
        padding: var(--space-4);
    }

    .connection__actions {
        grid-column: 1 / -1;
        justify-content: flex-start;
    }
}

/* Referral card
   <section class="referral">
     <div class="referral__share"><p class="referral__label">Your invite link</p><div class="keycode">…</div></div>
     <dl class="referral__stats"><div class="referral__stat"><dt>Invited</dt><dd>4</dd></div>…</dl>
     <div class="referral__cap"><div class="progress-meta">…</div><div class="progress progress--ticks" style="--ticks:5; --value:.4">…</div></div>
     <p class="referral__rule">…</p></section> */
.referral {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    min-width: 0;
    gap: var(--space-5);
    padding: clamp(var(--space-5), 2.5vw, var(--space-6));
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
}

.referral__label {
    margin-bottom: var(--space-2);
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
}

.referral__code {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-2);
    color: var(--text-3);
    font-size: var(--text-xs);
}

.referral__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    margin: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--line);
    overflow: hidden;
}

.referral__stat {
    display: flex;
    flex-direction: column-reverse;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-1);
}

.referral__stat dt {
    color: var(--text-3);
    font-size: var(--text-xs);
}

.referral__stat dd {
    margin: 0;
    color: var(--text);
    font-size: var(--text-xl);
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: -0.03em;
}

.referral__stat dd .stat__unit {
    font-size: 0.55em;
}

.referral__rule {
    color: var(--text-3);
    font-size: var(--text-xs);
    line-height: 1.6;
}

@media (max-width: 24rem) {
    .referral__stats {
        grid-template-columns: 1fr;
    }
}

/* --------------------------------------------------------------------------
   27. Upload dropzone (buildy loaderu)
   <div class="dropzone" data-dropzone data-max-mb="200">
     <input class="dropzone__input" type="file" id="build" accept=".exe,.zip" aria-describedby="build-hint">
     <label class="dropzone__label" for="build">
       <span class="dropzone__icon"><svg class="icon">…</svg></span>
       <span class="dropzone__title">Drop a build here or <span class="link">browse</span></span>
       <span class="dropzone__hint" id="build-hint">.exe or .zip · up to 200 MB</span></label>
     <div class="dropzone__file" hidden>…vyplní main.js…</div>
   </div>
   Stavy: .is-dragover, .has-file, .is-uploading, .is-invalid. Události: dropzone:change {file}, dropzone:clear.
   -------------------------------------------------------------------------- */
.dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.dropzone__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
    clip-path: inset(50%);
}

.dropzone__label {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-7) var(--space-5);
    border: 1px dashed var(--line-3);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
    color: var(--text-2);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--dur) ease, background-color var(--dur) ease;
}

.dropzone__label:hover {
    border-color: var(--text-3);
    background: var(--surface-2);
}

.dropzone__input:focus-visible + .dropzone__label {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.dropzone.is-dragover .dropzone__label {
    border-style: solid;
    border-color: var(--accent);
    background: var(--accent-soft);
}

.dropzone.is-invalid .dropzone__label {
    border-color: rgba(var(--danger-rgb), 0.6);
}

.dropzone__icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-1);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    color: var(--text-2);
    transition: translate var(--dur-slow) var(--ease-out);
}

.dropzone.is-dragover .dropzone__icon {
    translate: 0 -3px;
    color: var(--accent);
}

.dropzone__icon .icon {
    width: 20px;
    height: 20px;
}

.dropzone__title {
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
}

.dropzone__hint {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
}

.dropzone.has-file .dropzone__label {
    padding-block: var(--space-4);
}

.dropzone.has-file .dropzone__icon,
.dropzone.has-file .dropzone__hint {
    display: none;
}

.dropzone__file {
    display: grid;
    grid-template-columns: 36px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    background: var(--surface-1);
}

.dropzone__file[hidden] {
    display: none;
}

.dropzone__file-icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text-2);
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
}

.dropzone__file-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 500;
}

.dropzone__file-meta {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.dropzone__file .progress {
    grid-column: 1 / -1;
}

.dropzone__error {
    color: var(--danger);
    font-size: 0.8125rem;
    font-weight: 500;
}

.dropzone__error:empty {
    display: none;
}

/* --------------------------------------------------------------------------
   28. Secret — klíč/kódy zobrazené JEN JEDNOU (generate_keys, záložní kódy 2FA)
   <section class="secret" aria-labelledby="s-t">
     <header class="secret__head"><h3 class="secret__title" id="s-t">10 new keys</h3><span class="badge badge--warning">Shown once</span></header>
     <div class="alert alert--warning"><span class="alert__text">…</span></div>
     <ol class="secret__list" id="s-list"><li class="keycode">…</li></ol>      (.secret__list--grid = záložní kódy ve 2 sloupcích)
     <div class="secret__actions"><button class="btn" data-copy-target="#s-list">Copy all</button>…</div>
     <label class="check secret__ack"><input type="checkbox" data-secret-ack> I saved them somewhere safe</label>
     <button class="btn btn--primary" data-secret-done disabled>Done</button>
   </section>
   main.js: data-secret-ack odemkne [data-secret-done] ve stejném .secret;
            .secret.is-masked rozmaže hodnoty, dokud se neklikne na [data-secret-toggle].
   -------------------------------------------------------------------------- */
.secret {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5);
    border: 1px solid rgba(var(--warning-rgb), 0.3);
    border-radius: var(--radius-lg);
    background: var(--surface-1);
}

.secret__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-3);
}

.secret__title {
    font-size: var(--text-base);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.secret__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.secret__list--grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(10.5rem, 100%), 1fr));
}

.secret__list--grid > li {
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.875rem;
    letter-spacing: 0.06em;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.secret .keycode__value,
.secret__list--grid > li {
    transition: filter var(--dur) ease;
}

.secret.is-masked .keycode__value,
.secret.is-masked .secret__list--grid > li {
    filter: blur(6px);
    user-select: none;
}

.secret__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.secret__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-top: var(--space-4);
    border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   29. Prose (bezpečně vyrenderované HTML: changelog body_html, legal) a release
   <div class="prose">…p, ul, ol, h2–h4, code, pre, a, strong, em, blockquote, hr…</div>
   -------------------------------------------------------------------------- */
.prose {
    max-width: 68ch;
    color: var(--text-2);
    font-size: 0.9375rem;
    line-height: 1.7;
}

.prose > * + * {
    margin-top: var(--space-4);
}

.prose h2,
.prose h3,
.prose h4 {
    color: var(--text);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
    line-height: 1.25;
}

.prose h2 {
    margin-top: var(--space-7);
    font-size: var(--text-xl);
    scroll-margin-top: calc(var(--header-h) + var(--space-5));
}

.prose h3 {
    margin-top: var(--space-6);
    font-size: var(--text-lg);
}

.prose h4 {
    margin-top: var(--space-5);
    font-size: var(--text-base);
}

.prose > :first-child {
    margin-top: 0;
}

.prose ul,
.prose ol {
    padding-left: 1.25rem;
}

.prose li + li {
    margin-top: var(--space-2);
}

.prose li::marker {
    color: var(--text-3);
}

.prose a {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--line-3);
    text-underline-offset: 3px;
    transition: text-decoration-color var(--dur) ease;
}

.prose a:hover {
    text-decoration-color: var(--text);
}

.prose strong {
    color: var(--text);
    font-weight: 600;
}

.prose blockquote {
    padding-left: var(--space-4);
    border-left: 2px solid var(--line-2);
    color: var(--text-3);
}

.prose hr {
    border: 0;
    border-top: 1px solid var(--line);
}

.prose pre {
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface-1);
    font-size: 0.8125rem;
    overflow-x: auto;
}

/* Release (changelog.php) — verze vlevo, záznamy vpravo
   <article class="release" id="v4-1-0">
     <header class="release__meta"><h2 class="release__version">v4.1.0</h2><time class="release__date">…</time></header>
     <div class="release__entries"><section class="release__entry"><p class="release__cat"><span class="badge …">Feature</span></p>
       <h3 class="release__title">…</h3><div class="prose">…</div></section>…</div></article> */
.release {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    padding-block: var(--space-7);
    border-top: 1px solid var(--line);
    scroll-margin-top: calc(var(--header-h) + var(--space-4));
}

.release__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
}

.release__version {
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--text-lg);
    font-weight: 500;
    letter-spacing: 0;
}

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

.release__version a:hover {
    text-decoration: underline;
    text-decoration-color: var(--line-3);
    text-underline-offset: 4px;
}

.release__date {
    color: var(--text-3);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
}

.release__entries {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    min-width: 0;
}

.release__entry {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.release__entry + .release__entry {
    padding-top: var(--space-6);
    border-top: 1px dashed var(--line);
}

.release__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
}

.release__title {
    color: var(--text);
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: var(--tracking-snug);
    line-height: 1.3;
}

@media (min-width: 60rem) {
    .release {
        grid-template-columns: 13rem minmax(0, 1fr);
        gap: var(--space-7);
    }

    .release__meta {
        position: sticky;
        top: calc(var(--header-h) + var(--space-5));
        flex-direction: column;
        align-self: start;
        gap: var(--space-1);
    }
}

/* štítky kategorií changelogu: feature = akcent, fix = info, detection = warning */
.badge--feature   { --badge-rgb: var(--accent-rgb); }
.badge--fix       { --badge-rgb: var(--info-rgb); }
.badge--detection { --badge-rgb: var(--warning-rgb); }

/* v4: reduced motion — vypnout průběžné animace nových komponent */
@media (prefers-reduced-motion: reduce) {
    .otp.is-focused .otp__cell.is-active:not(.is-filled)::after,
    .cmdk__spinner {
        animation: none;
    }
}
