/* =========================================================================
 * OneGrid Web — Components
 * -------------------------------------------------------------------------
 * Buttons, toggle, dropdowns, county cards, tables, discussion panel.
 * Each component maps 1:1 to a widget in the desktop app so the visual
 * signature (rounded shells, header shell in bg_three, id-column shade,
 * horizontal row separators, context blue accents) stays consistent.
 * =======================================================================*/

/* ---------- Icon button ------------------------------------------------
 * Enhancement §3.3: the header buttons themselves are rounded squares
 * that match the header background (`bg_two`). On hover they fade to the
 * cluster fill (`bg_three` in dark, matches OneGrid PyIconButton), and on
 * active-press flash the context blue (mirrors PyPushButton pressed).
 * ---------------------------------------------------------------------- */
.og-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
    color: var(--icon-color);
    transition: background 120ms ease, transform 120ms ease;
}

.og-icon-btn:hover:not(:disabled),
.og-icon-btn:focus-visible:not(:disabled) {
    background: var(--bg-three);
    outline: none;
}

.og-icon-btn:focus-visible {
    box-shadow: var(--shadow-focus);
}

.og-icon-btn:active:not(:disabled) {
    background: var(--context-color);
    transform: translateY(1px);
}

.og-icon-btn:disabled {
    opacity: 0.42;
    cursor: not-allowed;
}

.og-icon-btn img {
    display: block;
    width: 16px;
    height: 16px;
    pointer-events: none;
}

/* Flat variant kept for county-card menu button (does not sit in a cluster). */
.og-icon-btn--flat { width: 30px; height: 30px; border-radius: 6px; }
.og-icon-btn--flat img { width: 16px; height: 16px; }

/* ---------- Button clusters ------------------------------------------- */
/* Enhancement §3.3: the pill behind the header buttons is REMOVED. The
 * clusters remain as inline flex containers so the divider between them
 * still lines up, but they no longer paint a rounded rectangle behind
 * the buttons. */
.og-btn-cluster {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0;
    background: transparent;
    border-radius: 0;
}

.og-btn-cluster--toggle { padding: 0; }

.og-btn-cluster__divider {
    /* Enhancement §3.4: vertical separator in the div_color from OneGrid
     * default.json (#3c4454). */
    width: 1px;
    height: 22px;
    background: var(--header-divider);
    margin: 0 var(--space-2);
    display: inline-block;
}

/* ---------- Theme toggle ----------------------------------------------
 * Enhancement §2: PyQT parity. The moving circle covers whichever icon
 * is on its side, so exactly one icon is visible at rest. The bounce is
 * an `OutBounce`-style cubic keyframe animation.
 * ---------------------------------------------------------------------- */
.og-toggle {
    position: relative;
    display: inline-block;
    /* Enhancement §15: pill widened 20% (52 → 62px). Circle stays 22px;
     * the thumb travel is recomputed below so it still fully covers the
     * icon on whichever side it rests. */
    width: 62px;
    height: 28px;
    padding: 0;
    background: var(--bg-one);
    border: 0;
    border-radius: 14px;
    cursor: pointer;
    overflow: hidden;
    color: inherit;
    transition: background 160ms ease;
    vertical-align: middle;
}

.og-toggle[data-mode="light"] {
    background: var(--context-color);
}

.og-toggle:hover { filter: brightness(1.08); }

.og-toggle:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.og-toggle__icon {
    position: absolute;
    top: 50%;
    width: 14px;
    height: 14px;
    z-index: 1;
    pointer-events: none;
    opacity: 0.95;
    transform: translateY(-50%);
    transition: opacity 120ms ease;
}

.og-toggle__icon--left  { left: 7px; }
.og-toggle__icon--right { right: 7px; }

/* Dark mode (checked=false): thumb at LEFT covers the left icon → only
 * the right (dark_mode) icon is visible. Light mode (checked=true):
 * thumb at RIGHT covers the right icon → only the left (light_mode) icon
 * is visible. */
.og-toggle[data-mode="dark"]  .og-toggle__icon--left  { opacity: 0; }
.og-toggle[data-mode="light"] .og-toggle__icon--right { opacity: 0; }

