/* =================================================================
   SURVIVAL PANEL

   A note on colour: this file uses --color-text-secondary (#94a3b8, 6.92:1
   on the panel background) and never --color-text-muted (#64748b, 3.73:1).
   Muted fails WCAG AA for body text, and every dimmed thing here — objective
   progress, the next tribute price, ledger notes — is information a player
   has to be able to read. It was originally written with muted throughout
   and corrected once the numbers were actually measured.

   The 2026-09-09 type pass (docs/TYPE-LEGIBILITY.md) found the same
   mistake made a second way: the colours were right, but seven of these
   styles rendered between 9.9px and 11.5px, which no contrast ratio can
   rescue. Nothing here renders below 0.75rem/12px now. Where 12px cost
   room it came out of letter-spacing, never out of the type.
   =================================================================
   The life clock, the daily ceiling, and every way to feed it.
   See frontend/game/js/lifePanel.js.

   Everything here is prefixed .lf- and lives inside .hud-panel's
   .hp-body, so it inherits the shell's scrolling and 44px header
   controls and only has to describe its own content.
   ================================================================= */

/* --- The clock ------------------------------------------------------ */

.lf-clock {
    padding: 12px;
    margin-bottom: 12px;
    background: rgba(26, 39, 68, 0.5);
    border: 1px solid var(--color-primary-700);
    border-left-width: 3px;
    border-radius: var(--radius-sm);
}

.lf-clock-main {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0 8px;
}

.lf-clock-value {
    font-family: var(--font-display);
    font-size: 2rem;
    line-height: 1.1;
    /* Life is the one figure on this panel that changes while it is being
       read. Tabular digits stop the whole block twitching sideways each
       time the tenths roll over. */
    font-variant-numeric: tabular-nums;
    color: var(--color-text-primary);
}

.lf-clock-unit {
    font-family: var(--font-display);
    font-size: 1rem;
    color: var(--color-text-secondary);
}

