/* HRTFinator site components.
 *
 * Rule for this file: every element is one HRTFinator already draws. The
 * window shell, the section-header band, the tile outline, the toolButton,
 * the status bar. Nothing is invented; where the site needs something the app
 * has no equivalent for, it reuses the nearest real element instead.
 */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    background: var(--bg-window);
}

body {
    margin: 0;
    padding: 0;
    height: 100vh;
    overflow: hidden;
    background: var(--bg-window);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: var(--size-body);
    font-weight: var(--weight-normal);
    line-height: 1.5;
    /* The app runs without font smoothing tricks; don't add any. */
}

/* ── Window shell ────────────────────────────────────────────────────────────
 * WindowChrome.cpp: the whole client rect is filled with the window
 * background and enclosed by a one-pixel theme border drawn inside the
 * bounds. Header, content, status bar stack inside that inset.
 *
 * The shell owns the viewport and does not scroll. Only .content scrolls, so
 * the title bar and status bar stay put — the same as an app window, where
 * neither bar moves when a panel's contents do.
 */

.window {
    height: 100vh;
    background: var(--bg-window);
    border: var(--window-outline-thickness) solid var(--window-outline);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* ── Title bar ─────────────────────────────────────────────────────────────── */

.titlebar {
    display: flex;
    align-items: stretch;
    height: var(--titlebar-height);
    background: var(--section-header-bg);
    border-bottom: var(--outline-thickness) solid var(--outline);
    flex: none;
}

.titlebar__title {
    display: flex;
    align-items: center;
    padding: 0 var(--panel-padding);
    font-size: var(--size-window-title);
    font-weight: var(--weight-bold);
    color: var(--text-primary);
    white-space: nowrap;
}

.titlebar__drag {
    flex: 1 1 auto;
}

/* ── Tab bar ─────────────────────────────────────────────────────────────────
 * TabBar.cpp, faithfully: the tabs divide the full bar width equally
 * (windowW / tabCount), each filled flat with tabColorA, labelled in the Tab
 * font role, centred.
 *
 * The bar owns ONE shared frame plus one-pixel interior separators. Bordering
 * each tab independently would overlap adjacent edges into a two-pixel rule —
 * the comment in TabBar.cpp calls this out by name. The divider below the bar
 * is separate from that frame so content begins after exactly one pixel.
 */

.tabbar {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    height: var(--tabbar-height);
    background: var(--tab-bar-bg);
    border: var(--outline-thickness) solid var(--outline);
    border-bottom: 0;
    box-shadow: inset 0 calc(-1 * var(--outline-thickness)) 0 var(--outline);
    flex: none;
}

.tab {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px; /* FramePadding.x */
    border: 0;
    background: var(--tab-fill);
    color: var(--tab-inactive-text);
    font-family: var(--font-body);
    font-size: var(--size-tab);
    font-weight: var(--weight-bold);
    line-height: 1;
    cursor: pointer;
}

.tab + .tab {
    border-left: var(--outline-thickness) solid var(--outline);
}

.tab:hover {
    background-image: linear-gradient(var(--tab-hover-overlay),
                                      var(--tab-hover-overlay));
}

.tab:active {
    background-image: linear-gradient(var(--tab-pressed-overlay),
                                      var(--tab-pressed-overlay));
}

.tab[aria-selected="true"] {
    color: var(--tab-active-text);
}

/* The accent indicator sits inside the bar along the active tab's bottom
 * edge, tabIndicatorH tall. */
.tab[aria-selected="true"]::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--tab-indicator-height);
    background: var(--accent);
}

/* ── Content ─────────────────────────────────────────────────────────────────
 * The only scrolling region. The window frame stays full-bleed; each tab's
 * content sits in a centred column inside it.
 */

.content {
    flex: 1 1 auto;
    overflow-y: auto;
}

/* Rows stretch rather than hug their content, so a tile and the screenshot
 * beside it are the same height and the two product rows agree with each
 * other. --row-height is the floor; a row grows if its text needs more. */
