/* ==========================================================================
   Components: the small, reusable pieces the whole product is built from.
   Every one of them earns its place by doing a job the plain element
   cannot. Nothing here exists for decoration.
   ========================================================================== */

/* --- Buttons -------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    height: var(--control-height);
    padding-inline: var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    /* Not 1. A line box exactly one em tall clips the tail of a Persian
       descender, and a button is where that shows first. */
    line-height: var(--leading-tight);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
}

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
}

.btn svg {
    width: 16px;
    height: 16px;
    flex: none;
}

.btn-primary {
    background: var(--color-primary);
    color: var(--color-on-primary);
    border-color: var(--color-primary);
}

.btn-primary:hover:not(:disabled) {
    background: var(--color-primary-hover);
    border-color: var(--color-primary-hover);
}

.btn-primary:active:not(:disabled) {
    background: var(--color-primary-active);
}

.btn-secondary {
    background: var(--color-surface);
    color: var(--color-text-primary);
    border-color: var(--color-border-strong);
}

.btn-secondary:hover:not(:disabled) {
    background: var(--color-surface-secondary);
}

.btn-ghost {
    color: var(--color-text-secondary);
}

.btn-ghost:hover:not(:disabled) {
    background: var(--color-surface-secondary);
    color: var(--color-text-primary);
}

.btn-danger {
    background: var(--color-danger);
    color: #fff;
    border-color: var(--color-danger);
}

.btn-danger:hover:not(:disabled) {
    background: var(--color-danger-hover);
    border-color: var(--color-danger-hover);
}

.btn-danger-ghost {
    color: var(--color-danger);
}

.btn-danger-ghost:hover:not(:disabled) {
    background: var(--color-danger-soft);
}

.btn-sm {
    height: var(--control-height-sm);
    padding-inline: var(--space-2);
    font-size: var(--text-xs);
}

.btn-lg {
    height: var(--control-height-lg);
    padding-inline: var(--space-4);
    font-size: var(--text-base);
}

.btn-icon {
    width: var(--control-height);
    padding-inline: 0;
}

.btn-icon.btn-sm {
    width: var(--control-height-sm);
}

.btn-block {
    width: 100%;
}

/* Loading state: the label stays in place so the button never resizes. */
.btn.is-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.btn.is-loading::after {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-radius: 50%;
    border-block-start-color: transparent;
    animation: spin 620ms linear infinite;
    color: var(--color-on-primary);
}

.btn-secondary.is-loading::after,
.btn-ghost.is-loading::after {
    color: var(--color-text-secondary);
}

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

/* --- Form controls -------------------------------------------------------- */
.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.field-label {
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    color: var(--color-text-secondary);
}

.field-label .required {
    color: var(--color-danger);
    margin-inline-start: 2px;
}

.field-help {
    font-size: var(--text-xs);
    color: var(--color-text-tertiary);
}

.field-error {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-xs);
    color: var(--color-danger);
}

.input,
.select,
.textarea {
    width: 100%;
    min-height: var(--control-height);
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    color: var(--color-text-primary);
    font-size: var(--text-sm);
    transition: border-color var(--duration-fast) var(--ease-out),
                box-shadow var(--duration-fast) var(--ease-out);
}

.textarea {
    padding: var(--space-2) var(--space-3);
    min-height: 76px;
    line-height: var(--leading-normal);
    resize: vertical;
}

.input::placeholder,
.textarea::placeholder {
    color: var(--color-text-tertiary);
}

.input:hover:not(:disabled),
.select:hover:not(:disabled),
.textarea:hover:not(:disabled) {
    border-color: var(--color-text-tertiary);
}

.input:focus,
.select:focus,
.textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.input:disabled,
.select:disabled,
.textarea:disabled {
    background: var(--color-surface-secondary);
    color: var(--color-text-tertiary);
    cursor: not-allowed;
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] {
    border-color: var(--color-danger);
}

.input[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 3px var(--color-danger-soft);
}

/* The chevron is a background image, which cannot take currentColor, so
   the whole image is a token and the dark palette swaps it for one drawn
   in a lighter grey. A single baked colour sits almost invisibly on one of
   the two themes, and it is always the dark one that loses. */
.select {
    appearance: none;
    padding-inline-end: var(--space-6);
    background-image: var(--select-chevron);
    background-repeat: no-repeat;
    background-position: right var(--space-3) center;
    background-size: 16px;
    cursor: pointer;
}

