/*
    Additions to MarqueeFinanceV2's design system (app.css), which this app takes unchanged.

    Two rules for anything here:
      1. If app.css already has a class for it, use app.css's. Do not restyle .panel or .grid.
      2. Only what this app has and Marquee Finance does not: the public hero photograph, the
         queue's sortable headers and pager, row selection, and the handful of status and
         decision pills whose vocabulary differs.
*/

/* ───────────────────────────────────────────────────── public: hero banner */

/*
    The photograph above the masthead, carried over from the Apps Script public form
    (PublicFormTemplate.html:51-53). Marquee Finance dropped it and leads with the navy band
    alone; this app keeps it, because it is the first thing a constituent sees and it is what
    makes the page read as the campaign's rather than as a form.

    object-position: center 25% is the deliberate part — it biases the crop upward so faces
    survive the 180px band.

    The gradient underneath is not decoration: it is what shows when a tenant has configured no
    hero at all, so the page still looks intentional with zero config set.
*/
.hero-banner {
    height: 180px;
    background: linear-gradient(135deg, var(--brand) 0%, #2a5298 100%);
}

.hero-banner img {
    display: block;
    width: 100%;
    height: 180px;
    object-fit: cover;
    object-position: center 25%;
}

@media (max-width: 720px) {
    .hero-banner, .hero-banner img { height: 130px; }
}

/* ────────────────────────────────────────────────────── staff: the queue */

/* Sortable headers. Marquee Finance's grid sorts server-side with no header affordance, so
   this is additive. */
.grid th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.grid th.sortable:hover { color: var(--brand-dark); }

.sort-icon { font-style: normal; color: var(--ink-faint); margin-left: 3px; }
.sort-icon.on { color: var(--brand); }

/* The select column. Narrow, and it must not inherit the row's click-to-expand. */
.grid th.col-check, .grid td.col-check { width: 32px; padding-right: 0; }
.grid td.col-check input { accent-color: var(--brand); }

.selection-bar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    background: var(--brand-tint); border: 1px solid var(--brand-border);
    border-radius: var(--radius); padding: 9px 14px; margin-bottom: 16px; font-size: 13px;
}

.pager {
    display: flex; align-items: center; justify-content: center; gap: 14px;
    padding: 14px 0; font-size: 13px; color: var(--ink-soft);
}

/* ─────────────────────────────────────────────────────── the extra pills */

/*
    Marquee Finance's status vocabulary is not quite this app's: it has no `decided` or
    `notified`, and it calls a declined request `cancelled`. The pairs below fill those gaps
    using the same tokens, so a pill is styled by its status name exactly as it is there.
*/
.pill-decided  { background: var(--pill-reviewed-bg);  color: var(--pill-reviewed-txt); }
.pill-notified { background: var(--ok-bg);             color: var(--ok); }
.pill-declined { background: var(--pill-cancelled-bg); color: var(--pill-cancelled-txt); }

