/* ==========================================================================
   <mh-upload> - the one upload surface.

   Namespaced `mh-upload__*` on purpose. A generic name here would collide with
   the many bespoke local `.upload-*` / `.dropzone` classes these templates
   already carry (invariant #31), and this file is loaded on every page.

   Tokens only. The drag highlight used to be hardcoded as
   rgba(52, 152, 219, a) across six surfaces at four different alphas (0.04,
   0.08, 0.1, 0.4), so "the box glows" meant a barely-visible tint on one page
   and a heavy wash on another. --brand-blue-rgb exists precisely for this.
   ========================================================================== */

mh-upload {
    display: block;
    width: 100%;
}

.mh-upload__label {
    display: block;
    margin-bottom: var(--spacing-sm);
    font-size: 0.875rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
}

/* --------------------------------------------------------------- the zone */

.mh-upload__zone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    /* Minimum comfortable drop target on desktop; full width on mobile keeps it
       a generous TAP target, which is the primary affordance there. */
    min-height: 132px;
    padding: var(--spacing-md);
    border: 2px dashed var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-dim);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--dur-fast) ease,
                background-color var(--dur-fast) ease,
                color var(--dur-fast) ease;
}

/* The native input covers the whole zone, so the entire surface is one tap
   target and keyboard focus lands on a real control. Opacity 0 rather than
   display:none deliberately - a hidden input is not focusable. */
.mh-upload__input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.mh-upload__input:focus-visible + .mh-upload__icon ~ .mh-upload__text,
.mh-upload__input:focus-visible {
    outline: none;
}

/* Focus is shown on the ZONE, since the input itself is transparent. Never
   removed without a visible replacement. */
.mh-upload__zone:focus-within {
    border-color: var(--brand-blue);
    box-shadow: 0 0 0 3px rgba(var(--brand-blue-rgb), 0.25);
}

.mh-upload__icon {
    font-size: 1.5rem;
    color: var(--text-dim);
    transition: transform var(--dur-fast) ease, color var(--dur-fast) ease;
}

.mh-upload__text {
    font-size: 0.9375rem;
    font-weight: var(--weight-semibold);
    color: var(--text);
}

.mh-upload__hint {
    font-size: 0.8125rem;
    color: var(--text-dim);
}

/* ----------------------------------------------------------- compact variant */

/* Inline control for rows and toolbars where a full zone would wreck the layout.
   Same states and same feedback - only the footprint differs. */
.mh-upload__zone--compact {
    flex-direction: row;
    gap: var(--spacing-xs);
    /* Still a 44px touch target: compact means narrower, never harder to hit. */
    min-height: 44px;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-width: 1px;
    border-radius: var(--radius-xs);
    font-size: 0.8125rem;
}

.mh-upload__zone--compact .mh-upload__icon {
    font-size: 0.9375rem;
}

.mh-upload__zone--compact .mh-upload__text {
    font-size: 0.8125rem;
}

/* The hint has no room inline, but it stays in the DOM: it is the element the
   input's aria-describedby points at, so removing it would take the size and
   format rules away from screen-reader users along with the pixels. */
.mh-upload__zone--compact .mh-upload__hint {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ------------------------------------------------------------- drag states */

.mh-upload__zone.is-dragging {
    border-style: solid;
    border-color: var(--brand-blue);
    background: rgba(var(--brand-blue-rgb), 0.08);
    color: var(--text);
}

.mh-upload__zone.is-dragging .mh-upload__icon {
    color: var(--brand-blue);
    transform: translateY(-2px);
}

.mh-upload__zone.is-rejecting {
    border-style: solid;
    border-color: var(--danger);
    background: color-mix(in srgb, var(--danger) 8%, transparent);
}

.mh-upload__zone.is-rejecting .mh-upload__icon {
    color: var(--danger);
}

/* Hover is an ENHANCEMENT, guarded so it never becomes the only affordance.
   163 hover-reveal rules exist site-wide against 3 such guards, which makes
   this the repo's most common mobile defect. */
@media (hover: hover) {
    .mh-upload__zone:hover {
        border-color: var(--border-strong);
        background: var(--surface-3);
    }
}

/* ------------------------------------------------------------------ queue */

.mh-upload__queue {
    list-style: none;
    margin: var(--spacing-sm) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
}

.mh-upload__item {
    display: grid;
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
        "name status actions"
        "bar  bar    bar";
    align-items: center;
    gap: var(--spacing-xs) var(--spacing-sm);
    padding: var(--spacing-sm) var(--spacing-sm);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.mh-upload__item-name {
    grid-area: name;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.875rem;
    color: var(--text);
}

.mh-upload__item-status {
    grid-area: status;
    font-size: 0.8125rem;
    color: var(--text-dim);
    white-space: nowrap;
}

.mh-upload__item.is-error .mh-upload__item-status {
    color: var(--danger);
    /* The reason must be readable, so it wraps rather than truncating. */
    white-space: normal;
}

.mh-upload__item.is-success .mh-upload__item-status {
    color: var(--success);
}

.mh-upload__bar {
    grid-area: bar;
    height: 3px;
    border-radius: var(--radius-xxs);
    background: var(--surface-3);
    overflow: hidden;
}

.mh-upload__bar-fill {
    display: block;
    height: 100%;
    width: 0;
    background: var(--brand-gradient);
    transition: width var(--dur-fast) linear;
}

.mh-upload__item.is-error .mh-upload__bar-fill {
    background: var(--danger);
}

/* Actions are ALWAYS visible, never hover-revealed: on touch there is no hover,
   and remove/retry are the only way out of a mistake. */
.mh-upload__item .mh-upload__btn {
    grid-area: actions;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44x44 minimum touch target. */
    min-width: 44px;
    min-height: 44px;
    padding: 0 var(--spacing-sm);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    background: transparent;
    color: var(--text-dim);
    font-size: 0.8125rem;
    cursor: pointer;
    transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.mh-upload__item .mh-upload__btn:hover,
.mh-upload__item .mh-upload__btn:focus-visible {
    color: var(--text);
    border-color: var(--border-strong);
}

.mh-upload__btn--remove:hover,
.mh-upload__btn--remove:focus-visible {
    color: var(--danger);
    border-color: var(--danger);
}

/* Two actions need their own column so they do not overlap in the grid area. */
.mh-upload__item.is-error {
    grid-template-columns: 1fr auto auto auto;
}

/* --------------------------------------------------------- live region a11y */

/* Visually hidden but present for assistive tech. NOT display:none, which
   removes it from the accessibility tree entirely. */
.mh-upload__live {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------- 375px */

@media (max-width: 480px) {
    .mh-upload__zone {
        min-height: 112px;
        padding: var(--spacing-md);
    }

    .mh-upload__item {
        /* Stack: a filename plus status plus two 44px buttons cannot share a row
           at this width without truncating the name to uselessness. */
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "name    actions"
            "status  actions"
            "bar     bar";
    }

    .mh-upload__item.is-error {
        grid-template-columns: 1fr auto auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .mh-upload__zone,
    .mh-upload__icon,
    .mh-upload__bar-fill {
        transition: none;
    }
}
