/*
 * File: index.css
 * Description: The listing page - the time axis, the controls and the rows.
 */

/* ========================================
   PAGE GRID
   Vertical rhythm is the grid's gap; main itself has horizontal padding only.
   ======================================== */
.index-page main {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-medium);
    padding-block: var(--space-medium);
}

/* ========================================
   TIME AXIS
   The non-document surface of frontend-design.md 14: the card, the caption
   and the tooltip are ordinary page furniture, only what the canvas paints
   inside itself has a palette of its own (js/timeline.js).

   The axis lies along whichever side of the viewport is longer - a strip
   above the listing in landscape, a rail beside it in portrait - because a
   row of dates is only as readable as the room it has to spread over.
   timeline.js reads the same media query, so the two cannot disagree.
   ======================================== */
.timeline-card {
    /* --sticky-offset is the measured header height, set by index.js: the
       header rescales at every breakpoint and this avoids a second copy of
       its sizing here. */
    position: sticky;
    top: var(--sticky-offset, 0px);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
}

.timeline-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-small);
    flex-wrap: wrap;
}

.timeline-summary {
    color: var(--muted-text);
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-xs);
}

.timeline-container {
    position: relative;   /* anchor for the tooltip */
    width: 100%;
    height: var(--timeline-depth);
    cursor: crosshair;
    user-select: none;
    /* The rail is the control, so the browser must not claim the gesture. */
    touch-action: none;
}

.timeline-canvas {
    display: block;
    border-radius: var(--radius-sm);
}

.timeline-tooltip {
    position: absolute;
    padding: 2px var(--space-small);
    background: var(--card-bg);
    border: 1px solid var(--frame-border);
    border-radius: var(--radius-sm);
    color: var(--text-strong);
    font-size: var(--font-xs);
    white-space: nowrap;
    pointer-events: none;
    z-index: 1001;
}

.timeline-hint {
    color: var(--muted-text);
    font-size: var(--font-xs);
}

/* --- Landscape: a strip across the top of the listing --- */
@media (orientation: landscape) {
    .index-page main {
        --timeline-depth: 90px;
    }

    .timeline-tooltip {
        top: 0;
        transform: translateX(-50%);
    }
}

/* --- Portrait: a rail down the side of the listing --- */
@media (orientation: portrait) {
    .index-page main {
        --timeline-depth: 100%;
        --timeline-rail-width: 68px;

        grid-template-columns: minmax(0, 1fr) var(--timeline-rail-width);
        grid-template-areas:
            "controls rail"
            "list     rail"
            "loading  rail";
        align-items: start;
    }

    .timeline-container {
        flex: 1;
        min-height: 0;
        height: auto;
    }

    .timeline-card {
        grid-area: rail;
        /* The rail fills what is left of the viewport under the header; the
           card's own padding and the page gutter come off that height. */
        height: calc(100vh - var(--sticky-offset, 0px) - var(--space-large));
        padding: var(--space-minimal);
    }

    /* There is no room for prose in a 68px column. The heading stays in the
       document for the outline and the screen reader; the gestures are
       explained in the about overlay instead. */
    .timeline-head h1 {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border-width: 0;
    }

    .timeline-summary,
    .timeline-hint {
        display: none;
    }

    .timeline-tooltip {
        /* Hangs off the rail towards the listing, which is to its left. */
        right: calc(100% + var(--space-minimal));
        transform: translateY(-50%);
    }

    .index-page .action-row {
        grid-area: controls;
    }

    .headline-list {
        grid-area: list;
    }

    .index-page .loading {
        grid-area: loading;
    }
}

/* ========================================
   CONTROLS
   ======================================== */
/* A toggle rather than a command: the pill stays neutral like every other
   button and marks its pressed state with the panel surface plus the accent
   border. Recorded in CLAUDE.md section 6 - the reference knows
   .pill-button--copied but no on/off variant. */
.pill-button--active {
    background: var(--panel-bg);
    border-color: var(--accent-primary);
    color: var(--text-strong);
}

.pill-button--active:hover {
    background: var(--accent-hover);
    border-color: var(--accent-primary);
}

/* The filter dialog's own controls, below its option list. */
.filter-actions {
    margin-bottom: var(--space-medium);
}

