/* Copyright (c) 2025 Onur Gumus. All Rights Reserved.
   Licensed under the proprietary license. See LICENSE file in the project root.

   Styles for common/ui.js (toasts and dialogs).

   Tokens only - no literal colours. Hardcoded hex is exactly why the roadmap
   modals rendered dark slate on a light background. */

/* ============================================================ toasts */

.ui-toasts {
    position: fixed;
    z-index: 20000; /* above .language-menu (10000) */
    /* Clear the fixed nav rather than overlapping it. */
    inset-block-start: calc(6.25rem + env(safe-area-inset-top, 0px));
    inset-inline-end: calc(1rem + env(safe-area-inset-right, 0px));
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    inline-size: min(24rem, calc(100vw - 2rem));
    pointer-events: none;
}

.ui-toast {
    pointer-events: auto;
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.5rem 0.75rem;
    padding: 0.875rem 1rem;
    border: 1px solid var(--border-color);
    border-inline-start: 3px solid var(--text-tertiary);
    border-radius: 12px;
    background: var(--bg-card);
    backdrop-filter: blur(12px);
    color: var(--text-primary);
    font-size: 0.95rem;
    line-height: 1.5;
    box-shadow: 0 8px 24px oklch(0 0 0 / 0.28);

    opacity: 0;
    translate: 0 -0.5rem;
    transition: opacity 0.18s ease, translate 0.18s ease;
}

.ui-toast--in      { opacity: 1; translate: 0 0; }
.ui-toast--leaving { opacity: 0; translate: 0 -0.5rem; }

.ui-toast--success { border-inline-start-color: var(--green); }
.ui-toast--info    { border-inline-start-color: var(--cyan); }
.ui-toast--warn    { border-inline-start-color: var(--orange); }
.ui-toast--error   { border-inline-start-color: var(--error-color); }

.ui-toast__body { grid-column: 1; min-inline-size: 0; overflow-wrap: anywhere; }

.ui-toast__close {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    background: none;
    border: 0;
    color: var(--text-tertiary);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.25rem;
}
.ui-toast__close:hover { color: var(--text-primary); }

.ui-toast__action {
    grid-column: 1 / -1;
    justify-self: start;
    background: none;
    border: 0;
    padding: 0;
    color: var(--cyan);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}

.ui-toast__detail {
    grid-column: 1 / -1;
    font-size: 0.85rem;
    color: var(--text-secondary);
}
.ui-toast__detail summary { cursor: pointer; }
.ui-toast__detail p {
    margin: 0.5rem 0 0;
    padding: 0.5rem;
    border-radius: 6px;
    background: var(--bg-tertiary);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow-wrap: anywhere;
}

/* ============================================================ dialogs */

.ui-dialog {
    /* Rendered in the top layer, so it needs no z-index of its own.
       margin:auto is what centres a modal <dialog>, and the reset layer's
       `* { margin: 0 }` cancels the user-agent rule - so restate it here or
       every dialog pins to the top-left corner. */
    margin: auto;
    inline-size: min(30rem, calc(100vw - 2rem));
    max-block-size: min(85dvh, calc(100dvh - 2rem));
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 16px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    overflow: auto;
}

.ui-dialog::backdrop {
    background: oklch(0 0 0 / 0.6);
    backdrop-filter: blur(4px);
}

.ui-dialog__content { padding: 1.5rem 1.5rem 0; }

.ui-dialog__title {
    margin: 0 0 0.5rem;
    font-size: 1.25rem;
    line-height: 1.3;
    color: var(--text-primary);
}

.ui-dialog__body {
    margin: 0;
    color: var(--text-secondary);
    line-height: 1.6;
}

.ui-dialog__label {
    display: block;
    margin: 1rem 0 0.375rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.ui-dialog__field {
    inline-size: 100%;
    padding: 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: var(--bg-primary);
    color: var(--text-primary);
    /* 16px: anything smaller makes iOS zoom the viewport on focus. */
    font-size: 1rem;
    font-family: inherit;
}
.ui-dialog__field:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
}

