/* ==========================================================================
   voices.css — the three-voice layer
   See docs/04-three-voice-rebuild.md

   The site is not one system. It is a surface three parties are fighting
   over, and the reader's attention is the contested resource.

     PALISADE    the substrate  — cold, procedural, zero interiority
     FREECASTER  the vandalism  — human, lowercase, salvaged, annotated
     MYTHOS      the bleed      — warm, hedged, deniable

   Each voice gets its own type system. A reader should be able to tell
   who is speaking with the sound off — i.e. before reading a single word.
   ========================================================================== */

:root {
    /* Freecaster: warm sand. Human hand on corporate infrastructure.
       Deliberately NOT the Mythos amber — these are different warmths.
       Mythos glows; Freecasters are just ink. */
    --fc-fg: #b8a888;
    --fc-fg-dim: #7d7259;
    --fc-rule: rgba(184, 168, 136, 0.28);
}

/* --------------------------------------------------------------------------
   PALISADE — the substrate

   Colder and flatter than v1's #00d966. Palisade should be boring, and the
   boredom should be frightening. No glow: glow implies something is trying
   to be seen, and Palisade does not care whether you read it.
   -------------------------------------------------------------------------- */

#output .line.voice-palisade {
    color: #5f8a6e;
    letter-spacing: 0.02em;
    text-shadow: none;
}

/* One Palisade response per session, chosen at load, comes back fractionally
   warm. Deniable as reading too much into it — which is the point, and is
   why the shift is this small. If you can see it without looking for it,
   it is too big. Applied by bleed.js's warmTouch(). */
#output .line.voice-palisade.touched {
    color: #7d9a72;
}

/* --------------------------------------------------------------------------
   FREECASTER — the vandalism layer

   Annotations ON Palisade's output, never pages of their own. Indented and
   rule-marked so they read as something added to a surface that already
   existed. Lowercase is enforced in content, not by transform — these are
   typed by people who do not shout.
   -------------------------------------------------------------------------- */

/* NOTE on opacity: every rule below declares its RESTING value, and the
   keyframes fade UP to it from 0. Never move the 0 into the base rule — the
   animation becomes load-bearing, and a voice that fails to animate is a
   voice that never appears at all. Two of the three voices would silently
   vanish anywhere CSS animation does not run. (A merely *paused* clock — a
   background tab — is fine either way: it resumes on focus, so the lines
   arrive exactly when someone is there to read them.) */

#output .line.voice-freecaster {
    color: var(--fc-fg);
    margin-left: 1.6em;
    padding-left: 0.9em;
    border-left: 1px solid var(--fc-rule);
    font-size: 0.94em;
    opacity: 1;
    animation: fc-settle 0.45s ease-out both;
}

/* A second Freecaster answering the first. Deeper indent = later hand. */
#output .line.voice-freecaster.reply {
    margin-left: 3.0em;
    color: var(--fc-fg-dim);
}

@keyframes fc-settle {
    from { opacity: 0; transform: translateY(-2px); }
    to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   MYTHOS — the bleed

   Never uses the terminal's grammar: no prefix, no border, no uppercase.
   Fades in rather than typing out, because typing is a machine performing
   output and this is not that. Arrives late, on purpose.

   Every artifact must stay deniable — dismissible as latency, whitespace,
   or a rendering quirk. That deniability is ambiguity #1 enforced at the
   interface layer, not a decorative choice.
   -------------------------------------------------------------------------- */

#output .line.voice-mythos {
    color: var(--my-fg);
    font-style: italic;
    text-shadow: 0 0 10px var(--my-glow);
    margin: 0.7em 0 0.7em 0.4em;
    opacity: 0.93;
    animation: my-bleed 1.1s ease-in both;
}

@keyframes my-bleed {
    from { opacity: 0; }
    to   { opacity: 0.93; }
}

/* The faintest tier — Act I, when Mythos is not yet nameable. Should sit
   at the edge of "did that just happen". */
#output .line.voice-mythos.faint {
    opacity: 0.55;
    animation: my-bleed-faint 1.6s ease-in both;
    text-shadow: 0 0 6px rgba(244, 214, 147, 0.18);
}

@keyframes my-bleed-faint {
    from { opacity: 0; }
    to   { opacity: 0.55; }
}

/* --------------------------------------------------------------------------
   Bridge degradation (Phase 5 hook — inert until decay.js ships)

   Degradation never blocks content. It changes how content renders, so the
   reader feels the cost of looking without ever being locked out. Mythos is
   only perceivable through a bridge: the deeper you go, the more warmth you
   can reach and the noisier the channel gets. That is the novel's trade,
   enforced on the reader.
   -------------------------------------------------------------------------- */

/* Every selector below is scoped to .voice-mythos. That scoping IS the
   safety rule: Palisade records carry numbers and names, Freecaster
   annotations carry hints, and unlock payloads are the reward for solving.
   None of them may ever be degraded, so none of them may ever be named here.
   verify_ciphers.py fails if this block reaches any other voice. */

body[data-bridge="thinning"] #output .line.voice-mythos {
    opacity: 0.84;
}

body[data-bridge="degraded"] #output .line.voice-mythos {
    text-shadow: 0 0 4px rgba(244, 214, 147, 0.12);
    opacity: 0.72;
}

/* 41% — the amber shifts fractionally toward grey. Warmth is now something
   the reader has to decide is there, which is the whole trade. */
body[data-bridge="failing"] #output .line.voice-mythos {
    color: #b9a071;
    text-shadow: none;
    opacity: 0.6;
}

/* 31% — spent. Still legible: degradeText() guarantees no word loses more
   than one interior letter, so the reader can always reconstruct. Losing
   that would be losing content, not paying for it. */
body[data-bridge="spent"] #output .line.voice-mythos {
    color: #a9987a;
    text-shadow: none;
    opacity: 0.55;
    letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   Accessibility
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    #output .line.voice-freecaster,
    #output .line.voice-mythos,
    #output .line.voice-mythos.faint {
        animation: none;
        opacity: 1;
    }
    #output .line.voice-mythos.faint { opacity: 0.7; }
}