/* ========================================
   STACKED FLOATING BUTTON
   frontend-design.md 6 sanctions stacking further floating buttons above the
   info button; this is one slot up from it. It deliberately shares the info
   button's box and its reversed hover - panel-bg going to panel-alt-bg -
   because both sit on the page rather than inside a panel.
   ======================================== */
.floating-stack-button {
    position: fixed;
    right: var(--floating-button-offset);
    bottom: calc(var(--floating-button-offset) + var(--floating-button-size)
                 + var(--space-small));
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--floating-button-size);
    height: var(--floating-button-size);
    border: 1px solid var(--frame-border);
    border-radius: 50%;
    background: var(--panel-bg);
    color: var(--muted-text);
    font-size: var(--font-lg);
    cursor: pointer;
    z-index: 2100;
    box-shadow: var(--card-shadow);
}

.floating-stack-button:hover {
    background: var(--panel-alt-bg);
}

/* display: flex above would otherwise win over the hidden attribute. */
.floating-stack-button[hidden] {
    display: none;
}

/* ========================================
   HEADLINE ROWS
   ======================================== */
.headline-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    list-style: none;
}

.headline {
    --headline-padding: var(--space-medium);
    --headline-title-size: var(--font-md);

    display: flex;
    flex-direction: column;
    gap: var(--space-minimal);
    padding: var(--headline-padding);
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-md);
    box-shadow: var(--card-shadow);
    animation: fadeIn var(--transition-slow) var(--ease-out) both;
}

.headline-title {
    font-size: var(--headline-title-size);
    font-weight: 500;
    line-height: 1.3;
}

.headline-meta {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    flex-wrap: wrap;
    font-size: var(--font-sm);
    color: var(--muted-text);
}

.headline-time {
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-xs);
}

/* The source is a state word, not a control - the badge rules apply. */
.headline-source {
    display: inline-block;
    padding: var(--space-minimal) var(--space-small);
    border-radius: var(--radius-pill);
    background: var(--panel-alt-bg);
    color: var(--muted-text);
    font-size: var(--font-xs);
    font-weight: 600;
}

/* A row's trigger for the history dialog. It is a .pill-button like every
   other small command; only the count is project-specific. */
.headline-versions-button {
    flex-shrink: 0;
}

/* Marks a headline read off the article page long after publication: what it
   says is the wording after every rewrite, and the earlier ones are lost. The
   warning pair is the honest colour for it - it is a caveat about the data,
   not a status of the article. */
.headline-origin-badge {
    display: inline-block;
    padding: var(--space-minimal) var(--space-small);
    border-radius: var(--radius-pill);
    background: var(--badge-warn-bg);
    color: var(--badge-warn-text);
    font-size: var(--font-xs);
    font-weight: 600;
}

/* ========================================
   HEADLINE HISTORY
   In a dialog rather than inside the row: the listing pages in both
   directions, and a row that can grow when it is expanded makes prepending
   a batch shift whatever the reader was looking at.
   ======================================== */
.versions-source {
    margin-bottom: var(--space-medium);
    color: var(--muted-text);
    font-size: var(--font-sm);
}

.versions-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    margin-bottom: var(--space-large);
    max-height: var(--list-max-height);
    overflow-y: auto;
    padding: var(--space-small);
    background: var(--surface-muted);
    border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm);
    list-style: none;
}

.version {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--space-small);
    background: var(--card-bg);
    border-radius: var(--radius-sm);
    /* The one accent stripe frontend-design.md section 3 allows down the
       side of a block; it is what makes the list read as a sequence. */
    border-left: var(--border-strong) solid var(--accent-primary);
}

/* The wording in force now, at the top of the list. */
.version:first-child .version-title {
    font-weight: 500;
    color: var(--text-strong);
}

.version-title {
    color: var(--muted-text);
    font-size: var(--font-sm);
}

.version-seen {
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-xs);
    color: var(--muted-text);
}

/* ========================================
   ABOUT OVERLAY FIGURES
   ======================================== */
.about-stats {
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-xs);
}

/* ========================================
   RESPONSIVE BREAKPOINTS
   Hardcoded px: custom properties do not work in media query conditions.
   ======================================== */
@media (max-width: 767px) {
    .headline {
        --headline-padding: var(--space-small);
        --headline-title-size: var(--font-base);
    }

}