.ui-dialog__error {
    margin: 0.5rem 0 0;
    color: var(--error-color);
    font-size: 0.9rem;
}

.ui-dialog__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 1.5rem;
    flex-wrap: wrap;
}

/* ---- choices ---- */

.ui-dialog__choices {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-block-start: 1rem;
}

.ui-choice {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.875rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--text-primary);
    text-align: start;
    font: inherit;
    cursor: pointer;
    min-block-size: 44px;
}
.ui-choice:hover { border-color: var(--border-hover); }
.ui-choice__label { font-weight: 600; }
.ui-choice__desc  { font-size: 0.875rem; color: var(--text-secondary); line-height: 1.45; }
.ui-choice--danger .ui-choice__label { color: var(--error-color); }

/* ---- buttons ---- */

.ui-btn {
    padding: 0.625rem 1.25rem;
    border-radius: 8px;
    border: 1px solid transparent;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    min-block-size: 44px;
}
.ui-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.ui-btn--primary { background: var(--gradient-primary); color: var(--bg-primary); }
.ui-btn--danger  { background: var(--error-color); color: var(--bg-primary); }
.ui-btn--ghost   { background: transparent; color: var(--text-primary); border-color: var(--border-color); }
.ui-btn--ghost:hover { border-color: var(--border-hover); }

/* =========================================================== ui.busy

   The phase checklist for AI generation. Three states, and the difference
   between them has to survive being read at a glance from across a desk:
   done is ticked and dimmed, active is the only thing moving, pending is
   flat. */

.ui-dialog--busy { min-inline-size: min(28rem, 92vw); }

.ui-busy__steps {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ui-busy__step {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    font-size: 0.95rem;
    color: var(--text-tertiary);
}

.ui-busy__mark {
    inline-size: 1.1rem;
    block-size: 1.1rem;
    flex: none;
    border-radius: 50%;
    border: 2px solid var(--border-color);
    display: grid;
    place-items: center;
}

.ui-busy__step[data-state="done"] { color: var(--text-secondary); }
.ui-busy__step[data-state="done"] .ui-busy__mark {
    border-color: var(--success-color);
    background: var(--success-color);
}
/* Drawn rather than a glyph so it needs no font and no extra request. */
.ui-busy__step[data-state="done"] .ui-busy__mark::after {
    content: "";
    inline-size: 0.3rem;
    block-size: 0.55rem;
    border: solid var(--bg-primary);
    border-width: 0 2px 2px 0;
    rotate: 45deg;
    translate: 0 -1px;
}

.ui-busy__step[data-state="active"] {
    color: var(--text-primary);
    font-weight: 600;
}
.ui-busy__step[data-state="active"] .ui-busy__mark {
    border-color: var(--cyan);
    border-block-start-color: transparent;
    animation: ui-busy-spin 0.9s linear infinite;
}

.ui-busy__step[data-state="failed"] { color: var(--error-color); }
.ui-busy__step[data-state="failed"] .ui-busy__mark {
    border-color: var(--error-color);
    background: var(--error-color);
}

@keyframes ui-busy-spin { to { rotate: 360deg; } }

.ui-busy__foot {
    margin: 1rem 0 0;
    font-size: 0.85rem;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
}
.ui-busy__foot--stalled { color: var(--warning-color, var(--orange)); }

.ui-dialog__note {
    margin: 0.75rem 0 0;
    font-size: 0.85rem;
    color: var(--text-tertiary);
}

/* ============================================================ motion */

@media (prefers-reduced-motion: reduce) {
    .ui-toast {
        transition: none;
        opacity: 1;
        translate: none;
    }
    .ui-toast--leaving { opacity: 0; }

    /* The spinner is the only signal that the job is alive, so slow it down
       rather than stopping it. */
    .ui-busy__step[data-state="active"] .ui-busy__mark {
        animation-duration: 3s;
    }
}

@media (width <= 480px) {
    .ui-toasts {
        inset-inline: 0.5rem;
        inline-size: auto;
    }
    .ui-dialog__actions { flex-direction: column-reverse; }
    .ui-dialog__actions .ui-btn { inline-size: 100%; }
}