.og-toggle__thumb {
    position: absolute;
    top: 3px;
    left: 4px;
    width: 22px;
    height: 22px;
    background: var(--icon-color);
    border-radius: 50%;
    z-index: 2;
    /* Enhancement §2.5 — bounce: match PyToggle's OutBounce curve
     * (500 ms). See gui/widgets/py_toggle/py_toggle.py. */
    transition: transform 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.og-toggle[data-mode="light"] .og-toggle__thumb {
    /* §15: travel = pill(62) − left(4) − circle(22) − right-inset(4) = 32px. */
    transform: translateX(32px);
}

/* ---------- Dropdowns (single + multi) --------------------------------
 * Enhancement §1 / §10 — match OneGridComboBox from styled_inputs.py.
 * Fill = `dark_two` to line up EXACTLY with the table-header chrome
 * (previous `bg_one` was one shade too light). Chevron is a standalone
 * rounded-square button positioned inside the picker with its own
 * hover + click states — mirrors the `PyArrowButton` overlay in the
 * PyQT combo box (dark_one/dark_three/context_color states).
 * ---------------------------------------------------------------------- */
.og-picker {
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: relative;
    min-width: 220px;
}

.og-picker__label {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-description);
    letter-spacing: 0.02em;
}

.og-picker__select-wrap {
    position: relative;
}

.og-picker__select,
.og-picker__multiselect {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    min-height: 30px;
    padding: 6px 42px 6px 12px;
    background: var(--dark-two);
    color: var(--text-active);
    font-family: var(--font-family);
    font-size: 12px;
    font-weight: 500;
    border: 2px solid transparent;
    border-radius: var(--radius-shell);
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease;
    text-align: left;
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    line-height: 1.2;
}

.og-picker__select:hover,
.og-picker__multiselect:hover {
    background: var(--dark-three);
}

.og-picker__multiselect[aria-expanded="true"] {
    background: var(--dark-three);
    border-color: var(--context-color);
}

.og-picker__select:focus-visible,
.og-picker__multiselect:focus-visible {
    outline: none;
    border-color: var(--context-color);
    box-shadow: var(--shadow-focus);
}

/* Native <select> options — WebKit lets us style the popup slightly. */
.og-picker__select option {
    background: var(--dark-two);
    color: var(--text-active);
}

.og-picker__select:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Enhancement §10.3: standalone arrow button INSIDE the picker.
 * Mirrors PyArrowButton — rounded rectangle 28×26, sitting flush against
 * the right edge of the picker with its own hover / click states. */
.og-picker__arrow {
    position: absolute;
    top: 50%;
    right: 4px;
    transform: translateY(-50%);
    width: 28px;
    height: 24px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--dark-one);
    border: 0;
    border-radius: 6px;
    cursor: pointer;
    transition: background 120ms ease;
    z-index: 2;
}

.og-picker__arrow:hover { background: var(--dark-three); }

/* Enhancement §10.3: click flashes context blue (mirrors PyArrowButton
 * pressed state and PyPushButton bg_color_pressed). */
.og-picker__arrow:active,
.og-picker__multiselect[aria-expanded="true"] + .og-picker__arrow,
.og-picker__arrow[data-open="true"] {
    background: var(--context-color);
}

.og-picker__arrow:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* The chevron glyph inside the standalone arrow button. */
.og-picker__chevron {
    pointer-events: none;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--icon-color);
    border-bottom: 2px solid var(--icon-color);
    transform: translateY(-2px) rotate(45deg);
    transition: border-color 120ms ease;
}

.og-picker__arrow:hover .og-picker__chevron {
    border-right-color: var(--icon-hover);
    border-bottom-color: var(--icon-hover);
}

.og-picker__arrow:active .og-picker__chevron,
.og-picker__multiselect[aria-expanded="true"] + .og-picker__arrow .og-picker__chevron,
.og-picker__arrow[data-open="true"] .og-picker__chevron {
    border-right-color: var(--white);
    border-bottom-color: var(--white);
}

/* ---------- Multiselect flyout ----------------------------------------
 * Enhancement §10.1: menu fill also drops to `dark_two` for parity with
 * the picker + table header chrome. */
.og-multiselect__menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    background: var(--dark-two);
    border: 1px solid var(--bg-three);
    border-radius: var(--radius-shell);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    box-shadow: var(--shadow-card);
    z-index: 30;
}

