/* Alerts view (B-2 alerts-surface slice, round 1).
 *
 * Structural lineage: the .saved-view block in chat.css, which is itself a
 * clone of the .alerts-view block above it. This file styles only what lives
 * INSIDE #alertsViewBody (rows, finds, sections, states, the new-watch form) —
 * the full-page shell (body.view-alerts, .alerts-view, .alerts-view-title,
 * .alerts-view-body) stays in chat.css where the other view shells live.
 *
 * Colour rule (CLAUDE.md): tokens only. There is not one raw hex or rgb() in
 * this file, and alerts-view.test.js asserts that.
 *
 * Two cascade traps this file deliberately avoids:
 *   - No media query precedes its own base rule (chat.css's ordering bug).
 *   - Nothing here relies on `el.hidden` alone; section vanish/appear is done
 *     by NOT RENDERING the section (alerts-view.js), and .alerts-form-error
 *     pairs its [hidden] with an explicit display:none below, because an
 *     author `display` beats the hidden attribute (the recurring #370 lesson).
 */

/* ---- action bar --------------------------------------------------------- */

.alerts-actions {
    display: flex;
    gap: var(--aw-space-2);
    margin: 0 0 var(--aw-space-4);
}

.alerts-btn {
    min-height: 44px; /* F9 chip-x lesson: real hit target */
    padding: var(--aw-space-2) var(--aw-space-4);
    border-radius: var(--aw-radius-pill);
    font: inherit;
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
}

.alerts-btn.is-primary {
    border: 1px solid var(--aw-accent-btn);
    background: var(--aw-accent-btn);
    color: var(--aw-on-accent);
}

.alerts-btn.is-primary:hover,
.alerts-btn.is-primary:focus-visible {
    background: var(--aw-accent-btn-hover);
    border-color: var(--aw-accent-btn-hover);
}

.alerts-btn.is-secondary {
    border: 1px solid var(--aw-line-strong);
    background: transparent;
    color: var(--aw-ink);
}

.alerts-btn.is-secondary:hover,
.alerts-btn.is-secondary:focus-visible {
    border-color: var(--aw-accent);
}

.alerts-btn:focus-visible {
    outline: 2px solid var(--aw-accent);
    outline-offset: 2px;
}

/* ---- sections ----------------------------------------------------------- */

.alerts-section {
    margin: 0 0 var(--aw-space-5);
}

.alerts-section-title {
    margin: 0 0 var(--aw-space-2);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aw-structure);
}

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

/* ---- watch row ---------------------------------------------------------- */

.alert-row,
.alert-find {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--aw-space-3);
    padding: var(--aw-space-3) var(--aw-space-4);
    border: 1px solid var(--aw-line);
    border-radius: var(--aw-radius);
    background: var(--aw-surface);
}

.alert-row-main,
.alert-find-main {
    min-width: 0;
    flex: 1 1 auto;
}

.alert-row-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--aw-space-2);
}

.alert-row-title {
    font-weight: 600;
    color: var(--aw-ink);
}

.alert-row-spec {
    margin: var(--aw-space-1) 0 0;
    font-size: 0.82rem;
    color: var(--aw-ink-soft);
}

/* Freshness is structural metadata, not a claim about award space — the
   quietest ink in the row. Today it reads "Never checked yet" on every row,
   which is the truth this surface exists to tell. */
.alert-row-freshness {
    margin: var(--aw-space-1) 0 0;
    font-size: 0.78rem;
    color: var(--aw-structure);
}

/* Badge: quiet structure ink for "Watching" (a state, not news); the choice
   accent for "Space found" (the one thing worth a look). An alert with no
   watch_state renders no badge node at all, so there is no third variant. */
.alert-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--aw-space-2);
    border-radius: var(--aw-radius-pill);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.03em;
}

.alert-badge.is-watching {
    color: var(--aw-structure);
    background: var(--aw-structure-wash);
    border: 1px solid var(--aw-structure-dim);
}

.alert-badge.is-matched {
    color: var(--aw-choice);
    background: var(--aw-choice-wash);
    border: 1px solid var(--aw-choice);
}

.alert-row-actions,
.alert-find-actions {
    flex: 0 0 auto;
}

