/* Global styles. Values come from tokens only: --tropies-boot-* (css/tokens.css, before Blazor starts),
   --tropies-* and --mud-* (Theme/TropiesTheme.cs and Theme/TropiesCssVariables, at runtime). */

html, body {
    margin: 0;
    font-family: var(--tropies-font-family);
    -webkit-tap-highlight-color: transparent;
}

body {
    background: var(--tropies-boot-bg);
    color: var(--tropies-boot-text);
}

:focus-visible {
    outline: var(--tropies-focus-width) solid var(--tropies-color-focus);
    outline-offset: var(--tropies-focus-offset);
}

.tropies-numeric {
    font-variant-numeric: tabular-nums;
}

/* MudBlazor makes an inline tooltip's root an inline-block, so a relative time would wrap as one block inside a line
   of text ("resting · confirmed 25 min ago"). */
.mud-tooltip-root.tropies-relative-time {
    display: inline;
}

.tropies-inline-icon {
    vertical-align: text-bottom;
}

.tropies-battery {
    display: inline-flex;
    align-items: center;
    gap: calc(var(--tropies-space-in-group) / 2);
}

.tropies-code {
    font-family: var(--tropies-font-family-mono);
    font-size: var(--tropies-text-code-size);
}

h1:focus {
    outline: none;
}

#blazor-error-ui {
    background: var(--tropies-boot-error-bg);
    color: var(--tropies-boot-on-error);
    bottom: 0;
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: var(--tropies-space-in-group) var(--tropies-space-between-groups);
    position: fixed;
    width: 100%;
    z-index: 2000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: var(--tropies-space-between-groups);
        top: var(--tropies-space-in-group);
    }

.blazor-error-boundary {
    background: var(--tropies-boot-error-bg);
    padding: var(--tropies-space-between-groups);
    color: var(--tropies-boot-on-error);
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: var(--tropies-boot-loader-size);
    height: var(--tropies-boot-loader-size);
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: var(--tropies-boot-track);
        stroke-width: var(--tropies-boot-loader-stroke);
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--tropies-boot-progress);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray var(--tropies-boot-loader-transition) ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + var(--tropies-boot-loader-text-offset)) 0 auto 0;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* A full-screen map page fills the main content below the app bar, without the container's width and padding. */
.mud-main-content:has(.tropies-map-page) {
    display: flex;
    flex-direction: column;
    height: 100dvh;
}

.mud-main-content:has(.tropies-map-page) > .mud-container {
    position: relative;
    flex: 1;
    max-width: none;
    padding: 0 !important;
}

/* The map screen's keyboard wrapper (Escape returns to all dogs) must not become a box between the page and the map. */
.tropies-map-screen {
    display: contents;
}

.tropies-map-page {
    position: absolute !important;
    inset: 0;
}

/* Its own stacking context keeps the error and loading overlays (z-index 3) inside the map, so a screen's panel
   beside it stays on top while the map fails (screen map G12). */
.tropies-map {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.tropies-map__canvas,
.tropies-map__overlay {
    position: absolute;
    inset: 0;
}

/* Above MapLibre's control containers (z-index 2), so a stale attribution doesn't show over the error state. */
.tropies-map__overlay {
    z-index: 3;
}

.tropies-map__message {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--tropies-space-between-groups);
}

.tropies-map__controls {
    position: absolute;
    top: calc(var(--tropies-space-map-inset) + env(safe-area-inset-top));
    right: calc(var(--tropies-space-map-inset) + env(safe-area-inset-right));
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--tropies-space-in-group);
}

/* Primitives: where Tropies differs from MudBlazor's defaults. Each rule's decision is listed in
   src/Tropies.Web.Stories/POSTEP.md ("Stage 2 – how the primitives differ") and on the component's page. */
.mud-ripple-effect {
    display: none;
}

.mud-button-root.mud-button {
    min-height: var(--tropies-button-height);
    padding-inline: var(--tropies-space-between-groups);
}

.mud-button-root.mud-button-text {
    padding-inline: var(--tropies-space-in-group);
}

.mud-button-filled,
.mud-button-filled:hover,
.mud-button-filled:focus-visible,
.mud-button-filled:active {
    box-shadow: none;
}

