/* ==========================================================================
   Additions for the server-rendered build.

   Everything else in assets/css is the original COSMIC SHAIVA design system,
   copied unchanged. This file holds only what changes when the pages are HTML
   documents instead of a single-page app: anchor offsets that matter once
   navigation is real, a nav with four destinations rather than five, the
   no-JavaScript fallbacks, and the affordances a document needs that an app
   shell did not.

   The palette rules still hold. Saffron stays at three places (brand mark,
   takeaway card, active nav indicator) — nothing below introduces a fourth.
   ========================================================================== */

/* The phase-1 navigation has four destinations; the original grid assumed the
   five the signed-in app will have. Restated here rather than edited into
   components.css so that file stays a faithful copy. */
.bottom-nav { grid-template-columns: repeat(4, 1fr); }

/* Anchors now scroll the real document, so every jump target has to clear the
   sticky top bar and the rail strip — otherwise the heading lands underneath
   them and looks like the wrong block was selected. */
.block-card,
.rail-anchor,
[id^='section-'] {
    scroll-margin-top: calc(var(--nav-h) + 72px);
}

.rail-anchor { display: block; height: 0; }

html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* ---- Line-preserving prose ---------------------------------------------
   `.verse` is already pre-wrap. Other block types that keep their line breaks
   (flow, quote, source notes) need the same, and must NOT also get <br> — that
   combination double-spaces every line. */
.preserve-lines { white-space: pre-wrap; }

/* ---- Collapsed blocks ---------------------------------------------------
   Applied by script only: with JavaScript off every block stays open, which is
   the correct fallback for a reading app — content the reader cannot reveal
   would simply be missing. */
.block-card [hidden] { display: none; }

/* ---- Block actions ------------------------------------------------------ */

.block-card__actions {
    display: flex;
    justify-content: flex-end;
    margin-top: var(--s-4);
    padding-top: var(--s-3);
    border-top: 1px solid var(--hairline);
}

/* The action is secondary to the verse; it should be findable, not loud. */
.block-card__actions .btn {
    color: var(--ink-faint);
    font-size: var(--text-xs);
}

.block-card__actions .btn:hover { color: var(--copper-bright); }

.btn-sm { padding: var(--s-1) var(--s-3); gap: var(--s-2); }

/* ==========================================================================
   Concept flow (§8) — the shape of a lesson

   A flow block is where the poem's whole arc is drawn: where the poet begins,
   what turns, where the reader is set down. It is the one body that holds more
   than one shape at a time — a numbered map, a summary chain, and the sentences
   written around them — so it gets a layout instead of a row of pills.

   Motion here is decorative only, and never on the words themselves: a spark
   travelling the thread, a halo drawing itself, an arrow breathing. Text is at
   full opacity in the first painted frame, because a reading app whose content
   depends on an animation having run is a reading app that can lose its
   content. Everything below is inside prefers-reduced-motion: no-preference.
   ========================================================================== */

.flow-stack {
    display: flex;
    flex-direction: column;
    gap: var(--s-5);
}

/* The author's own sentences around the chain — quieter than the steps, but
   present. Losing them was the old bug. */
.flow-lead {
    color: var(--ink-soft);
    font-size: calc(var(--text-base) * var(--reader-font-scale));
}

/* ---- The short chain: still pills ---------------------------------------- */

.flow__node {
    transition: border-color var(--fast) var(--ease), color var(--fast) var(--ease);
}

.flow__node--final {
    color: var(--copper-bright);
    border-color: var(--copper-edge);
    background: var(--copper-wash);
}

.flow__arrow { display: inline-grid; place-items: center; }

/* ---- The long walk ------------------------------------------------------- */

.journey { position: relative; }

.journey__steps {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
}

.journey__step {
    position: relative;
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr);
    gap: var(--s-4);
    align-items: start;
}

/*
 * The thread between one marker and the next.
 *
 * 17px is half a marker, so it leaves this step's centre; 100% is this step's
 * own height and --s-4 is the gap to the next one, which lands it exactly on
 * the next marker's centre whatever either step's text does. The last step
 * draws nothing — the walk ends at the lamp.
 */
.journey__step:not(:last-child)::before,
.journey__step:not(:last-child)::after {
    content: '';
    position: absolute;
    left: 16px;
    top: 17px;
    width: 2px;
    height: calc(100% + var(--s-4));
}

.journey__step:not(:last-child)::before { background: var(--hairline-strong); }

/* The light that walks the thread. Drawn as a moving gradient rather than a
   moving box: background-position never touches layout. */