/* Flag pills with no Finance equivalent. */
.pill-personal { background: #f3e8fd; color: #6a1fd8; }
.pill-awaiting { background: var(--pill-awaiting-bg); color: var(--pill-awaiting-txt); }

/* The row wash for a declined request. Finance calls the same state `is-cancelled`; both names
   map to one tint so either vocabulary reads correctly. */
.grid tr.is-declined { background: var(--row-cancelled); }
.grid tr.is-declined.alt { background: #ffeeee; }

/* A hidden request is on screen only because somebody asked for it. */
.grid tr.is-hidden td { opacity: .6; font-style: italic; }

/* A tenant's logo in the topbar, in place of the wordmark. brightness(0) invert(1) renders any
   supplied mark flat white so a customer's colour logo does not fight the navy bar. */
.topbar-logo { height: 20px; width: auto; display: block; filter: brightness(0) invert(1); }
.topbar .wordmark { text-decoration: none; color: inherit; display: flex; align-items: center; }

/* ───────────────────────────────────────────────── layout utility classes */

/*
    Marquee Finance sets these inline (style="padding:0", style="flex:1 1 240px"). This app
    cannot: its CSP is `style-src 'self'`, which blocks style ATTRIBUTES as well as <style>
    elements, and hashes do not apply to them without 'unsafe-hashes'. Copying the inline
    styles across produced two blocked-style violations on the first page load.

    Classes instead. Same result, and the policy stays strict.
*/
.panel-flush { padding: 0; }
.field-grow { flex: 1 1 240px; }
.sub-flush { margin: 0; }
.sub-spaced { margin: 12px 0 0; }

/* ─────────────────────────────────────────────────── the activity timeline */

/*
    Comments and audit entries in one list. app.css already styles .comment and .history
    separately, because Marquee Finance shows them in separate panels; here they interleave,
    so the list needs a shared rhythm and a marker that says which kind each entry is
    without reading it.
*/
.timeline { list-style: none; margin: 16px 0 0; padding: 0; border-left: 2px solid var(--border-light); }
.timeline > li { position: relative; padding: 0 0 14px 16px; }
.timeline > li::before {
    content: ""; position: absolute; left: -5px; top: 6px;
    width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong);
}
.timeline > .tl-comment::before { background: var(--brand); }
.tl-audit { font-size: 12px; color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }

/* ──────────────────────────────────────────────────────────── modal dialog */

/*
    A plain overlay, not <dialog>. showModal() needs a JS interop call on every open, and the
    only things it buys here — focus trapping and Esc — are one attribute and one handler.
*/
/* Above the topbar, which app.css:227 makes sticky at z-index 100. At 50 the scrim stopped
   short of the top 52px and the nav links stayed clickable underneath a dialog claiming
   aria-modal, so a click on "Settings" mid-intake threw the form away. */
.modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-start;
         justify-content: center; padding: 24px; overflow-y: auto; background: rgb(0 0 0 / 45%); }
.modal-card { width: min(760px, 100%); background: var(--surface); border-radius: var(--radius);
              box-shadow: var(--shadow); }
.modal-head { display: flex; justify-content: space-between; align-items: center; gap: 12px;
              padding: 16px 20px; border-bottom: 1px solid var(--border-light); }
.modal-head h2 { margin: 0; }
.modal-body { padding: 20px; }
.modal-foot { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
              padding: 16px 20px; border-top: 1px solid var(--border-light); }
/* The grid itself is app.css's .field-grid, which also sizes the labels and inputs inside it;
   only the full-width span is new. */
.field-grid .wide { grid-column: 1 / -1; }

/* ───────────────────────────────────────────────────────── the conflicts chip */

/*
    A schedule conflict is the one thing in the queue that means "somebody has to look at this
    now", so it is the one chip that reads as urgent before it is clicked.

    Bold, and the Conflict pair rather than Caution. DESIGN.md §2 assigns #FCE8E6 / #C5221F to
    "schedule conflicts, validation errors, destructive actions" and #FEF7E0 / #A37200 to
    "warnings that need acknowledgment but aren't blocking" — this chip had the second.
    app.css's own .pill-conflict already uses the pair; this brings the chip into line.

    Written as .chip.chip-conflict so it outranks .chip.active, which is also two classes and
    would otherwise repaint the chip brand-blue the moment the filter is on.
*/
.chip.chip-conflict {
    border-color: var(--error);
    color: var(--error);
    font-weight: 700;
}
.chip.chip-conflict:hover { border-color: var(--error); background: var(--error-bg); }
.chip.chip-conflict.active { border-color: var(--error); background: var(--error-bg); color: var(--error); }

/* ──────────────────────────────────────────── public: the reference number */

/*
    The one thing a requester has to be able to read back over the phone, so it is set in the
    monospace face at a size that survives a photograph of a screen.
*/
.reference {
    font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
    font-size: 20px; letter-spacing: .04em; color: var(--brand);
    background: var(--brand-soft); border-radius: var(--radius);
    display: inline-block; padding: 10px 18px; margin: 4px 0 12px;
    user-select: all;
}