[dir="rtl"] .select {
    background-position: left var(--space-3) center;
}

/* --- A heading inside a long form -------------------------------------------
   A rule with a word on it. Enough to break twenty controls into groups
   somebody can hold in their head, without pretending to be a panel. */
.form-section {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-block-start: var(--space-2);
}

.form-section::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--color-border);
}

.form-section-title {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--color-text-tertiary);
}

/* Persian has no upper case, so the transform does nothing but the extra
   letter spacing pulls the joined script apart. Both are dropped. */
[dir="rtl"] .form-section-title {
    text-transform: none;
    letter-spacing: 0;
}

/* --- Meta tag pills ---------------------------------------------------------
   A prompt author is doing two things with the same list: deciding which
   pieces of context an assistant may use, and dropping their names into the
   prompt. One pill does both. The left half is the decision and shows its
   state by filling in; the right half is the shortcut and stays quiet until
   the pointer is over it. */
.meta-tag {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    overflow: hidden;
    max-width: 100%;
}

.meta-tag.is-on {
    border-color: var(--color-primary-border);
    background: var(--color-primary-soft);
}

.meta-tag-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    padding-inline: var(--space-3) var(--space-2);
    padding-block: 5px;
    cursor: pointer;
    font-size: var(--text-xs);
}

.meta-tag-toggle input {
    width: 14px;
    height: 14px;
    flex: none;
    margin: 0;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.meta-tag-name {
    color: var(--color-text-primary);
    white-space: nowrap;
}

.meta-tag-slug {
    color: var(--color-text-tertiary);
    font-size: var(--text-2xs);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.meta-tag-insert {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    flex: none;
    border: 0;
    border-inline-start: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text-tertiary);
    cursor: pointer;
}

.meta-tag-insert:hover {
    background: var(--color-surface-secondary);
    color: var(--color-text-primary);
}

.meta-tag-insert svg {
    width: 14px;
    height: 14px;
}

@media (pointer: coarse) {
    .meta-tag-insert { width: 40px; }
    .meta-tag-toggle { padding-block: 8px; }
}

/* --- A group of fields behind one switch -----------------------------------
   For settings most people never touch. The switch stays visible so the
   capability is discoverable; the boxes stay out of the way until somebody
   wants them. The frame appears only once the group is open, so a closed
   group reads as one more line in the form rather than an empty panel. */
.field-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.field-group-switch {
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}

.field-group > .field-help {
    margin-block-start: -4px;
    margin-inline-start: 46px;
}

.field-group-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-inline-start: 46px;
    padding-inline-start: var(--space-3);
    border-inline-start: 2px solid var(--color-border);
}

@media (max-width: 640px) {
    .field-group > .field-help,
    .field-group-body {
        margin-inline-start: 0;
    }
}

.input-group {
    position: relative;
    display: flex;
    align-items: center;
}

.input-group .input {
    padding-inline-start: var(--space-6);
}

.input-group .input-icon {
    position: absolute;
    inset-inline-start: var(--space-2);
    display: flex;
    color: var(--color-text-tertiary);
    pointer-events: none;
}

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

.checkbox,
.radio {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--text-sm);
    cursor: pointer;
}

.checkbox input,
.radio input {
    width: 16px;
    height: 16px;
    margin: 2px 0 0;
    accent-color: var(--color-primary);
    flex: none;
    cursor: pointer;
}

.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    cursor: pointer;
    font-size: var(--text-sm);
}

.switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.switch-track {
    width: 34px;
    height: 20px;
    flex: none;
    background: var(--color-border-strong);
    border-radius: var(--radius-full);
    transition: background-color var(--duration-base) var(--ease-out);
    position: relative;
}

.switch-track::after {
    content: "";
    position: absolute;
    inset-block-start: 2px;
    inset-inline-start: 2px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    box-shadow: var(--shadow-sm);
    transition: transform var(--duration-base) var(--ease-out);
}

.switch input:checked + .switch-track {
    background: var(--color-primary);
}

.switch input:checked + .switch-track::after {
    transform: translateX(14px);
}

[dir="rtl"] .switch input:checked + .switch-track::after {
    transform: translateX(-14px);
}