.journey__step:not(:last-child)::after {
    background-image: linear-gradient(to bottom, transparent, var(--copper-bright) 45%, var(--copper-bright) 55%, transparent);
    background-size: 100% 26px;
    background-repeat: no-repeat;
    background-position: 0 -26px;
    opacity: 0;
}

.journey__marker {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--bg-inset);
    border: 1px solid var(--hairline-strong);
    color: var(--copper-bright);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: border-color var(--base) var(--ease);
}

.journey__step:hover .journey__marker { border-color: var(--copper-edge); }

.journey__halo {
    position: absolute;
    inset: -2px;
    width: auto;
    height: auto;
    overflow: visible;
    pointer-events: none;
}

.journey__halo circle {
    fill: none;
    stroke: var(--copper);
    stroke-width: 1.4;
    opacity: 0.45;
    /* Drawn from the top, clockwise, when it animates. */
    transform: rotate(-90deg);
    transform-origin: center;
}

.journey__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--copper);
    opacity: 0.7;
}

/* The last step is where the poet leaves the reader. It is allowed to glow. */
.journey__step--final .journey__marker {
    background: var(--copper-wash);
    border-color: var(--copper-edge);
    box-shadow: var(--glow-copper);
}

.journey__body { display: block; min-width: 0; padding-top: 5px; }

.journey__label {
    display: block;
    font-family: var(--font-tamil);
    font-size: calc(var(--text-base) * var(--reader-font-scale));
    line-height: var(--reader-line-height);
    color: var(--ink);
}

.journey__step--final .journey__label { color: var(--copper-bright); }

/* The English gloss under a Tamil step: §17 — a fallback beside the Tamil,
   never instead of it, so it is deliberately the smaller voice. */
.journey__gloss {
    display: block;
    margin-top: 2px;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--ink-muted);
}

@media (max-width: 480px) {
    .journey__step { gap: var(--s-3); }
}

/* ==========================================================================
   Motion (§4, §36)

   Slow, small, and never in the reading path. Two of these run forever, so
   they are transform/opacity/stroke only — nothing that forces layout.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

    /* One light walking the whole chain: every segment runs the same six
       seconds, each starting a beat after the one above it, so what the eye
       follows is a single point moving from the first step to the last and
       then resting. The beat is derived from the step count, which is why the
       partial writes --journey-steps — a four-step chain and a twenty-two-step
       map both finish their walk in the same time. */
    .journey__step:not(:last-child)::after {
        animation: journeySpark 6s var(--ease) infinite;
        animation-delay: calc(var(--step, 0) * (2.6s / var(--journey-steps, 8)));
    }

    /* Each halo draws itself once, in reading order. */
    .journey__halo circle {
        stroke-dasharray: 100;
        animation: journeyHalo 900ms var(--ease) both;
        animation-delay: calc(var(--step, 0) * 70ms);
    }

    .journey__step--final .journey__marker { animation: sacredPulse 4.5s var(--ease) infinite 1.2s; }

    .flow__arrow svg {
        animation: arrowDrift 2.8s var(--ease) infinite;
        animation-delay: calc(var(--step, 0) * 160ms);
    }

    /* The marks themselves, wherever they are drawn. The wheel turns, the
       flame breathes, the lotus opens — each one slow enough that a reader
       notices it only if they stop to look. */
    .icon-cosmic_ring { animation: sacredSpin 60s linear infinite; transform-origin: center; }
    .icon-atom { animation: sacredSpin 44s linear infinite reverse; transform-origin: center; }
    .icon-jyoti { animation: sacredFlame 3.6s var(--ease) infinite; transform-origin: 50% 70%; }
    .icon-lotus { animation: sacredBreath 6s var(--ease) infinite; transform-origin: 50% 80%; }
    .icon-sparkle { animation: sacredBreath 5s var(--ease) infinite; transform-origin: center; }
}

/* ---- Claim marks (§5, §12) -----------------------------------------------
   What an author's ❌ / ✅ / ⚠ becomes. Sized and coloured to sit in a line of
   Tamil without interrupting it — a refused claim should be recognisable at a
   glance down the page, which is the whole job the emoji was doing. */

.mark {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    vertical-align: -5px;
    margin-inline-end: 2px;
    flex: 0 0 auto;
}

.mark svg { width: 14px; height: 14px; }

.mark--no { color: var(--danger); background: var(--danger-wash); }
.mark--yes { color: var(--ok); background: rgba(111, 191, 139, 0.12); }
.mark--note { color: var(--warn); background: var(--saffron-wash); }

