/*
 * File: nivelacka.css
 * Description: The survey page — result tiles, entry table, point-by-point mode,
 * map and report. Note: tokens, reset, cards, buttons and overlays are in
 * common.css; the header is in header.css.
 */

/* ========================================
   PAGE
   `main` carries horizontal padding only, so the vertical rhythm is here.
   ======================================== */
.results {
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
    padding: var(--space-large) 0;
    min-width: 0;
}

/* ========================================
   RESULT TILES
   ======================================== */
.kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-small);
}

.kpi {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--space-medium);
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-left: var(--border-strong) solid var(--panel-border);
    border-radius: var(--radius-md);
    box-shadow: var(--card-shadow);
    min-width: 0;
}

/* The accent as a stripe down the side, which is how the system uses it. */
.kpi-accent {
    border-left-color: var(--accent-primary);
}

.kpi-label {
    color: var(--muted-text);
    font-size: var(--font-xs);
    letter-spacing: var(--letter-spacing-sm);
    text-transform: uppercase;
}

.kpi-value {
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-lg);
    font-weight: 500;
    line-height: 1.2;
}

.kpi-note {
    color: var(--muted-text);
    font-size: var(--font-xs);
}

/* ========================================
   WARNINGS
   ======================================== */
.warnings {
    display: flex;
    flex-direction: column;
    gap: var(--space-minimal);
}

.warnings:empty {
    display: none;
}

.warning {
    padding: var(--space-small) var(--space-medium);
    background: var(--badge-warn-bg);
    color: var(--badge-warn-text);
    border-radius: var(--radius-sm);
    font-size: var(--font-sm);
}

/* ========================================
   TABS
   A variant of the neutral button: it carries which panel is showing, which one
   button style cannot express. Recorded in the project's CLAUDE.md.
   ======================================== */
.tabs {
    display: flex;
    gap: var(--space-minimal);
    flex-wrap: wrap;
}

.tab {
    padding: var(--button-padding-block) var(--button-padding-inline);
    min-height: 44px;
    background-color: transparent;
    color: var(--muted-text);
    border: 1px solid transparent;
    transition: background-color var(--transition-fast) var(--ease-out),
                color var(--transition-fast) var(--ease-out);
}

.tab:hover {
    background-color: var(--accent-hover);
    color: var(--text-strong);
}

.tab.is-active {
    background-color: var(--card-bg);
    border-color: var(--card-border);
    color: var(--text-strong);
    font-weight: 500;
}

/* ========================================
   SEGMENTED CONTROL
   The second recorded button variant: a set of mutually exclusive views, where
   separate neutral buttons would not show which one is on.
   ======================================== */
.segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 1px;
    padding: 2px;
    background-color: var(--panel-alt-bg);
    border: 1px solid var(--frame-border);
    border-radius: var(--radius-sm);
}

.segmented-button {
    padding: 6px 12px;
    min-height: 32px;
    background-color: transparent;
    color: var(--muted-text);
    border: 0;
    font-size: var(--font-sm);
    transition: background-color var(--transition-fast) var(--ease-out),
                color var(--transition-fast) var(--ease-out);
}

.segmented-button:hover {
    background-color: transparent;
    color: var(--text-strong);
}

.segmented-button.is-active {
    background-color: var(--card-bg);
    color: var(--text-strong);
    font-weight: 500;
}

/* ========================================
   FORM LAYOUT
   ======================================== */
.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-minimal);
    min-width: 0;
}

/* A field only grows inside a row; in a column it would stretch vertically. */
.field-row > .field {
    flex: 1 1 140px;
}

.field-label {
    color: var(--muted-text);
    font-size: var(--font-xs);
    letter-spacing: var(--letter-spacing-sm);
}

.field-row {
    display: flex;
    gap: var(--space-small);
    flex-wrap: wrap;
}

.field input:not([type="checkbox"]),
.field textarea,
.settings-group input:not([type="checkbox"]),
.settings-group textarea {
    width: 100%;
    padding: 8px 10px;
    font-size: var(--font-sm);
}

.check {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    font-size: var(--font-sm);
    cursor: pointer;
}

.check-row {
    display: flex;
    gap: var(--space-medium);
    flex-wrap: wrap;
}

.button-row {
    display: flex;
    gap: var(--space-small);
    flex-wrap: wrap;
}

.button-row > button {
    flex: 1 1 140px;
}

/* Deleting every reading deserves to look unlike the buttons beside it.
   Recorded in the project's CLAUDE.md. */