.lf-clock-rate {
    margin-left: auto;
    font-family: var(--font-mono, monospace);
    font-size: 0.78rem;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.lf-clock-meta {
    margin-top: 6px;
    font-size: 0.8rem;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

/* The three states. Colour carries on the value and the bar, and the left
   border repeats it down the edge of the block — the value alone is a small
   target on a phone held at arm's length, and the border survives being
   glanced at rather than read.

   Thresholds are set in lifePanel.js and pinned to app.js's life bar, so a
   player never sees the HUD call something critical while this does not. */

.lf-clock.lf-healthy { border-left-color: var(--color-accent-green-light); }
.lf-clock.lf-healthy .lf-clock-value { color: var(--color-accent-green-light); }
.lf-clock.lf-healthy .lf-fill { background: var(--color-accent-green-light); }

.lf-clock.lf-warning { border-left-color: var(--color-accent-orange); }
.lf-clock.lf-warning .lf-clock-value { color: var(--color-accent-orange); }
.lf-clock.lf-warning .lf-fill { background: var(--color-accent-orange); }

.lf-clock.lf-critical { border-left-color: var(--color-accent-red-light); }
.lf-clock.lf-critical .lf-clock-value { color: var(--color-accent-red-light); }
.lf-clock.lf-critical .lf-fill { background: var(--color-accent-red-light); }
.lf-clock.lf-critical .lf-clock-meta { color: var(--color-accent-red-light); }

/* --- Bars ----------------------------------------------------------- */

.lf-track {
    display: block;
    position: relative;
    height: 8px;
    margin-top: 8px;
    background: rgba(10, 15, 26, 0.9);
    border: 1px solid var(--color-primary-700);
    border-radius: 4px;
    overflow: hidden;
}

.lf-track-slim {
    height: 5px;
    margin-top: 6px;
}

.lf-fill {
    display: block;
    height: 100%;
    width: 0;
    background: var(--color-accent-gold);
    /* Matches the 1s tick in lifePanel.js so the bar creeps rather than
       stepping once a second. */
    transition: width 1s linear;
}

.lf-fill-earned {
    background: linear-gradient(90deg, var(--color-accent-gold-dark), var(--color-accent-gold-light));
}

.lf-fill-obj {
    background: var(--color-accent-cyan);
}

/* --- The ceiling ---------------------------------------------------- */

.lf-ceiling {
    padding: 10px 12px;
    margin-bottom: 12px;
    background: rgba(212, 175, 55, 0.07);
    border: 1px solid var(--color-accent-gold-dark);
    border-radius: var(--radius-sm);
}

.lf-ceiling-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.lf-ceiling-label {
    font-family: var(--font-display);
    font-size: var(--text-xs);
    letter-spacing: 1.1px;
    color: var(--color-text-secondary);
}

.lf-ceiling-value {
    font-family: var(--font-display);
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-accent-gold);
    white-space: nowrap;
}

.lf-ceiling-note {
    margin-top: 6px;
    font-size: 0.76rem;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

/* At the ceiling, every action on this panel stops paying. That is the one
   state a player must not mistake for "keep going", so the block stops
   looking like an opportunity and starts looking like a stop sign. */
.lf-capped {
    background: rgba(220, 38, 38, 0.08);
    border-color: var(--color-accent-red);
}

.lf-capped .lf-ceiling-value,
.lf-capped .lf-ceiling-note { color: var(--color-accent-red-light); }

.lf-capped .lf-fill-earned {
    background: var(--color-accent-red-light);
}

/* --- Section heads -------------------------------------------------- */

.lf-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin: 16px 2px 6px;
    font-family: var(--font-display);
    font-size: var(--text-xs);
    letter-spacing: 1.1px;
    color: var(--color-text-secondary);
}

.lf-section-note {
    font-family: var(--font-mono, monospace);
    font-size: var(--text-xs);
    letter-spacing: 0;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.lf-badge {
    padding: 2px 7px;
    background: var(--color-accent-gold);
    border-radius: 9px;
    font-size: var(--text-xs);
    letter-spacing: 0.4px;
    color: var(--color-primary-900);
    white-space: nowrap;
}

/* The "this section could not be reached" line. Deliberately quiet: one of
   three sources being down is not an error the player caused or can fix,
   and the other two sections are still worth reading. */
.lf-note {
    padding: 10px 12px;
    background: rgba(17, 24, 39, 0.6);
    border: 1px dashed var(--color-primary-700);
    border-radius: var(--radius-sm);
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--color-text-secondary);
}

/* --- Objectives ----------------------------------------------------- */

.lf-obj {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    margin-bottom: 6px;
    background: rgba(17, 24, 39, 0.6);
    border: 1px solid var(--color-primary-700);
    border-radius: var(--radius-sm);
}

/* Done, not dimmed. At opacity 0.6 the objective's own description and its
   progress line fell to ~3.5:1 — a finished row is still the record of what
   the player did today. The CLAIMED chip and the flatter field carry the
   state instead (achievements.css makes the same argument at length). */
.lf-obj-done {
    background: rgba(26, 39, 68, 0.35);
    border-color: rgba(26, 39, 68, 0.9);
}

.lf-obj-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    /* Without this a long objective name refuses to shrink and pushes the
       Claim button off the right edge of a 390px sheet. */
    min-width: 0;
}

.lf-obj-name {
    font-family: var(--font-heading);
    font-weight: var(--font-semibold);
    font-size: 0.9rem;
    color: var(--color-text-primary);
}

.lf-obj-desc {
    font-size: var(--text-xs);
    color: var(--color-text-secondary);
    overflow-wrap: anywhere;
}

.lf-obj-progress {
    margin-top: 4px;
    font-family: var(--font-mono, monospace);
    font-size: var(--text-xs);
    color: var(--color-text-secondary);
}

.lf-claimed {
    flex-shrink: 0;
    font-family: var(--font-display);
    font-size: var(--text-xs);
    letter-spacing: 0.8px;
    color: var(--color-accent-green-light);
}

/* --- Tribute -------------------------------------------------------- */

.lf-tribute {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: rgba(26, 39, 68, 0.6);
    border: 1px solid var(--color-primary-600);
    border-radius: var(--radius-sm);
}

.lf-tribute-blocked { opacity: 0.75; }

.lf-tribute-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.lf-tribute-grant {
    font-family: var(--font-heading);
    font-weight: var(--font-semibold);
    font-size: 0.9rem;
    color: var(--color-accent-green-light);
}