/* In a card title the mark is part of the heading, not an ornament beside it. */
.block-card__title .mark { vertical-align: -4px; margin-inline-end: var(--s-1); }

/* ---- The verse card ------------------------------------------------------
   §4 asks for "very subtle sacred geometry" behind the poem, and the design
   system carries it as `.verse-hero`. This build has no separate hero — the
   verse is a block card like any other — so the treatment is given to the card
   that actually holds the poem. One concentric ring set, anchored off the
   corner at a tenth of full strength, so it is felt rather than seen. */

.block-card[data-block-type='original_verse'] {
    position: relative;
    overflow: hidden;
}

.block-card[data-block-type='original_verse']::after {
    content: '';
    position: absolute;
    top: -150px;
    right: -150px;
    width: 340px;
    height: 340px;
    border-radius: 50%;
    border: 1px solid var(--copper);
    opacity: 0.09;
    box-shadow:
        inset 0 0 0 1px var(--copper),
        inset 0 0 0 36px transparent,
        inset 0 0 0 37px var(--copper),
        inset 0 0 0 72px transparent,
        inset 0 0 0 73px var(--copper);
    pointer-events: none;
}

.block-card[data-block-type='original_verse'] > * { position: relative; z-index: 1; }

/* ---- The front door's mark ---------------------------------------------- */

.sacred-mark {
    width: 104px;
    height: 104px;
    color: var(--copper);
    opacity: 0.85;
    margin-bottom: calc(var(--s-2) * -1);
}

.sacred-mark__wheel,
.sacred-mark__ring {
    /* SVG children rotate about their own box only once it is declared. */
    transform-box: fill-box;
    transform-origin: center;
}

.sacred-mark__ring {
    stroke-dasharray: 26 74;
    opacity: 0.55;
}

@media (prefers-reduced-motion: no-preference) {
    .sacred-mark__wheel { animation: sacredSpin 90s linear infinite; }
    .sacred-mark__ring { animation: sacredSpin 26s linear infinite reverse; }
}

@media (max-width: 480px) {
    .sacred-mark { width: 84px; height: 84px; }
}

@keyframes journeySpark {
    0% { background-position: 0 -26px; opacity: 0; }
    8% { opacity: 0.55; }
    30% { background-position: 0 calc(100% + 26px); opacity: 0; }
    100% { background-position: 0 calc(100% + 26px); opacity: 0; }
}

@keyframes journeyHalo {
    from { stroke-dashoffset: 100; opacity: 0; }
    to { stroke-dashoffset: 0; opacity: 0.45; }
}

@keyframes arrowDrift {
    0%, 100% { transform: translateX(0); opacity: 0.7; }
    50% { transform: translateX(3px); opacity: 1; }
}

@keyframes sacredPulse {
    0%, 100% { box-shadow: var(--glow-copper); }
    50% { box-shadow: 0 0 26px -6px rgba(192, 138, 78, 0.55); }
}

@keyframes sacredSpin {
    to { transform: rotate(360deg); }
}

@keyframes sacredFlame {
    0%, 100% { transform: scaleY(1) scaleX(1); opacity: 0.92; }
    35% { transform: scaleY(1.06) scaleX(0.98); opacity: 1; }
    70% { transform: scaleY(0.97) scaleX(1.02); opacity: 0.95; }
}

@keyframes sacredBreath {
    0%, 100% { transform: scale(1); opacity: 0.9; }
    50% { transform: scale(1.06); opacity: 1; }
}

/* ---- Attached sources (§13) ---------------------------------------------
   These rules lived in the Vue component's SCOPED <style> block, so they were
   not in any of the copied stylesheets — the disclosure rendered with the
   browser's default triangle instead. Restated here, which is where they
   belong now that the renderer is a PHP partial. */

.block-sources {
    margin-top: var(--s-4);
    padding-top: var(--s-3);
    border-top: 1px solid var(--hairline);
}

.block-sources summary {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    cursor: pointer;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-muted);
    list-style: none;
}

.block-sources summary::-webkit-details-marker { display: none; }
.block-sources summary::marker { content: ''; }
.block-sources summary:hover { color: var(--ink); }

/* ---- Theme toggle ------------------------------------------------------- */

[data-theme-toggle] {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: var(--r-sm);
    color: var(--ink-muted);
    flex: 0 0 auto;
    transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}

[data-theme-toggle]:hover { color: var(--copper-bright); background: var(--glass); }