.button-danger {
    color: var(--badge-danger-text);
}

.button-danger:hover {
    background-color: var(--badge-danger-bg);
}

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

.muted {
    color: var(--muted-text);
}

.badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    background-color: var(--panel-alt-bg);
    color: var(--muted-text);
    font-size: var(--font-xs);
}

.badge.is-done {
    background-color: var(--badge-success-bg);
    color: var(--badge-success-text);
}

/* ========================================
   DIALOGS
   `.floating-message` centres its text, which is right for a one-line notice
   and wrong for a form or a page of instructions.
   ======================================== */
.dialog-wide {
    text-align: left;
}

.settings-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
}

/* Controls that are as wide as their content sit at the left rather than
   stretching across the dialog. */
.settings-group > .segmented,
.settings-group > button {
    align-self: flex-start;
}

/* ========================================
   PANELS
   ======================================== */
.panel {
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
}

/* A card is a plain box, so `hidden` alone would not beat its own display. */
.panel[hidden] {
    display: none;
}

.panel-toolbar {
    display: flex;
    gap: var(--space-medium);
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
}

/* The data buttons sit at the far end, away from the view switches they must
   not be confused with. */
.data-actions {
    display: flex;
    gap: var(--space-small);
    flex-wrap: wrap;
    margin-left: auto;
}

/* ========================================
   ENTRY TABLE
   ======================================== */
.entry-table-wrap {
    overflow: auto;
    max-height: 62vh;
    /* Hugs the table instead of leaving a strip of empty frame beside it. */
    width: max-content;
    max-width: 100%;
    border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm);
}

.entry-table {
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--font-sm);
}

.entry-table th {
    position: sticky;
    z-index: 1;
    background-color: var(--panel-alt-bg);
    color: var(--muted-text);
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-xs);
    font-weight: 500;
    padding: 6px 8px;
    white-space: nowrap;
    border-bottom: 1px solid var(--panel-border);
    border-right: 1px solid var(--panel-border);
}

.entry-table thead th {
    top: 0;
}

.entry-table .entry-axis {
    left: 0;
    z-index: 2;
    text-align: right;
}

.entry-table thead th:first-child {
    z-index: 3;
    left: 0;
}

.entry-cell {
    padding: 0;
    border-bottom: 1px solid var(--panel-border);
    border-right: 1px solid var(--panel-border);
}

.entry-cell input {
    width: 88px;
    min-height: 34px;
    padding: 4px 6px;
    background-color: transparent;
    border: 0;
    border-radius: 0;
    font-family: 'Roboto Mono', monospace;
    text-align: right;
}

.entry-cell input:focus-visible {
    outline-offset: -2px;
}

.entry-cell input[readonly] {
    color: var(--muted-text);
}

/* The cell background carries the height so the table reads as a map too. */
.entry-cell.is-shaded {
    background: var(--cell-shade, transparent);
}

.entry-cell.is-empty input {
    background-color: var(--badge-danger-bg);
}

/* The mark of a point ("okno", "dveře") sits under its value. The row only
   grows once something is actually marked, so an unmarked grid stays compact. */