.og-multiselect__item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    color: var(--text-active);
    font-size: 12px;
    font-weight: 500;
    border-radius: 6px;
    cursor: pointer;
    user-select: none;
    transition: background 100ms ease, color 100ms ease;
}

/* Enhancement §1.3: row highlight = scrollbar blue; hovered text turns
 * dark_two chrome grey so it reads clearly against the blue fill. */
.og-multiselect__item:hover {
    background: var(--context-color);
    color: var(--text-on-highlight);
}

.og-multiselect__item input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border: 1.5px solid var(--icon-color);
    border-radius: 3px;
    background: transparent;
    cursor: pointer;
    display: inline-grid;
    place-content: center;
    transition: background 120ms ease, border-color 120ms ease;
}

.og-multiselect__item:hover input[type="checkbox"]:not(:checked) {
    border-color: var(--text-on-highlight);
}

.og-multiselect__item input[type="checkbox"]:checked {
    background: var(--context-color);
    border-color: var(--context-color);
}

.og-multiselect__item input[type="checkbox"]:checked::before {
    content: "";
    width: 7px;
    height: 7px;
    background: var(--white);
    clip-path: polygon(14% 44%, 0 60%, 40% 100%, 100% 20%, 84% 8%, 40% 68%);
}

/* ---------- County card -----------------------------------------------
 * Enhancement §11.3: every card enforces a MINIMUM height so a
 * collapsed neighbour never squishes an expanded one, and vice-versa
 * (the reference GUI keeps the container height uniform regardless of
 * how many rows the table has). The value below matches the "full
 * viewport" scenario: 46 (header shell) + 8 (breathing gap) + 34
 * (table header) + 8 * 32 (eight rows) + 24 (padding) ≈ 386 px.
 * ---------------------------------------------------------------------- */
.og-county-card {
    background: var(--bg-two);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: var(--space-3);
    gap: var(--space-2);
    position: relative;
    min-height: 340px; /* Originally 386px */
}

/* Enhancement §4 — semi-transparent brand mark behind the container when
 * the table is collapsed. Only visible when `.is-collapsed` is on;
 * opacity driven by `--collapsed-logo-opacity` (default 25 %). If BOTH
 * columns in a row are collapsed the parent grid strips the surrounding
 * background — the logo is scoped per card so a single collapsed card
 * still shows its brand mark. */
.og-county-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: url("../logos/onegrid_logo_full_web.svg");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 55% auto;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
    z-index: 0;
}

.og-county-card.is-collapsed::before {
    opacity: var(--collapsed-logo-opacity);
}

/* Ensure the county header renders above the backdrop logo. */
.og-county-card__header,
.og-county-card__body {
    position: relative;
    z-index: 1;
}

/* Enhancement §11.6: title + count + collapse button all sit on the same
 * horizontal baseline; padding is now symmetric so the row is truly
 * centred vertically inside the header pill. */
.og-county-card__header {
    background: var(--bg-three);
    border-radius: var(--radius-shell);
    padding: 5px 10px;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 35px;
    /* Enhancement §11.4: extra bottom margin below the header so the
     * table body has a bit more breathing room. */
    margin-bottom: 6px;
}

.og-county-card__title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    color: var(--text-title);
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
}

.og-county-card__count {
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    color: var(--text-description);
    display: inline-flex;
    align-items: center;
}

.og-county-card__body {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1 1 auto;
}

.og-county-card.is-collapsed .og-county-card__body {
    display: none;
}

/* Enhancement §4.3 / §11.3 refined: when BOTH cards in a row are
 * collapsed we drop the backdrop logo AND release the min-height so
 * the row snaps back to just the header pill height. As soon as ONE
 * card in the row re-expands, the pair returns to the uniform 386 px
 * min-height.
 *
 * Enhancement §17: hide the logo INSTANTLY (no fade) the moment the row
 * becomes fully collapsed. Without this, the sibling card's logo would
 * fade over 200ms while the card is already shrinking to header height,
 * producing the "unusual" oversized-logo-over-a-tiny-card flash. The
 * fade-IN when a single card collapses is preserved (that transition
 * lives on the base `::before` rule). */