.switch input:focus-visible + .switch-track {
    outline: 2px solid var(--color-border-focus);
    outline-offset: 2px;
}

/* --- Cards and panels ------------------------------------------------------
   A panel is used where content genuinely needs separation from the page,
   not as a default wrapper for everything. */
.panel {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-block-end: 1px solid var(--color-border);
}

.panel-title {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
}

.panel-body {
    padding: var(--space-4);
}

.panel-body-flush {
    padding: 0;
}

/* --- Badges --------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    height: 20px;
    padding-inline: var(--space-2);
    border-radius: var(--radius-xs);
    background: var(--color-surface-secondary);
    border: 1px solid var(--color-border);
    color: var(--color-text-secondary);
    font-size: var(--text-2xs);
    font-weight: var(--weight-medium);
    white-space: nowrap;
}

.badge-success { background: var(--color-success-soft); border-color: var(--color-success-border); color: var(--color-success); }
.badge-warning { background: var(--color-warning-soft); border-color: var(--color-warning-border); color: var(--color-warning); }
.badge-danger  { background: var(--color-danger-soft);  border-color: var(--color-danger-border);  color: var(--color-danger); }
.badge-info    { background: var(--color-info-soft);    border-color: var(--color-info-border);    color: var(--color-info); }
.badge-primary { background: var(--color-primary-soft); border-color: var(--color-primary-border); color: var(--color-primary); }
/* For a thing that is switched off: present, but not asking for attention. */
.badge-muted   { background: transparent; border-style: dashed; color: var(--color-text-tertiary); }

/* A block of text the machine wrote or will read: a resolved prompt, a
   payload, a stack of settings. Monospace because alignment carries
   meaning here, and scrollable because it is never short. */
.code-block {
    margin: 0;
    padding: var(--space-3);
    max-block-size: 320px;
    overflow: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface-secondary);
    color: var(--color-text-secondary);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-xs);
    line-height: 1.7;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* A status dot carries meaning alongside a text label, never alone. */
.status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 20px;
    padding-inline: var(--space-2);
    border-radius: var(--radius-xs);
    background: var(--color-surface-secondary);
    border: 1px solid var(--color-border);
    font-size: var(--text-2xs);
    font-weight: var(--weight-medium);
    color: var(--color-text-secondary);
    max-width: 160px;
}

.tag-chip .tag-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex: none;
}

.tag-chip button {
    border: 0;
    background: none;
    padding: 0;
    margin-inline-start: 2px;
    cursor: pointer;
    color: var(--color-text-tertiary);
    display: inline-flex;
}

.tag-chip button:hover { color: var(--color-danger); }
.tag-chip button svg { width: 11px; height: 11px; }

.tag-slate  .tag-dot, .dot-slate  { background: var(--tag-slate); }
.tag-blue   .tag-dot, .dot-blue   { background: var(--tag-blue); }
.tag-green  .tag-dot, .dot-green  { background: var(--tag-green); }
.tag-amber  .tag-dot, .dot-amber  { background: var(--tag-amber); }
.tag-red    .tag-dot, .dot-red    { background: var(--tag-red); }
.tag-violet .tag-dot, .dot-violet { background: var(--tag-violet); }
.tag-teal   .tag-dot, .dot-teal   { background: var(--tag-teal); }
.tag-pink   .tag-dot, .dot-pink   { background: var(--tag-pink); }

/* --- Avatars -------------------------------------------------------------- */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex: none;
    border-radius: var(--radius-full);
    background: var(--color-surface-tertiary);
    color: var(--color-text-secondary);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.01em;
    overflow: hidden;
    user-select: none;
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-sm { width: 24px; height: 24px; font-size: var(--text-2xs); }
.avatar-lg { width: 44px; height: 44px; font-size: var(--text-base); }
.avatar-xl { width: 60px; height: 60px; font-size: var(--text-lg); }

/* Channel identity: an outlined glyph plus a colour, never colour alone. */
.channel-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    flex: none;
    border-radius: var(--radius-xs);
    background: var(--color-surface-secondary);
    color: var(--color-text-secondary);
}

.channel-mark svg { width: 12px; height: 12px; }