/* ─────────────────────────────────────── public: the wizard's progress rail */

/*
    app.css draws the rail as one absolutely-positioned .steps-fill whose width is set inline.
    This app cannot: its CSP is `style-src 'self'`, which blocks style ATTRIBUTES, and hashes
    do not apply to them without 'unsafe-hashes'. One segment per gap instead, filled by class
    — same rail, no inline anything, and it needs no arithmetic in the markup.

    .steps::before still paints the unfilled track underneath.
*/
.steps-track {
    position: absolute; top: 14px; left: 14px; right: 14px;
    display: flex; z-index: 1; pointer-events: none;
}
.steps-track .seg { flex: 1; height: 2px; background: transparent; transition: background .25s; }
.steps-track .seg.done { background: var(--accent); }

@media (prefers-reduced-motion: reduce) { .steps-track .seg { transition: none; } }

/* ───────────────────────────────────────────── the queue on a narrow screen */

/*
    app.css hides queue columns by position, on a selector — `.grid-requests` — that this app's
    table never carried, so every one of those rules was dead and a phone got all eight columns
    crammed into 375px with the headers and the data landing on top of each other.

    By NAME instead. Position selectors were already wrong once here: they were written before
    the select-all checkbox became column one, so every index was off by one and the rule meant
    to drop "Host" would have dropped "Event".

    What survives on a phone is what a triage decision needs — the event, when it is, what is
    wrong with it, and where it stands. Host, received date and source are one tap away in the
    expanded row, which is where somebody goes to act on it anyway.
*/
@media (max-width: 768px) {
    .grid .col-host,
    .grid .col-received,
    .grid .col-source { display: none; }

    .grid .col-event { max-width: 46vw; }

    /* Long words - an address, an organisation - must wrap rather than force the table wider
       than the screen, which is what pushed the header row out of line with its cells. */
    .grid th, .grid td { overflow-wrap: anywhere; }
    .grid { table-layout: fixed; width: 100%; }

    /* "AWAITING DECISION" is 133px of unbreakable pill in a column narrower than that, so it
       hung past the right edge of the screen and took the page's scroll width with it. */
    .grid .col-status .pill { white-space: normal; font-size: 10px; padding: 3px 6px; }
}

/* Below 420 something else has to go. Flags, because the expanded row repeats the clash and
   the hold, and the event's own name is what somebody is scanning for. */
@media (max-width: 420px) {
    .grid .col-flags { display: none; }
    .grid .col-event { max-width: 52vw; }
}

/* ─────────────────────────────────────────────────── hiding a request */

/*
    Deliberately not a .btn-ghost like its neighbours. Hiding takes a request out of everyone's
    default view, and it is the one control on the page whose effect a colleague will not see
    happen — so it reads as a stop rather than as another link.
*/
.btn-hide {
    background: #4A4A4A;
    border-color: #4A4A4A;
    color: #fff;
}
.btn-hide:hover:not(:disabled) { background: #333; border-color: #333; color: #fff; }

/* ────────────────────────────────────────────────────────────── footer */

.app-footer {
    display: flex; flex-wrap: wrap; gap: 12px; align-items: baseline;
    justify-content: space-between;
    max-width: 1400px; margin: 0 auto; padding: 20px 24px 32px;
    font-family: var(--font-ui); font-size: 11px; color: var(--ink-faint);
}
.app-footer .app-version { margin-left: auto; font-variant-numeric: tabular-nums; }

@media (max-width: 768px) {
    .app-footer { padding: 16px; }
}

/* The mention table's action column shrinks to its button rather than taking a third of the
   width, which it does by default in a three-column fixed layout. */
.grid-mentions .col-actions { width: 1%; white-space: nowrap; text-align: right; }