.mud-button-outlined.mud-button-outlined-default {
    border-color: var(--tropies-color-border-input);
}

.mud-button-filled.mud-button-filled-primary:active {
    background-color: color-mix(in srgb, var(--mud-palette-primary-darken) 80%, var(--mud-palette-black));
}

.mud-button-outlined:active,
.mud-button-text:active,
.mud-icon-button:active {
    background-color: color-mix(in srgb, currentColor 16%, transparent);
}

.mud-input {
    font-weight: var(--tropies-text-body-weight);
}

.mud-input > input.mud-input-root-outlined,
.mud-input > textarea.mud-input-root-outlined,
div.mud-input-slot.mud-input-root-outlined {
    padding: var(--tropies-input-padding-block) var(--tropies-input-padding-inline);
    line-height: var(--tropies-text-body-line-height);
}

.mud-input > input:focus-visible,
.mud-input > textarea:focus-visible {
    outline: none;
}

/* The label sits above the field in the normal flow, so a long label wraps instead of being cut off (Q6). */
.mud-input-control.mud-input-outlined-with-label > .mud-input-control-input-container {
    display: flex;
    flex-direction: column-reverse;
    gap: var(--tropies-space-in-group);
}

.mud-input-control > .mud-input-control-input-container > .mud-input-label-outlined.mud-input-label-inputcontrol,
.mud-shrink ~ label.mud-input-label.mud-input-label-inputcontrol.mud-input-label-outlined,
.mud-input:focus-within ~ label.mud-input-label.mud-input-label-inputcontrol.mud-input-label-outlined {
    position: static;
    transform: none;
    max-width: 100%;
    padding: 0 !important;
    white-space: normal;
    overflow: visible;
    font-size: var(--tropies-text-label-size);
    font-weight: var(--tropies-text-label-weight);
    line-height: var(--tropies-text-label-line-height);
}

.mud-input > textarea.mud-input-root-outlined {
    margin-top: 0;
}

.mud-input.mud-input-outlined.mud-shrink > .mud-input-outlined-border legend,
.mud-input.mud-input-outlined:focus-within > .mud-input-outlined-border legend,
.mud-input.mud-input-outlined:focus-within .mud-shrink > .mud-input-outlined-border legend {
    width: 0;
    padding: 0;
}

.mud-input-adornment .mud-icon-button {
    padding: var(--tropies-space-in-group);
}

.mud-input-control-helper-container {
    padding-inline: 0 !important;
}

.mud-checkbox .mud-checkbox-true.mud-default-text {
    color: var(--mud-palette-primary);
}

.mud-checkbox .mud-icon-button:has(input:focus-visible) {
    outline: var(--tropies-focus-width) solid var(--tropies-color-focus);
    outline-offset: calc(var(--tropies-focus-offset) * -1);
}

.mud-input-helper-text {
    font-size: var(--tropies-text-secondary-size);
    line-height: var(--tropies-text-secondary-line-height);
    letter-spacing: normal;
}

.mud-input > input.mud-input-root::placeholder,
.mud-input > textarea.mud-input-root::placeholder {
    color: var(--tropies-color-text-muted);
    opacity: 1;
}

.mud-chip {
    border-radius: var(--tropies-radius-control);
    font-size: var(--tropies-text-secondary-size);
}

.mud-chip.mud-chip-size-small {
    height: auto;
    padding: calc(var(--tropies-space-in-group) / 2) var(--tropies-space-in-group);
    border-radius: var(--tropies-radius-control);
    font-size: var(--tropies-text-secondary-size);
    line-height: var(--tropies-text-secondary-line-height);
}

.mud-avatar.mud-avatar-filled-default {
    background-color: var(--tropies-color-divider);
    color: var(--tropies-color-text);
    border: 1px solid var(--tropies-color-border-input);
}

.mud-tooltip.mud-tooltip-default {
    background-color: var(--tropies-color-text);
    color: var(--tropies-color-surface);
    font-size: var(--tropies-text-secondary-size);
    font-weight: var(--tropies-text-secondary-weight);
    line-height: var(--tropies-text-secondary-line-height);
}