/* ---- Scroll to top ------------------------------------------------------ */

.to-top {
    position: fixed;
    right: var(--s-4);
    bottom: calc(var(--bottom-nav-h) + var(--s-4));
    z-index: 40;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    color: var(--ink-soft);
    background: color-mix(in srgb, var(--bg-raised) 92%, transparent);
    backdrop-filter: blur(var(--blur));
    -webkit-backdrop-filter: blur(var(--blur));
    border: 1px solid var(--hairline-strong);
    box-shadow: var(--shadow-md);
    animation: fadeIn var(--fast) var(--ease);
}

/* The library has no "up" glyph — every mark is drawn once, in one direction
   (§5), and rotating this one is cheaper than adding a near-duplicate. */
.to-top svg { transform: rotate(-90deg); }

.to-top:hover { color: var(--copper-bright); border-color: var(--copper-edge); }

@media (min-width: 900px) {
    .to-top { bottom: var(--s-5); right: var(--s-5); }
}

/* ---- Mobile outline ------------------------------------------------------
   Below 1100px both reader rails are hidden, so on a phone this is the only
   way to see the shape of a long lesson. */

.outline-fab {
    position: fixed;
    left: var(--s-4);
    bottom: calc(var(--bottom-nav-h) + var(--s-4));
    z-index: 40;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    color: var(--copper-bright);
    background: color-mix(in srgb, var(--bg-raised) 94%, transparent);
    backdrop-filter: blur(var(--blur));
    -webkit-backdrop-filter: blur(var(--blur));
    border: 1px solid var(--copper-edge);
    box-shadow: var(--shadow-md);
}

@media (min-width: 1100px) {
    /* The real rails are back; a button that opens a copy of them is noise. */
    .outline-fab { display: none; }
}

#outline-sheet .toc__item { padding-block: var(--s-3); }

/* ---- Reading position ----------------------------------------------------
   Offered, never applied: jumping a returning reader down the page without
   asking is disorienting, so this is a dismissible prompt. */

.resume {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-3) var(--s-4);
    margin-bottom: var(--s-4);
    border-radius: var(--r-md);
    background: var(--copper-wash);
    border: 1px solid var(--copper-edge);
    font-size: var(--text-sm);
}

.resume__spacer { margin-left: auto; }

/* ---- Search -------------------------------------------------------------- */

#search-results { min-height: 40vh; }

/* Held during an in-flight query so the page does not collapse and jump. */
#search-results[aria-busy='true'] { opacity: 0.45; transition: opacity var(--fast) var(--ease); }

.search-result mark { scroll-margin-top: var(--nav-h); }

/* ---- Settings ------------------------------------------------------------ */

.segmented__option { cursor: pointer; }
.segmented__option:focus-within { outline: 2px solid var(--cyan-edge); outline-offset: 2px; }

/* A slider with no read-out makes the reader guess what they just chose. */
.setting-value {
    min-width: 4ch;
    text-align: right;
    font-size: var(--text-xs);
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
}

.setting-row input[type='range'] { max-width: 220px; }

/* ---- Keyboard help ------------------------------------------------------- */

kbd {
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    padding: 2px 6px;
    border-radius: 4px;
    background: var(--bg-inset);
    border: 1px solid var(--hairline-strong);
    color: var(--ink-muted);
}

/* ---- Layout -------------------------------------------------------------- */

.reading-column { margin-inline: auto; }

/* ---- Print ---------------------------------------------------------------
   A lesson is something people print and carry. Everything interactive goes;
   the content, its badges and its disclaimers stay — a printed analogy without
   its §12 notice would be exactly the misreading the badge exists to prevent. */

@media print {
    .topbar,
    .bottom-nav,
    .rails,
    .reader-aside,
    .outline-fab,
    .to-top,
    .toasts,
    .progress-rail,
    .segmented,
    .block-card__actions,
    .block-card__toggle,
    footer {
        display: none !important;
    }

    :root {
        --bg: #fff;
        --bg-card: #fff;
        --bg-raised: #fff;
        --bg-inset: #fff;
        --ink: #000;
        --ink-soft: #222;
        --ink-muted: #555;
        --hairline: #ccc;
    }

    body { background: #fff; }

    .block-card {
        break-inside: avoid;
        border: 1px solid #ddd;
        box-shadow: none;
        background: #fff;
    }

    .block-card [hidden] { display: revert !important; }

    .disclaimer { border: 1px solid #999; }

    a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 0.75em; color: #555; }
}
