/*
  Quindi design system
  ====================

  Shared look and feel for the Quindi.SmartMaintenance apps, adopted from Quindi.Rfid.Legacy's
  "liquid glass" theme: mint accent on graphite, translucent surfaces over a fixed gradient,
  glowing status lamps, uppercase micro-labels and tabular numerals.

  This file owns the vocabulary every app draws from - tokens, type roles, shell, cards, badges,
  status lamps, buttons. Anything specific to one app's screens belongs in that app's own
  stylesheet, which loads after this one and may build on these tokens.

  Served from an RCL, so paths resolve under _content/Quindi.SmartMaintenance.Ui/.
  Fonts are self-hosted: these are offline-first PWAs and a service worker can only cache
  same-origin assets. Both families are SIL Open Font License.
*/

/* ---------------------------------------------------------------- fonts */

@font-face {
    font-family: "Hanken Grotesk";
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("../fonts/hanken-grotesk-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
        U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Hanken Grotesk";
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url("../fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
        U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Spline Sans Mono";
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url("../fonts/spline-sans-mono-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
        U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Spline Sans Mono";
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url("../fonts/spline-sans-mono-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
        U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}
/* ---------------------------------------------------------------- tokens */

:root {
    --primary: #1cd685;
    --primary-dark: #36b084;
    --danger: #e05151;
    --warning: #e5b364;
    --info: #51e0cf;
    --accent-soft: rgba(28, 214, 133, 0.14);

    --bg-0: #0c1014;
    --bg-1: #121820;
    --surface: rgba(255, 255, 255, 0.04);
    --surface-2: rgba(255, 255, 255, 0.06);
    --border: rgba(255, 255, 255, 0.09);
    --border-strong: rgba(255, 255, 255, 0.16);

    --text-primary: rgba(255, 255, 255, 0.90);
    --text-secondary: rgba(255, 255, 255, 0.62);
    --text-muted: rgba(255, 255, 255, 0.42);

    --radius: 14px;
    --font-sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "Spline Sans Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

    color-scheme: dark;
}

* {
    box-sizing: border-box;
}

html {
    margin: 0;
    min-height: 100%;
    background: var(--bg-0);
}

body {
    margin: 0;
    height: 100dvh;
    overflow: hidden;
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.45;
    color: var(--text-primary);
    /* The mint glow sits top-right and stays put while the roster scrolls under it. */
    background:
        radial-gradient(1200px 700px at 80% -10%, rgba(28, 214, 133, 0.08), transparent 60%),
        linear-gradient(160deg, var(--bg-1), var(--bg-0));
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    overscroll-behavior-y: none;
}

button {
    font: inherit;
    color: inherit;
    border: 0;
    background: none;
    cursor: pointer;
}

a {
    color: inherit;
    text-decoration: none;
}

:focus-visible {
    outline: 2px solid rgba(28, 214, 133, 0.52);
    outline-offset: 2px;
}
/* ---------------------------------------------------------------- type roles */

.eyebrow {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--primary);
}

.label {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.text-mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

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

.text-muted {
    color: var(--text-muted);
}
/* ---------------------------------------------------------------- boot screen */

.boot {
    position: fixed;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 1.25rem;
}

.boot__mark {
    width: 2.5rem;
    height: 2.5rem;
    border: 2px solid var(--border-strong);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}

.boot__legend {
    margin: 0;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

@keyframes spin {
    to {
        transform: rotate(1turn);
    }
}
/* ---------------------------------------------------------------- shell */

/*
  Header and capture dock are rows of the page grid, not floating layers: the roster between them
  is the only thing that scrolls. That keeps the record button planted while the list moves under
  the thumb, and it removes the guesswork of padding the list to clear a fixed element.
*/
.shell {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    height: 100dvh;
    overflow: hidden;
}

.topbar {
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: calc(env(safe-area-inset-top) + 0.7rem) 1rem 0.7rem;
    background: rgba(8, 11, 15, 0.72);
    border-bottom: 1px solid var(--border);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

/* Same brand block as the Legacy sidebar, laid on its side to fit a phone header. */
.brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
}

.brand-mark {
    height: 28px;
    width: auto;
    flex: none;
}

.brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
}

.brand-name {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.topbar__spacer {
    flex: 1;
}

.topbar__back {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.45rem 0.6rem 0.45rem 0;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.topbar__back:active {
    color: var(--primary);
}
/* ---------------------------------------------------------------- status dots */

.status {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.status-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: none;
    background: var(--text-muted);
}

.status-dot.is-ready {
    background: var(--primary);
    box-shadow: 0 0 8px rgba(28, 214, 133, 0.6);
}

.status-dot.is-live {
    background: var(--primary);
    animation: pulse 1.6s infinite;
}

.status-dot.is-fault {
    background: var(--danger);
    box-shadow: 0 0 8px rgba(224, 81, 81, 0.5);
}

@keyframes pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(28, 214, 133, 0.55);
    }
    70% {
        box-shadow: 0 0 0 7px rgba(28, 214, 133, 0);
    }
    100% {
        box-shadow: 0 0 0 0 rgba(28, 214, 133, 0);
    }
}
/* ---------------------------------------------------------------- badges */

.badge {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--surface-2);
    color: var(--text-secondary);
    border: 1px solid var(--border);
    white-space: nowrap;
}

/* Shows the work is moving, inside whatever badge or line it sits in. */
.badge__spinner {
    display: inline-block;
    width: 0.7em;
    height: 0.7em;
    margin-right: 0.4em;
    border: 1.5px solid color-mix(in srgb, currentColor 28%, transparent);
    border-top-color: currentColor;
    border-radius: 50%;
    vertical-align: -0.05em;
    animation: spin 0.8s linear infinite;
}

.transcript__empty .badge__spinner {
    color: var(--primary);
}

.badge-success {
    background: rgba(28, 214, 133, 0.16);
    color: var(--primary);
    border-color: rgba(28, 214, 133, 0.34);
}

.badge-danger {
    background: rgba(224, 81, 81, 0.16);
    color: var(--danger);
    border-color: rgba(224, 81, 81, 0.34);
}

.badge-info {
    background: rgba(81, 224, 207, 0.14);
    color: var(--info);
    border-color: rgba(81, 224, 207, 0.3);
}
/* ---------------------------------------------------------------- glass card */

.glass-card {
    background: linear-gradient(180deg, var(--surface-2), var(--surface));
    border: 1px solid var(--border);
    border-radius: var(--radius);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
    overflow: hidden;
}

.glass-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--border);
}

.glass-card-body {
    padding: 1rem;
}
/* ---------------------------------------------------------------- notices */

.notice {
    padding: 2.5rem 1rem;
    text-align: center;
}

.notice__title {
    margin: 0 0 0.5rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.notice__text {
    margin: 0 auto;
    max-width: 28ch;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.banner {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin: 0.85rem 0 0;
    padding: 0.7rem 0.85rem;
    border: 1px solid rgba(224, 81, 81, 0.28);
    border-radius: 10px;
    background: rgba(224, 81, 81, 0.10);
    color: var(--text-primary);
    font-size: 0.85rem;
    line-height: 1.45;
}

.banner__dismiss {
    margin-left: auto;
    padding: 0 0.2rem;
    color: var(--text-muted);
    flex: none;
}
/* ---------------------------------------------------------------- actions */

.actions {
    display: grid;
    gap: 0.55rem;
    margin: 1.1rem 0 0;
}

/* Glove-friendly: 3rem clears the 44px touch minimum with room to spare. */
.glass-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 3rem;
    padding: 0 1rem;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.9rem;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.glass-btn:active {
    background: var(--surface);
    color: var(--text-primary);
}

.glass-btn:disabled {
    opacity: 0.5;
    cursor: default;
}

.glass-btn--primary {
    background: var(--accent-soft);
    color: var(--primary);
    border-color: rgba(28, 214, 133, 0.34);
}

.glass-btn--primary:active {
    background: rgba(28, 214, 133, 0.22);
    color: var(--primary);
}

.glass-btn--danger {
    color: rgba(255, 180, 180, 0.9);
    border-color: rgba(224, 81, 81, 0.28);
    background: rgba(224, 81, 81, 0.10);
}

.glass-btn--danger:active {
    background: rgba(224, 81, 81, 0.18);
    color: #fff;
}

.btn-spinner {
    width: 0.9rem;
    height: 0.9rem;
    border: 2px solid rgba(255, 255, 255, 0.25);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}
/* ---------------------------------------------------------------- blazor error ui */

#blazor-error-ui {
    display: none;
    position: fixed;
    inset: auto 0 0 0;
    z-index: 100;
    padding: 1rem 1.25rem calc(1rem + env(safe-area-inset-bottom));
    background: var(--danger);
    color: #1a0505;
    font-size: 0.875rem;
    font-weight: 500;
}

#blazor-error-ui .dismiss {
    position: absolute;
    top: 0.75rem;
    right: 1rem;
    cursor: pointer;
}

#blazor-error-ui .reload {
    text-decoration: underline;
}
/* ---------------------------------------------------------------- accessibility */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/*
  Reading measure. Every app's scrolling region and docked bars opt in by carrying .measure,
  so a phone layout stays edge to edge while a tablet keeps the column readable.
*/
@media (min-width: 34rem) {
    .measure {
        max-width: 34rem;
        margin-inline: auto;
    }
}