.mud-tooltip.mud-tooltip-default.mud-tooltip-arrow::after {
    border-color: var(--tropies-color-text) transparent transparent transparent;
}

.tropies-panel-floating {
    border-radius: var(--tropies-radius-sheet);
}

.mud-alert {
    padding: var(--tropies-space-in-group) var(--tropies-space-between-groups);
}

.mud-snackbar {
    box-shadow: var(--tropies-elevation-float);
}

.mud-snackbar.mud-alert-filled-normal {
    background-color: var(--tropies-color-text);
    color: var(--tropies-color-surface);
    font-weight: var(--tropies-text-body-weight);
}

@media (prefers-reduced-motion: reduce) {
    .mud-skeleton-wave::after,
    .mud-skeleton-pulse {
        animation: none;
    }

    /* MudBlazor sets the snackbar fade as an inline style and removes the snackbar on the transition's end event:
       !important overrides the style, and 1 ms instead of none keeps the end event firing (DS-P13, D02). */
    .mud-snackbar {
        transition-duration: 1ms !important;
        animation-duration: 1ms !important;
    }
}

.mud-stepper .mud-step-label-icon:not(.mud-primary) {
    background-color: var(--tropies-color-text-muted);
    color: var(--tropies-color-surface);
}

.mud-alert .mud-alert-position {
    align-items: center;
}

/* Dog marker on the map (REF-R01.12): the body in the text color with a contrasting ring, the avatar initial inside.
   Stale positions are dimmed and carry a warning badge, so the state never depends on color alone (B03). With several
   dogs the body takes the dog's color and the surface ring keeps it apart from any base layer; the markers beside a
   focused dog are smaller, never dimmed (all dogs on the map spec, D6, D9). */
.tropies-marker {
    width: var(--tropies-button-height);
    height: var(--tropies-button-height);
    border-radius: var(--tropies-radius-round);
}

.tropies-marker--selectable {
    cursor: pointer;
}

.tropies-marker:focus-visible {
    outline: var(--tropies-focus-width) solid var(--tropies-color-focus);
    outline-offset: var(--tropies-focus-offset);
}

.tropies-marker--small {
    width: calc(var(--tropies-button-height) * 0.75);
    height: calc(var(--tropies-button-height) * 0.75);
}

.tropies-marker__pin {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border-radius: var(--tropies-radius-round) var(--tropies-radius-round) 0 var(--tropies-radius-round);
    transform: rotate(45deg);
    background: var(--tropies-marker-color, var(--tropies-map-marker-fill));
    border: var(--tropies-map-marker-ring-width) solid var(--tropies-map-marker-ring);
    box-shadow: var(--tropies-elevation-float);
}

.tropies-marker__initial {
    display: inline-block;
    transform: rotate(-45deg);
    color: var(--tropies-map-marker-ring);
    font-weight: var(--tropies-text-name-weight);
    font-size: var(--tropies-text-name-size);
}

.tropies-marker--colored .tropies-marker__initial {
    color: var(--tropies-color-on-dog);
}

.tropies-marker--small .tropies-marker__initial {
    font-size: var(--tropies-text-label-size);
}

.tropies-marker--stale .tropies-marker__pin {
    opacity: 0.6;
}

.tropies-marker__badge {
    display: none;
}

.tropies-marker--stale .tropies-marker__badge {
    position: absolute;
    top: calc(var(--tropies-space-in-group) * -1);
    right: calc(var(--tropies-space-in-group) * -1);
    display: grid;
    place-items: center;
    width: calc(var(--tropies-space-in-group) * 2.5);
    height: calc(var(--tropies-space-in-group) * 2.5);
    border-radius: var(--tropies-radius-round);
    background: var(--tropies-color-state-warning);
    color: var(--tropies-color-surface);
    font-weight: var(--tropies-text-label-weight);
    font-size: var(--tropies-text-label-size);
}

/* Map panel: a bottom sheet on phones (REF-R01.1, REF-R01.10), a floating panel from the md breakpoint (REF-R02.1, REF-R02.3). */
.tropies-map-panel {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 2;
    background: var(--tropies-color-surface);
    border-radius: var(--tropies-radius-sheet) var(--tropies-radius-sheet) 0 0;
    box-shadow: var(--tropies-elevation-float);
    padding: 0 var(--tropies-space-panel) calc(var(--tropies-space-panel) + env(safe-area-inset-bottom));
}