.lf-tribute-cost {
    font-family: var(--font-mono, monospace);
    font-size: 0.76rem;
    color: var(--color-text-secondary);
    overflow-wrap: anywhere;
}

/* The escalation. Muted, because it is context rather than the offer — but
   present, because a price that only appears after payment is a trap. */
.lf-tribute-next {
    font-size: var(--text-xs);
    line-height: 1.35;
    color: var(--color-text-secondary);
    overflow-wrap: anywhere;
}

.lf-reason {
    margin-top: 6px;
    padding: 0 2px;
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--color-accent-orange);
}

/* --- History -------------------------------------------------------- */

.lf-history {
    display: flex;
    flex-direction: column;
}

.lf-entry {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px;
    border-bottom: 1px solid rgba(26, 39, 68, 0.8);
}

.lf-entry:last-child { border-bottom: none; }

.lf-entry-amount {
    flex-shrink: 0;
    min-width: 48px;
    font-family: var(--font-mono, monospace);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-accent-green-light);
}

.lf-entry-info {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
}

.lf-entry-source {
    font-size: 0.8rem;
    color: var(--color-text-primary);
}

.lf-entry-note {
    font-size: var(--text-xs);
    color: var(--color-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.lf-entry-time {
    flex-shrink: 0;
    font-family: var(--font-mono, monospace);
    font-size: var(--text-xs);
    color: var(--color-text-secondary);
    white-space: nowrap;
}

/* --- Buttons -------------------------------------------------------- */

.lf-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* WCAG 2.5.5: Claim and Pay are the two things this panel exists to let
       a player do, and both are pressed on a phone in a hurry. */
    min-height: var(--touch-target);
    min-width: 88px;
    padding: 0 12px;
    background: rgba(26, 39, 68, 0.9);
    border: 1px solid var(--color-primary-600);
    border-radius: 3px;
    color: var(--color-text-secondary);
    font-family: var(--font-heading);
    font-size: 0.8rem;
    font-weight: var(--font-semibold);
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast),
                background var(--transition-fast);
}

.lf-btn:hover:not(:disabled) {
    color: var(--color-text-primary);
    border-color: var(--color-accent-gold);
}

/* A disabled Claim/Pay button still has to say why — "In progress",
   "Capped", "Can't afford". At opacity 0.5 that label measured 2.55:1, so
   the state is carried by colour and field instead of by alpha. */
.lf-btn:disabled {
    color: var(--color-text-secondary);
    background: rgba(17, 24, 39, 0.75);
    border-color: var(--color-primary-700);
    cursor: not-allowed;
}

.lf-btn-primary:disabled {
    background: rgba(212, 175, 55, 0.3);
    border-color: rgba(212, 175, 55, 0.45);
    color: var(--color-text-primary);
}

/* base.css clears button outlines globally; keyboard users still need one. */
.lf-btn:focus-visible {
    outline: 2px solid var(--color-accent-gold);
    outline-offset: 2px;
}

.lf-btn-primary {
    background: var(--color-accent-gold);
    border-color: var(--color-accent-gold);
    color: var(--color-primary-900);
}

.lf-btn-primary:hover:not(:disabled) {
    background: var(--color-accent-gold-light);
    color: var(--color-primary-900);
}

/* --- Narrow widths -------------------------------------------------- */

/* Below ~420px an 88px button beside a two-line description leaves the text
   three or four words wide and the row reads as broken. Stacked, it reads as
   a labelled action — and the button gets the full sheet width, which is the
   easiest thing on the panel to hit one-handed. */
@media (max-width: 420px) {
    .lf-obj,
    .lf-tribute {
        flex-direction: column;
        align-items: stretch;
    }

    .lf-obj .lf-btn,
    .lf-tribute .lf-btn {
        width: 100%;
    }

    .lf-claimed {
        align-self: flex-start;
    }

    .lf-clock-value { font-size: 1.7rem; }

    /* The rate loses its right-hand anchor once the value block can wrap;
       left-aligned under the number it stays part of the same reading. */
    .lf-clock-rate {
        margin-left: 0;
        flex-basis: 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .lf-fill { transition: none; }
}