.channel-telegram { color: var(--channel-telegram); }
.channel-whatsapp { color: var(--channel-whatsapp); }
.channel-instagram { color: var(--channel-instagram); }
.channel-bale { color: var(--channel-bale); }
.channel-rubika { color: var(--channel-rubika); }
.channel-eitaa { color: var(--channel-eitaa); }
.channel-sms { color: var(--channel-sms); }
.channel-email { color: var(--channel-email); }
.channel-livechat { color: var(--channel-livechat); }

/* --- Tables --------------------------------------------------------------- */
.table-wrap {
    width: 100%;
    overflow-x: auto;
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.table th {
    padding: var(--space-2) var(--space-4);
    text-align: start;
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    color: var(--color-text-tertiary);
    background: var(--color-surface-secondary);
    border-block-end: 1px solid var(--color-border);
    white-space: nowrap;
    position: sticky;
    inset-block-start: 0;
    z-index: 1;
}

.table td {
    padding: var(--space-3) var(--space-4);
    border-block-end: 1px solid var(--color-border);
    vertical-align: middle;
}

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

.table tbody tr:hover td {
    background: var(--color-surface-secondary);
}

.table .cell-actions {
    text-align: end;
    white-space: nowrap;
}

.table .cell-primary {
    font-weight: var(--weight-medium);
    color: var(--color-text-primary);
}

/* --- Dropdown menus ------------------------------------------------------- */
.dropdown {
    position: relative;
}

.menu {
    position: absolute;
    inset-inline-end: 0;
    inset-block-start: calc(100% + 4px);
    min-width: 200px;
    max-height: 340px;
    overflow-y: auto;
    padding: var(--space-1);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-dropdown);
    animation: menu-in var(--duration-fast) var(--ease-out);
}

.menu-start { inset-inline-end: auto; inset-inline-start: 0; }
.menu-up { inset-block-start: auto; inset-block-end: calc(100% + 4px); }

@keyframes menu-in {
    from { opacity: 0; transform: translateY(-3px); }
    to { opacity: 1; transform: translateY(0); }
}

.menu-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-2);
    border: 0;
    border-radius: var(--radius-xs);
    background: none;
    color: var(--color-text-primary);
    font-size: var(--text-sm);
    text-align: start;
    cursor: pointer;
}

.menu-item:hover,
.menu-item:focus-visible {
    background: var(--color-surface-secondary);
    text-decoration: none;
}

.menu-item[aria-selected="true"] {
    background: var(--color-primary-soft);
    color: var(--color-primary);
}

.menu-item svg { width: 15px; height: 15px; flex: none; color: var(--color-text-tertiary); }
.menu-item.is-danger { color: var(--color-danger); }
.menu-item.is-danger svg { color: var(--color-danger); }
.menu-item:disabled { opacity: 0.5; cursor: not-allowed; }

.menu-label {
    padding: var(--space-2) var(--space-2) var(--space-1);
    font-size: var(--text-2xs);
    font-weight: var(--weight-semibold);
    color: var(--color-text-tertiary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.menu-separator {
    height: 1px;
    margin: var(--space-1) 0;
    background: var(--color-border);
}

/* --- Modal ---------------------------------------------------------------- */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: var(--color-overlay);
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    animation: fade-in var(--duration-base) var(--ease-out);
}

@keyframes fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.modal {
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - var(--space-7));
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    animation: modal-in var(--duration-base) var(--ease-out);
}

.modal-lg { max-width: 720px; }
.modal-sm { max-width: 400px; }