.tabpanel {
    max-width: var(--column-width);
    margin: 0 auto;
    padding: var(--content-pad-y) var(--content-pad-x);
    display: grid;
    grid-template-columns: minmax(0, var(--tile-width)) minmax(0, 1fr);
    grid-auto-rows: minmax(var(--row-height), auto);
    align-items: stretch;
    gap: var(--content-gap);
}

.tabpanel[hidden] {
    display: none;
}

/* ── Tile ────────────────────────────────────────────────────────────────────
 * The MEASUREMENTS / TARGETS / EQ BANDS panels: a panel-background body
 * topped by a section-header band.
 *
 * Now that the panels are separated by real gaps there are no shared edges to
 * double up, so each tile carries its own outline again.
 */

.tile {
    background: var(--bg-panel);
    border: var(--outline-thickness) solid var(--outline);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.tile__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--panel-padding);
    padding: 4px var(--panel-padding);
    background: var(--section-header-bg);
    border-bottom: var(--outline-thickness) solid var(--outline);
    font-size: var(--size-section-header);
    font-weight: var(--weight-bold);
    color: var(--section-header-fg);
    text-transform: uppercase;
    flex: none;
}

.tile__body {
    padding: var(--panel-padding);
    display: flex;
    flex-direction: column;
    gap: var(--panel-padding);
    flex: 1 1 auto;
    min-height: 0;
}

.tile__price {
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: var(--size-list-meta);
    text-transform: none;
    white-space: nowrap;
}

.platform-downloads {
    display: flex;
    flex-direction: column;
    gap: var(--panel-padding);
}

.download-subheader {
    margin: 0;
    padding: 0;
    height: var(--subheader-height);
    display: flex;
    align-items: center;
    background: var(--subheader-bg);
    border: 0;
    color: var(--subheader-text);
    font-size: var(--size-section-header);
    line-height: 1;
    letter-spacing: var(--subheader-tracking);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
}

/* The download is drawn as an installed row from the Measurements tab
 * (gradientListItem, two-line): bold name top-left, a textDisabled sub-label
 * under it, and a textSecondary side value in the bottom-right corner. */
.download-row {
    position: relative;
    display: block;
    height: var(--row-height-two-line);
    padding: calc(6px * var(--ui-scale)) var(--panel-padding) 0;
    background: linear-gradient(to right,
                                var(--row-installed-dark) var(--row-fade-start),
                                var(--row-installed-bright));
    border: var(--outline-thickness) solid var(--outline);
    color: var(--text-primary);
    text-decoration: none;
    line-height: 1;
}

.download-row:hover {
    background: linear-gradient(var(--row-hover-overlay), var(--row-hover-overlay)),
                linear-gradient(to right,
                                var(--row-installed-dark-hover) var(--row-fade-start),
                                var(--row-installed-bright-hover));
}

.download-row:focus-visible {
    outline: var(--outline-thickness) solid var(--accent);
    outline-offset: 1px;
}

.download-row__name {
    display: block;
    font-size: var(--size-body);
    font-weight: var(--weight-bold);
}

.download-row__sub,
.download-row__side {
    position: absolute;
    bottom: calc(6px * var(--ui-scale));
    font-family: var(--font-mono);
    font-size: var(--size-list-meta);
}

.download-row__sub {
    left: var(--panel-padding);
    color: var(--text-disabled);
}

.download-row__side {
    right: var(--panel-padding);
    color: var(--text-secondary);
}

.button:disabled {
    opacity: 0.45;
    cursor: default;
}

.tile__body p {
    margin: 0;
}

.tile__body p + p {
    margin-top: var(--panel-padding);
}

/* Cascadia Code, the app's listMeta role — the "gadgetrytech-squig-link"
 * subtitle under a measurement row. */
.meta {
    font-family: var(--font-mono);
    font-size: var(--size-list-meta);
    color: var(--text-secondary);
}