.entry-mark {
    display: none;
    padding: 0 6px 3px;
    color: var(--accent-link);
    font-size: var(--font-xs);
    line-height: 1.2;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.entry-table.has-marks .entry-mark {
    display: block;
}

/* In the mark editor the cells are text, so they need the room to show it. */
.entry-table.is-marks .entry-cell input {
    width: 130px;
    text-align: left;
    color: var(--accent-link);
}

.entry-table.is-marks .entry-mark {
    display: none;
}

/* ========================================
   POINT-BY-POINT ENTRY
   ======================================== */
.point-entry {
    /* One point at a time reads best in a phone-sized column, whatever the
       screen; the card around it may be far wider. */
    --point-width: 520px;

    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
    width: 100%;
    max-width: var(--point-width);
    align-self: center;
}

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

.point-coords {
    font-family: 'Roboto Mono', monospace;
    font-size: var(--font-md);
}

.point-field input {
    min-height: 64px;
    font-family: 'Roboto Mono', monospace;
    font-size: 32px;
    text-align: center;
}

.point-height {
    text-align: center;
    font-size: var(--font-sm);
}

/* The progress overview is a thumbnail, not a second grid to click through --
   the cells are square, so an unbounded width would make them huge. */
.mini-grid {
    display: grid;
    gap: 2px;
    width: 100%;
    max-width: 340px;
    align-self: center;
}

.mini-cell {
    width: 100%;
    aspect-ratio: 1;
    min-width: 0;
    padding: 0;
    background-color: var(--panel-alt-bg);
    border: 1px solid var(--panel-border);
    border-radius: 2px;
}

.mini-cell.is-measured {
    background-color: var(--accent-primary);
    border-color: var(--accent-primary);
}

.mini-cell.is-current {
    outline: 2px solid var(--text-strong);
    outline-offset: 1px;
}

/* A marked point gets a dot, so the room's landmarks are visible in the
   thumbnail while walking the grid. */
.mini-cell.is-marked::after {
    content: "";
    display: block;
    width: 34%;
    height: 34%;
    margin: 33%;
    border-radius: var(--radius-pill);
    background-color: var(--card-bg);
}

/* ========================================
   MAP
   The canvas is sized in device pixels by the renderer; CSS only stretches it
   to the column width, and the renderer sets the height to match the room.
   ======================================== */
.map-figure {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
}

.map-figure canvas {
    width: 100%;
    display: block;
    background-color: var(--card-bg);
    border-radius: var(--radius-sm);
}

/* ========================================
   REPORT
   ======================================== */
.report {
    display: grid;
    /* Wide enough that a value like "15.2 mm · X 0.493 m, Y 0 m" fits on one line. */
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: var(--space-large);
}

.report-block {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    padding: var(--space-medium);
    background-color: var(--panel-bg);
    border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm);
    min-width: 0;
}

.report-title {
    color: var(--muted-text);
    font-size: var(--font-xs);
    letter-spacing: var(--letter-spacing-sm);
    text-transform: uppercase;
}

.report-rows {
    display: flex;
    flex-direction: column;
    gap: var(--space-minimal);
}

.report-row {
    display: flex;
    gap: var(--space-small);
    justify-content: space-between;
    align-items: baseline;
    font-size: var(--font-sm);
}

.report-row dt {
    color: var(--muted-text);
    min-width: 0;
}

.report-row dd {
    font-family: 'Roboto Mono', monospace;
    text-align: right;
    min-width: 0;
}

/* ========================================
   DATA AND EXPORTS
   ======================================== */
.exports {
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
}

.exports-head {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    flex-wrap: wrap;
}

.exports-head h2 {
    margin-right: auto;
}

.export-links {
    display: flex;
    gap: var(--space-small);
    flex-wrap: wrap;
}

/* ========================================
   HOWTO LISTS
   ======================================== */
.howto {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    font-size: var(--font-sm);
    padding-left: var(--space-large);
    text-align: left;
}

ol.howto {
    list-style: decimal;
}

ul.howto {
    list-style: disc;
}

/* ========================================
   ERROR PAGE
   ======================================== */
.error-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-medium);
    max-width: 520px;
    margin: var(--space-large) auto;
    text-align: center;
}

.error-code {
    font-family: 'Roboto Mono', monospace;
    font-size: 64px;
    line-height: 1;
    color: var(--muted-text);
}

/* ========================================
   SETTINGS HINT
   A single entry animation pointing at where every parameter lives; it runs
   once and never repeats (frontend-design.md §8).
   ======================================== */
.settings-button.is-hinted {
    animation: settings-hint var(--transition-slow) var(--ease-out) both;
}

@keyframes settings-hint {
    50% {
        box-shadow: 0 0 0 4px var(--accent-primary);
    }
}

/* ========================================
   UTILITIES
   Last in the cascade on purpose: every component it hides is declared earlier
   at the same specificity, so no !important is needed.
   ======================================== */
.is-hidden {
    display: none;
}

/* ========================================
   RESPONSIVE BREAKPOINTS
   Hardcoded px: custom properties do not work in media query conditions.
   ======================================== */
@media (max-width: 1199px) {
    .results {
        gap: var(--space-medium);
    }

    .data-actions {
        margin-left: 0;
    }
}

@media (max-width: 767px) {
    .entry-table-wrap {
        max-height: 55vh;
    }

    .entry-cell input {
        width: 74px;
    }

    .panel-toolbar {
        gap: var(--space-small);
    }

    .segmented {
        width: 100%;
    }

    .segmented-button {
        flex: 1 1 auto;
    }

    .data-actions {
        width: 100%;
    }

    .data-actions > button {
        flex: 1 1 140px;
    }

    .export-links > button {
        flex: 1 1 140px;
    }

    .exports-head > button {
        flex: 1 1 100%;
    }
}