@keyframes modal-in {
    from { opacity: 0; transform: translateY(8px) scale(0.99); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

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

.modal-header h2 { font-size: var(--text-md); }
.modal-header p { margin-block-start: 2px; font-size: var(--text-xs); color: var(--color-text-secondary); }

.modal-body {
    padding: var(--space-2) var(--space-5) var(--space-4);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5) var(--space-4);
    border-block-start: 1px solid var(--color-border);
}

.modal-footer .footer-start {
    margin-inline-end: auto;
}

/* --------------------------------------------------------------------------
   A dialog on a phone.

   Centring a card in a viewport barely taller than the card itself puts the
   actions somewhere in the middle of the screen and the top of the form off
   the top edge. So on a small screen the dialog becomes a sheet: anchored to
   the bottom, reaching for the full height it needs, with its title and its
   actions pinned where a thumb can find them.

   The height uses dvh where it exists. On a phone, 100vh is the height the
   viewport would have if the address bar were hidden, which it usually is
   not, so a vh-sized sheet hides its own footer behind the browser chrome.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
    .modal-backdrop {
        padding: 0;
        align-items: flex-end;
    }

    .modal,
    .modal-lg,
    .modal-sm {
        max-width: 100%;
        max-height: 92vh;
        border-start-start-radius: var(--radius-lg);
        border-start-end-radius: var(--radius-lg);
        border-end-start-radius: 0;
        border-end-end-radius: 0;
        animation: sheet-in var(--duration-base) var(--ease-out);
    }

    @supports (height: 100dvh) {
        .modal,
        .modal-lg,
        .modal-sm {
            max-height: 92dvh;
        }
    }

    .modal-header {
        position: sticky;
        inset-block-start: 0;
        z-index: 1;
        background: var(--color-surface);
        padding-block-start: var(--space-4);
    }

    /* A grab handle above the title: it tells the reader this panel came up
       from the bottom and can go back down. */
    .modal-header::before {
        content: "";
        position: absolute;
        inset-block-start: 6px;
        inset-inline-start: 50%;
        width: 36px;
        height: 4px;
        margin-inline-start: -18px;
        border-radius: var(--radius-full);
        background: var(--color-border-strong);
    }

    .modal-footer {
        position: sticky;
        inset-block-end: 0;
        background: var(--color-surface);
        padding-block-end: max(var(--space-4), env(safe-area-inset-bottom));
        flex-wrap: wrap;
    }

    /* Two buttons side by side on a narrow screen leaves each too small to
       hit; stacked and full width, neither can be missed. */
    .modal-footer .btn {
        flex: 1 1 100%;
        height: var(--control-height-lg);
    }

    .modal-footer .footer-start {
        order: 3;
        margin-inline-end: 0;
    }
}

@keyframes sheet-in {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   Touch.

   A 28px button is comfortable under a mouse and awkward under a thumb.
   Rather than growing every control on every screen, the floor is raised
   only where the pointer is actually coarse, which is the device that has
   the problem.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
    .btn,
    .input,
    .select,
    .textarea {
        min-height: 40px;
    }

    .btn-sm {
        height: auto;
        min-height: 36px;
        padding-inline: var(--space-3);
    }

    .btn-icon,
    .btn-icon.btn-sm {
        width: 40px;
    }

    .checkbox input,
    .radio input {
        width: 20px;
        height: 20px;
    }
}

/* --- Drawer (mobile and contextual panels) -------------------------------- */
.drawer-backdrop {
    position: fixed;
    inset: 0;
    background: var(--color-overlay);
    z-index: var(--z-drawer);
    animation: fade-in var(--duration-base) var(--ease-out);
}

.drawer {
    position: fixed;
    inset-block: 0;
    inset-inline-end: 0;
    width: min(380px, 92vw);
    background: var(--color-surface);
    border-inline-start: 1px solid var(--color-border);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-drawer);
    display: flex;
    flex-direction: column;
    animation: drawer-in var(--duration-slow) var(--ease-out);
}

@keyframes drawer-in {
    from { transform: translateX(12px); opacity: 0.4; }
    to { transform: translateX(0); opacity: 1; }
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    height: var(--topbar-height);
    padding-inline: var(--space-4);
    border-block-end: 1px solid var(--color-border);
    flex: none;
}

.drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-4);
}

/* --- Tabs ----------------------------------------------------------------- */
.tabs {
    display: flex;
    gap: var(--space-1);
    border-block-end: 1px solid var(--color-border);
    overflow-x: auto;
    scrollbar-width: none;
}

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

.tab {
    position: relative;
    padding: var(--space-2) var(--space-3);
    border: 0;
    background: none;
    color: var(--color-text-secondary);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
    white-space: nowrap;
}

.tab:hover { color: var(--color-text-primary); }

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

.tab[aria-selected="true"]::after {
    content: "";
    position: absolute;
    inset-inline: var(--space-2);
    inset-block-end: -1px;
    height: 2px;
    background: var(--color-primary);
    border-radius: 2px 2px 0 0;
}