.og-county-card[data-row-collapsed="true"]::before {
    opacity: 0;
    transition: none;
}

.og-county-card[data-row-collapsed="true"] {
    min-height: 0;
}

/* Enhancement §11.5: the collapse/expand button inherits the exact same
 * hover treatment as the download/logout icon buttons in the header
 * (`bg_three` → active-press `context_color`). The .og-icon-btn base
 * already handles this — the county-specific rule below just makes
 * sure the flat variant plays nicely with the bg_three pill it sits on
 * by hovering to a slightly darker shade so the button "pops". */
.og-county-card__header .og-icon-btn--flat:hover:not(:disabled),
.og-county-card__header .og-icon-btn--flat:focus-visible:not(:disabled) {
    background: var(--dark-four);
}

.og-county-card__header .og-icon-btn--flat:active:not(:disabled) {
    background: var(--context-color);
}

/* ---------- Table -----------------------------------------------------
 * Enhancement §5 / §11.1 — the scrollbar sits INSIDE the table shell,
 * flush against the right edge, and NEVER overlaps the last column.
 * When the row-count fits inside `max-height` there is no scrollbar
 * gutter at all → the table content fills the whole shell width. When
 * the row-count overflows, the browser draws a rounded blue pill in the
 * reserved gutter. This matches the OneGrid Qt table's scrollbar
 * placement (see `onegrid_gui_scrollbars.png` reference).
 * ---------------------------------------------------------------------- */
.og-table-wrap {
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--bg-two);
    border: 1px solid var(--table-outline);
    border-radius: var(--radius-shell);
    /* Viewport cap derived from the tunable table metrics (tokens.css):
     * one header row + N body rows before the scrollbar appears. */
    max-height: calc(
        var(--table-header-height) +
        var(--table-visible-rows) * var(--table-row-height)
    );
    /* No `scrollbar-gutter: stable` — Chromium reserves the gutter only
     * when the content actually overflows, so single-page tables stretch
     * to the full shell width without a phantom gap on the right. */
}

/* Rounded scrollbar chrome scoped to the table wrap (§11.1). The extra
 * padding + border on the thumb centres it inside the 10px gutter and
 * carries the pill shape all the way to the top/bottom of the track. */
.og-table-wrap::-webkit-scrollbar {
    width: 10px;
    background: transparent;
}

.og-table-wrap::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 8px;
    margin: 6px 2px;
}

.og-table-wrap::-webkit-scrollbar-thumb {
    background: var(--context-color);
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
    min-height: 32px;
}

.og-table-wrap::-webkit-scrollbar-thumb:hover {
    background: var(--context-hover);
    background-clip: padding-box;
}

/* Firefox — thin auto scrollbar with the same accents. */
.og-table-wrap {
    scrollbar-color: var(--context-color) transparent;
    scrollbar-width: thin;
}

.og-table {
    width: 100%;
    border-collapse: collapse;
    /* Body-cell text size (tokens.css → --table-row-font-size). */
    font-size: var(--table-row-font-size);
    color: var(--text-foreground);
}

.og-table thead th {
    position: sticky;
    top: 0;
    background: var(--dark-two);
    color: var(--text-active);
    font-weight: 600;
    /* Header text size + row height come from tokens.css. Vertical
     * padding is dropped in favour of an explicit height so the row
     * size is controlled by a single knob; `vertical-align: middle`
     * keeps the label centred. */
    font-size: var(--table-header-font-size);
    height: var(--table-header-height);
    text-align: center;
    vertical-align: middle;
    padding: 0 10px;
    border-bottom: 1px solid var(--table-outline);
    z-index: 1;
}

:root[data-theme="light"] .og-table thead th {
    /* Keep the dark chrome on the header even in light mode (matches
     * OneGrid's baseplate design where the header stays dark). */
    background: var(--dark-two);
    color: var(--white);
}

.og-table tbody td {
    /* Body-row height from tokens.css; horizontal padding only so the
     * height knob fully controls the row size (text centred vertically). */
    height: var(--table-row-height);
    vertical-align: middle;
    padding: 0 10px;
    text-align: center;
    border-bottom: 1px solid var(--table-outline);
    background: var(--bg-two);
    color: var(--text-foreground);
    transition: background 100ms ease, color 100ms ease;
}