/* ── Buttons ─────────────────────────────────────────────────────────────────
 * toolButton: flat fill, bright one-pixel outline, 3px rounding, fixed
 * height, hover brightens the fill, held darkens it. No gradient, no shadow,
 * no transform. Transitions run at the theme's own 60ms or not at all.
 */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--button-height-tool);
    padding: 0 11px; /* toolButton's minW is text + 22px */
    border: var(--outline-thickness) solid var(--outline);
    border-radius: var(--radius-button);
    background: var(--btn-neutral-fill);
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: var(--size-button);
    font-weight: var(--weight-bold);
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition) linear,
                border-color var(--transition) linear;
}

.button:not(:disabled):hover {
    background: var(--btn-neutral-fill-hover);
}

.button:focus-visible {
    outline: var(--outline-thickness) solid var(--accent);
    outline-offset: 1px;
}

/* The page's two calls to action carry the Apply section's own fills: the
 * green EQ toggle and the blue Corr toggle. Active toolButtons take the
 * lighter text colour. */
.button--cta {
    height: var(--button-height-cta);
    padding: 0 18px;
    color: var(--text-on-fill);
    align-self: flex-start;
}

.button--eq {
    background: var(--eq-fill);
    border-color: var(--eq-edge);
}

.button.button--eq:hover {
    background: var(--eq-fill-hover);
    border-color: var(--eq-edge-hover);
}

.button--eq:active {
    background: var(--eq-fill-held);
}

.button--corr {
    background: var(--corr-fill);
    border-color: var(--corr-edge);
}

.button.button--corr:hover {
    background: var(--corr-fill-hover);
    border-color: var(--corr-edge-hover);
}

.button--corr:active {
    background: var(--corr-fill-held);
}

/* ── Screenshot ──────────────────────────────────────────────────────────────
 * Not a tile. A screenshot is already a picture of the app's own panels, so
 * framing it in another panel would draw a chrome around chrome. It floats on
 * the window background beside the tile it belongs to.
 *
 * Until real images land the well shows the graph background, which is the
 * darkest surface in the theme and reads as an empty plot area rather than as
 * a mocked-up screenshot.
 */

.shot {
    background: var(--graph-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.shot img {
    display: block;
    max-width: 100%;
    height: auto;
}

.shot__placeholder {
    font-family: var(--font-mono);
    font-size: var(--size-list-meta);
    color: var(--text-disabled);
}

/* ── Status bar ──────────────────────────────────────────────────────────────
 * WindowChrome.cpp puts a status bar on the bottom outline, as thick as a
 * tile header band. The app fills it with CPU/GPU/memory telemetry and a
 * version; a web page has no telemetry to report, so it carries the version
 * and the site's links instead.
 */

.statusbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--panel-padding);
    min-height: var(--statusbar-height);
    flex-wrap: wrap;
    padding: 0 var(--panel-padding);
    background: var(--section-header-bg);
    border-top: var(--outline-thickness) solid var(--outline);
    font-family: var(--font-mono);
    font-size: var(--size-list-meta);
    color: var(--section-header-fg);
    flex: none;
}

.statusbar a {
    color: var(--section-header-fg);
    text-decoration: none;
}

.statusbar a:hover {
    color: var(--text-primary);
}

.statusbar__group {
    display: flex;
    align-items: center;
    gap: var(--panel-padding);
    white-space: nowrap;
}

.statusbar__versions {
    margin-left: auto;
}

.statusbar__sep {
    color: var(--text-disabled);
}

/* ── Narrow widths ───────────────────────────────────────────────────────────
 * The app's panels stack when the window narrows past their minimum; so do
 * these. Nothing is hidden, only reflowed.
 */

@media (max-width: 860px) {
    .tabpanel {
        grid-template-columns: minmax(0, 1fr);
    }

    .tab {
        font-size: var(--size-body);
    }

    .tabpanel {
        grid-auto-rows: minmax(200px, auto);
    }
}