/* --- Segmented control ---------------------------------------------------- */
.segmented {
    display: inline-flex;
    padding: 2px;
    background: var(--color-surface-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}

.segmented button {
    padding: 4px var(--space-3);
    border: 0;
    border-radius: var(--radius-xs);
    background: none;
    color: var(--color-text-secondary);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    cursor: pointer;
}

.segmented button[aria-pressed="true"] {
    background: var(--color-surface);
    color: var(--color-text-primary);
    box-shadow: var(--shadow-sm);
}

/* --- Tooltip -------------------------------------------------------------- */
.tooltip-host { position: relative; }

.tooltip-host::after {
    content: attr(data-tooltip);
    position: absolute;
    inset-block-end: calc(100% + 6px);
    inset-inline-start: 50%;
    transform: translateX(-50%) translateY(2px);
    padding: 4px var(--space-2);
    background: var(--color-surface-inverse);
    color: var(--color-text-inverse);
    font-size: var(--text-2xs);
    font-weight: var(--weight-medium);
    white-space: nowrap;
    border-radius: var(--radius-xs);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
    z-index: var(--z-dropdown);
}

.tooltip-host:hover::after,
.tooltip-host:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* --- Toasts --------------------------------------------------------------- */
.toast-stack {
    position: fixed;
    inset-block-end: var(--space-4);
    inset-inline-end: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    z-index: var(--z-toast);
    pointer-events: none;
    max-width: min(400px, calc(100vw - var(--space-6)));
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-inline-start: 3px solid var(--color-text-tertiary);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    pointer-events: auto;
    animation: toast-in var(--duration-slow) var(--ease-out);
}

.toast.is-leaving {
    animation: toast-out var(--duration-base) var(--ease-in-out) forwards;
}

.toast-success { border-inline-start-color: var(--color-success); }
.toast-error { border-inline-start-color: var(--color-danger); }
.toast-warning { border-inline-start-color: var(--color-warning); }
.toast-info { border-inline-start-color: var(--color-info); }

.toast-icon { flex: none; margin-block-start: 1px; }
.toast-icon svg { width: 16px; height: 16px; }
.toast-success .toast-icon { color: var(--color-success); }
.toast-error .toast-icon { color: var(--color-danger); }
.toast-warning .toast-icon { color: var(--color-warning); }
.toast-info .toast-icon { color: var(--color-info); }

.toast-content { flex: 1; min-width: 0; }
.toast-title { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.toast-message { font-size: var(--text-xs); color: var(--color-text-secondary); margin-block-start: 2px; }
.toast-action {
    margin-block-start: var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    color: var(--color-primary);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.toast-close {
    border: 0;
    background: none;
    padding: 2px;
    cursor: pointer;
    color: var(--color-text-tertiary);
    display: flex;
}

.toast-close svg { width: 14px; height: 14px; }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes toast-out {
    to { opacity: 0; transform: translateY(6px); }
}

/* --- Empty and loading states --------------------------------------------- */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-7) var(--space-4);
    text-align: center;
    color: var(--color-text-secondary);
}

.empty-state .empty-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-block-end: var(--space-1);
    border-radius: var(--radius-md);
    background: var(--color-surface-secondary);
    color: var(--color-text-tertiary);
}

.empty-state .empty-mark svg { width: 20px; height: 20px; }
.empty-state h3 { font-size: var(--text-sm); font-weight: var(--weight-semibold); }
.empty-state p { font-size: var(--text-xs); max-width: 42ch; }
.empty-state .btn { margin-block-start: var(--space-2); }

.skeleton {
    background: linear-gradient(
        90deg,
        var(--color-surface-secondary) 25%,
        var(--color-surface-tertiary) 37%,
        var(--color-surface-secondary) 63%
    );
    background-size: 400% 100%;
    animation: shimmer 1.3s ease-in-out infinite;
    border-radius: var(--radius-xs);
}

@keyframes shimmer {
    from { background-position: 100% 50%; }
    to { background-position: 0 50%; }
}

.skeleton-line { height: 10px; }
.skeleton-line + .skeleton-line { margin-block-start: var(--space-2); }
.skeleton-circle { border-radius: 50%; }

.spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--color-border-strong);
    border-block-start-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 620ms linear infinite;
}

/* --- Inline notice -------------------------------------------------------- */
.notice {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface-secondary);
    font-size: var(--text-xs);
    color: var(--color-text-secondary);
}