.og-table tbody tr:last-child td {
    border-bottom: 0;
}

/* Enhancement §6: entire row (INCLUDING the ID cell) flashes blue on
 * hover; row text darkens to `dark_two` so it reads against the fill. */
.og-table tbody tr:hover td {
    background: var(--context-color);
    color: var(--text-on-highlight);
    font-weight: 600;
}

/* ID column keeps the baseplate grey shade UNLESS the row is hovered
 * (enhancement §6 — hover now overrides the ID column shade too). */
.og-table tbody td.og-table__col-id {
    background: var(--id-column-bg);
    color: var(--id-column-fg);
    font-weight: 600;
}

.og-table tbody tr:hover td.og-table__col-id {
    background: var(--context-color);
    color: var(--text-on-highlight);
    font-weight: 600;
}

/* Unit column mutes on default paint but follows the row highlight. */
.og-table__col-id     { width: 74px; text-align: center; }
.og-table__col-name   { text-align: center; min-width: 130px; }
.og-table__col-value  { width: 96px; text-align: center; }
.og-table__col-unit   { width: 68px; text-align: center; color: var(--text-description); }
.og-table tbody tr:hover td.og-table__col-unit { color: var(--text-on-highlight); }

/* ---------- Discussion panel ------------------------------------------ */
.og-discussion {
    background: var(--bg-two);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.og-discussion__header {
    background: var(--bg-three);
    border-radius: var(--radius-shell);
    padding: 8px 8px;
    display: flex;
    align-items: center;
    min-height: 35px;
    /* Enhancement §18: same header↔body breathing room as the county
     * card (which pairs the parent flex `gap` with a 6px header margin). */
    margin-bottom: 6px;
}

.og-discussion__title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-title);
}

.og-discussion__body {
    background: var(--bg-three);
    border-radius: var(--radius-shell);
    padding: var(--space-4);
    color: var(--text-title);
    font-size: 14px;
    line-height: 1.55;
    max-height: 320px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    /* Enhancement §21.2 / §21.4 — token-driven gap so the subtitle sits
     * flush against the first paragraph AND every subsequent paragraph
     * separation matches the same knob. */
    gap: var(--paragraph-space);
}

.og-discussion__subtitle {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    line-height: var(--eyebrow-line-height);
    color: var(--text-active);
}

.og-discussion__placeholder {
    margin: 0;
    color: var(--text-description);
    font-style: italic;
}

.og-discussion__body p {
    margin: 0;
}

/* ---------- Tooltip pill (Enhancement §19) ---------------------------
 * PyQT parity. Mirrors `gui/widgets/py_icon_button/py_icon_button.py`
 * `_ToolTip.style_tooltip` — dark_one fill, text_foreground copy,
 * 17 px radius, 3 px context blue accent flush against the right edge,
 * matching drop-shadow. Positioned in the viewport via `position: fixed`
 * with JS-driven `left/top` (see `js/tooltip.js`).
 * ---------------------------------------------------------------------- */
.og-tooltip {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 10000;
    min-height: 23px; /* Enhancement §19: reduced from 34px for a more compact tooltip */
    padding: 0 10px;
    background: var(--dark-one);
    color: var(--text-foreground);
    border: 0 solid transparent;
    border-right: 3px solid var(--context-color);
    border-radius: 17px;
    font-family: var(--font-family);
    font-size: 11px;
    font-weight: 700;
    line-height: 23px; /* Enhancement §19: match the reduced min-height for a more compact tooltip */
    letter-spacing: 0.01em;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    transition: opacity 120ms ease;
}

.og-tooltip.is-visible {
    opacity: 1;
    visibility: visible;
}

/* Suppress the pill during PDF export — no floating hints should bleed
 * into the printed copy. */
body.og-pdf-render .og-tooltip { display: none; }

/* ---------- PDF export marker ---------------------------------------- */
/* When html2pdf is generating the export it toggles a class on <body>
 * so we can suppress the header actions in the printed copy.            */
body.og-pdf-render .og-header__actions,
body.og-pdf-render .og-subheader__pickers,
body.og-pdf-render .og-icon-btn--flat {
    visibility: hidden;
}