.tropies-map-panel__handle {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    min-height: var(--tropies-space-between-sections);
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}

.tropies-map-panel__grip {
    width: var(--tropies-sheet-handle-width);
    height: var(--tropies-sheet-handle-height);
    border-radius: var(--tropies-radius-round);
    background: var(--tropies-color-border-input);
}

@media (min-width: 960px) {
    /* At the top left (REF-R02.1); the dog list replaced the dog pill above it (all dogs on the map spec). */
    .tropies-map-panel {
        inset: var(--tropies-space-map-inset) auto auto var(--tropies-space-map-inset);
        width: calc(var(--tropies-content-max-width-form) * 0.75);
        border-radius: var(--tropies-radius-sheet);
        padding: var(--tropies-space-panel);
    }

    .tropies-map-panel__handle {
        display: none;
    }
}

/* The dog list in the map panel (all dogs on the map spec, D2, D13): at most 60 % of the map's height, scrolling inside. */
.tropies-map-panel:has(.tropies-dog-list) {
    max-height: 60%;
    overflow-y: auto;
}

.tropies-dog-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.tropies-dog-list__heading {
    margin-bottom: var(--tropies-space-in-group);
}

.tropies-dog-row {
    display: flex;
    align-items: center;
    gap: var(--tropies-space-between-groups);
    width: 100%;
    min-height: var(--tropies-button-height);
    padding: var(--tropies-space-in-group) 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: start;
    cursor: pointer;
    border-radius: var(--tropies-radius-control);
}

.tropies-dog-row:focus-visible {
    outline: var(--tropies-focus-width) solid var(--tropies-color-focus);
    outline-offset: var(--tropies-focus-offset);
}

.tropies-dog-avatar {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: calc(var(--tropies-button-height) * 0.75);
    height: calc(var(--tropies-button-height) * 0.75);
    border-radius: var(--tropies-radius-round);
    color: var(--tropies-color-on-dog);
    font-weight: var(--tropies-text-label-weight);
    font-size: var(--tropies-text-label-size);
}

.tropies-dog-row__main {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.tropies-dog-row__side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--tropies-space-in-group);
    text-align: end;
}

.tropies-dog-row__status {
    display: inline-flex;
    align-items: center;
    gap: var(--tropies-space-in-group);
}

.tropies-dog-row__skeleton {
    width: calc(var(--tropies-button-height) * 1.5);
}

/* Bottom tab bar on phones (REF-R01.1); the side menu takes over from the md breakpoint (REF-R02.2). */
.tropies-tab-bar {
    display: flex;
    background: var(--tropies-color-surface);
    border-top: 1px solid var(--tropies-color-divider);
    padding-bottom: env(safe-area-inset-bottom);
}

.tropies-tab-bar__item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(var(--tropies-space-in-group) / 2);
    min-height: calc(var(--tropies-button-height) + var(--tropies-space-in-group));
    color: var(--tropies-color-text-muted);
    font-size: var(--tropies-text-label-size);
    font-weight: var(--tropies-text-label-weight);
    text-decoration: none;
}

.tropies-tab-bar__item--active {
    color: var(--tropies-color-action);
}

@media (min-width: 960px) {
    .tropies-tab-bar {
        display: none;
    }
}

.tropies-app-tab-bar {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: var(--mud-zindex-appbar);
}

/* The bar's height: an item plus the 1 px divider above it. scroll-padding keeps focused and scrolled-to controls,
   with their focus ring, above the fixed bar (WCAG 2.4.11). */
@media (max-width: 959.98px) {
    html {
        --tropies-tab-bar-space: calc(var(--tropies-button-height) + var(--tropies-space-in-group) + 1px + env(safe-area-inset-bottom));
        scroll-padding-bottom: calc(var(--tropies-tab-bar-space) + var(--tropies-space-in-group));
    }

    .tropies-main {
        padding-bottom: var(--tropies-tab-bar-space);
    }
}