.notice svg { width: 15px; height: 15px; flex: none; margin-block-start: 1px; }
.notice-info { background: var(--color-info-soft); border-color: var(--color-info-border); color: var(--color-info); }
.notice-warning { background: var(--color-warning-soft); border-color: var(--color-warning-border); color: var(--color-warning); }
.notice-danger { background: var(--color-danger-soft); border-color: var(--color-danger-border); color: var(--color-danger); }
.notice-success { background: var(--color-success-soft); border-color: var(--color-success-border); color: var(--color-success); }

/* --- Key-value list ------------------------------------------------------- */
.kv {
    display: grid;
    grid-template-columns: minmax(84px, 34%) 1fr;
    gap: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
}

.kv dt { color: var(--color-text-tertiary); font-size: var(--text-xs); }
.kv dd { margin: 0; color: var(--color-text-primary); overflow-wrap: anywhere; }

/* --- Copy field ----------------------------------------------------------- */
.copy-field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    background: var(--color-surface-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    overflow-wrap: anywhere;
}

.copy-field code { flex: 1; min-width: 0; color: var(--color-text-secondary); }

/* A count that rides on top of an icon button (notifications). */
.btn-badge { position: relative; overflow: visible; }

.btn-badge .unread-pill {
    position: absolute;
    inset-block-start: -4px;
    inset-inline-end: -4px;
    min-width: 18px;
    height: 18px;
    padding-inline: 5px;
    /* Was nine pixels. A Persian digit at that size is a smudge, and this
       badge is the one telling somebody they have unread notifications. */
    font-size: 10px;
    line-height: 1;
    border: 2px solid var(--color-surface);
}

[dir="rtl"] .btn-badge .unread-pill {
    min-width: 20px;
    height: 20px;
    font-size: 11px;
}

/* --- System health list ---------------------------------------------------
   A short list of statements, one per check. The dot is decoration; the
   sentence beside it is what a reader acts on. */
.check-list {
    list-style: none;
    display: flex;
    flex-direction: column;
}

.check-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-block-end: 1px solid var(--color-border);
}

.check-row:last-child { border-block-end: 0; }

.check-row .status-dot { margin-block-start: 6px; }

.check-row > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.check-row strong {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
}

/* --- File picker ----------------------------------------------------------
   The browser's own file control cannot be styled and looks nothing like
   the rest of the forms here, so it is taken out of the flow and a label
   does its job. The input keeps its place in the tab order and still
   receives focus, which is why it is clipped rather than hidden. */
.file-picker {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.file-picker input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.file-picker .file-button {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 32px;
    padding-inline: var(--space-3);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text-primary);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
    flex: none;
}

.file-picker .file-button:hover { background: var(--color-surface-secondary); }

.file-picker input[type="file"]:focus-visible + .file-button {
    outline: 2px solid var(--color-border-focus);
    outline-offset: 2px;
}

.file-picker .file-name {
    min-width: 0;
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.file-picker .file-name.is-empty { color: var(--color-text-tertiary); }

.file-picker .file-clear {
    flex: none;
    border: 0;
    background: none;
    padding: var(--space-1);
    cursor: pointer;
    color: var(--color-text-tertiary);
    display: flex;
}

.file-picker .file-clear:hover { color: var(--color-danger); }

/* --- QR frame -------------------------------------------------------------
   The code is drawn on the server as an SVG, so it is sized here rather
   than in the markup. A white plate under it matters: a scanner needs the
   quiet zone to stay light even when the reader is in dark mode. */
.qr-frame {
    display: inline-flex;
    padding: var(--space-2);
    background: #ffffff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    align-self: flex-start;
}

.qr-frame svg {
    width: 180px;
    height: 180px;
    display: block;
}

/* --- Am I taking work? ------------------------------------------------------
   A dot on the avatar, and a title that says the same thing in words, because
   a colour on its own is not a message everybody receives. Only drawn once
   someone has an availability, so an avatar in a list is unaffected. */
.avatar.has-presence {
    position: relative;
    overflow: visible;
}

.avatar.has-presence::after {
    content: "";
    position: absolute;
    inset-block-end: -1px;
    inset-inline-end: -1px;
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    border: 2px solid var(--color-surface);
    background: var(--color-text-tertiary);
}

.avatar.has-presence.is-available::after { background: var(--color-success); }
.avatar.has-presence.is-away::after      { background: var(--color-warning); }
.avatar.has-presence.is-busy::after      { background: var(--color-danger); }