.alert-row-cancel,
.alert-find-mark-read {
    min-height: 44px;
    padding: var(--aw-space-2) var(--aw-space-3);
    border: 1px solid var(--aw-line-strong);
    border-radius: var(--aw-radius-pill);
    background: transparent;
    color: var(--aw-ink);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.alert-row-cancel:hover,
.alert-row-cancel:focus-visible,
.alert-find-mark-read:hover,
.alert-find-mark-read:focus-visible {
    border-color: var(--aw-accent);
}

.alert-row-cancel:disabled,
.alert-find-mark-read:disabled {
    opacity: 0.55;
    cursor: default;
}

/* ---- recent finds ------------------------------------------------------- */

.alert-find.is-unread {
    border-color: var(--aw-accent-line);
}

.alert-find-title {
    display: block;
    color: var(--aw-ink);
}

/* The ONLY pre-wrap in this surface, and it sits on the leaf that holds the
   notification body. The body is preformatted by design (a decision line, a
   blank line, one ladder line per date+program, a Book: url, a freshness
   line); collapsing it destroys the ladder. pre-wrap on any CONTAINER would
   inherit into template markup and render its indentation as blank lines —
   the #235 .bubble bug, which alerts-view.test.js re-checks by probing every
   ancestor. */
.alert-find-body {
    white-space: pre-wrap;
    margin: var(--aw-space-2) 0 0;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--aw-ink-soft);
    overflow-wrap: anywhere;
}

.alert-find-time {
    display: block;
    margin-top: var(--aw-space-2);
    font-size: 0.74rem;
    color: var(--aw-structure);
}

.alert-find.is-read .alert-find-title,
.alert-find.is-read .alert-find-body {
    color: var(--aw-ink-faint);
}

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

/* 240px rhythm, ruled once for the whole empty-state family
   (agent-lab/docs/design/2026-09-01-empty-state-family.md §2). */
.alerts-state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: var(--aw-space-2);
    min-height: 240px;
    padding: var(--aw-space-4);
    border: 1px solid var(--aw-line);
    border-radius: var(--aw-radius);
    background: var(--aw-surface);
}

.alerts-state.is-error {
    border-color: var(--aw-bad);
}

.alerts-state-heading {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--aw-ink);
}

.alerts-state-body {
    margin: 0;
    max-width: 46ch;
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--aw-ink-soft);
}

.alerts-state-cta {
    margin-top: var(--aw-space-2);
}

.alerts-state-loading {
    margin: 0;
    padding: var(--aw-space-4);
    color: var(--aw-ink-soft);
}

/* An error block nested inside a section is a per-tier message, not a page
   state: it must not claim the full 240px rhythm. */
.alerts-section .alerts-state.is-error {
    min-height: 0;
}

/* ---- new-watch form ----------------------------------------------------- */

.alerts-form {
    margin: 0 0 var(--aw-space-5);
    padding: var(--aw-space-4);
    border: 1px solid var(--aw-line-2);
    border-radius: var(--aw-radius);
    background: var(--aw-surface-2);
}

.alerts-form-title {
    margin: 0 0 var(--aw-space-3);
    font-size: 0.95rem;
    color: var(--aw-ink);
}

.alerts-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--aw-space-3);
}

/* Anchor for the airport type-ahead dropdown, which positions itself
   absolutely against the field wrapper (.airport-typeahead-listbox). */
.alerts-form-field {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--aw-space-1);
    min-width: 0;
}

.alerts-form-label {
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--aw-structure);
}

/* box-sizing is NOT globally reset in this app (chat.css sets it per
   selector), so width:100% + padding + border overflowed the grid column by
   26px — caught in a real engine, invisible to jsdom's layout-free probes. */
.alerts-form-input {
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
    padding: var(--aw-space-2) var(--aw-space-3);
    border: 1px solid var(--aw-line-strong);
    border-radius: var(--aw-radius-sm);
    background: var(--aw-ground-2);
    color: var(--aw-ink);
    font: inherit;
    font-size: 0.88rem;
}

.alerts-form-input:focus-visible {
    outline: 2px solid var(--aw-accent);
    outline-offset: 1px;
}

.alerts-form-error {
    margin: var(--aw-space-3) 0 0;
    font-size: 0.82rem;
    color: var(--aw-bad-ink);
}

/* el.hidden alone loses to an author display rule (#370, twice) — pair it. */
.alerts-form-error[hidden] {
    display: none;
}

.alerts-form-actions {
    display: flex;
    gap: var(--aw-space-2);
    margin-top: var(--aw-space-4);
}

/* ---- phones ------------------------------------------------------------- */

/* Base rules above, the narrow override here (never the reverse: chat.css
   puts media queries FIRST and equal-specificity overrides silently lose). */
@media (max-width: 700px) {
    .alert-row,
    .alert-find {
        flex-direction: column;
        align-items: stretch;
    }

    .alert-row-actions,
    .alert-find-actions {
        margin-top: var(--aw-space-3);
    }

    .alert-row-cancel,
    .alert-find-mark-read {
        width: 100%;
    }

    .alerts-form-grid {
        grid-template-columns: 1fr;
    }
}
