/* TradeScheduler - additive micro-interactions only (design stays blue topbar).
   Every selector uses a ts-* prefix; nothing here overrides Tailwind utility classes. */

/* ---------- Toasts ---------- */
.ts-toast-wrap {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 70;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: 20rem;
    width: calc(100% - 2rem);
    pointer-events: none;
}
.ts-toast {
    pointer-events: auto;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-left: 4px solid #3b82f6;
    border-radius: 0.5rem;
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.15);
    padding: 0.75rem 1rem;
    font-size: 0.875rem;
    color: #1f2937;
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    animation: ts-toast-in 0.25s ease-out;
}
.ts-toast--error { border-left-color: #ef4444; }
.ts-toast--success { border-left-color: #22c55e; }
.ts-toast__close {
    margin-left: auto;
    flex-shrink: 0;
    cursor: pointer;
    color: #9ca3af;
    background: none;
    border: none;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0 0 0.5rem;
}
.ts-toast.ts-toast--out { animation: ts-toast-out 0.2s ease-in forwards; }

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

/* ---------- Confirmation modal ---------- */
.ts-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.ts-modal {
    background: #ffffff;
    border-radius: 0.75rem;
    box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.3);
    padding: 1.5rem;
    width: 100%;
    max-width: 24rem;
    animation: ts-modal-in 0.2s ease-out;
}
.ts-modal__title {
    font-size: 1.05rem;
    font-weight: 700;
    color: #111827;
    margin-bottom: 0.5rem;
}
.ts-modal__body { font-size: 0.875rem; color: #4b5563; margin-bottom: 1.25rem; }
.ts-modal__actions { display: flex; justify-content: flex-end; gap: 0.75rem; }
@keyframes ts-modal-in {
    from { opacity: 0; transform: scale(0.95); }
    to { opacity: 1; transform: scale(1); }
}

/* ---------- Count-up numbers ---------- */
.ts-count {
    display: inline-block;
    font-variant-numeric: tabular-nums;
}

/* ---------- Live row filtering ---------- */
.ts-filter-control {
    position: relative;
}
.ts-filter-control input {
    width: 100%;
    border: 1px solid #d1d5db;
    border-radius: 0.375rem;
    padding: 0.375rem 2rem 0.375rem 0.75rem;
    font-size: 0.875rem;
    color: #374151;
}
.ts-filter-control input:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}
.ts-filter-clear {
    position: absolute;
    right: 0.375rem;
    top: 50%;
    transform: translateY(-50%);
    color: #9ca3af;
    cursor: pointer;
    background: none;
    border: none;
    font-size: 0.9rem;
    padding: 0.125rem 0.25rem;
}

/* ---------- Dashboard rows at phone width ----------
   These are plain CSS rather than sm: utilities because tailwind.css is a
   prebuilt *purged* file: it only holds the utilities that were in use when it
   was generated, and Node is not available to regenerate it. sm:flex-col,
   sm:items-start, sm:ml-4 and sm:gap-0 are not in it, so a responsive row
   written with those would silently do nothing on a desktop.

   The stat cards and the money boxes were fixed-column grids. On a phone their
   contents were wider than their tracks, and the overflow dragged the whole
   page sideways. Each row now stacks until the columns genuinely fit, and the
   one-column track is minmax(0, 1fr) so a wide value can never stretch it past
   the viewport again. The breakpoints keep the old look from 400px (two stat
   cards) and 480px (three money boxes) upwards. */
.ts-stat-grid,
.ts-money-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}
.ts-stat-grid { gap: 1rem; }
.ts-money-grid { gap: 0.75rem; }

/* A job card puts its buttons down the right-hand side. A phone has no room for
   that, so the buttons drop under the details and wrap; from 640px they return
   to the narrow right-hand column they have always been. */
.ts-job-card {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.ts-job-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* The top bar holds the brand, the links and the language picker. Those do not
   fit on one line between 768px and about 1080px, and the row used to push the
   page sideways instead of wrapping. */
.ts-nav-row {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

@media (min-width: 400px) {
    .ts-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 480px) {
    .ts-money-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 640px) {
    .ts-job-card {
        flex-direction: row;
        justify-content: space-between;
        align-items: flex-start;
        gap: 0;
    }
    .ts-job-actions {
        flex-direction: column;
        flex-wrap: nowrap;
        margin-left: 1rem;
    }
}

/* ---------- Reveal on scroll ---------- */
.ts-reveal {
    opacity: 0.001;
    transform: translateY(10px);
    transition: opacity 0.45s ease-out, transform 0.45s ease-out;
}
.ts-reveal.ts-reveal--in {
    opacity: 1;
    transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
    .ts-reveal { opacity: 1; transform: none; transition: none; }
    .ts-toast, .ts-modal { animation: none; }
}
