﻿/* ============================================================================
   HotelTRS shared utilities

   Three components that are dropped into other people's screens - the file
   picker, the full-screen loading overlay and the avatar. Being shared is
   exactly what made their <style> blocks dangerous, because a <style> in a
   .razor file is not scoped to anything: it is a global stylesheet that
   happens to appear and disappear with the component.

   Four things were wrong, and all four are the same mistake:

   1. InputFileComponent styled the bare element selector input[type="file"].
      For as long as that component was on screen, EVERY file input in the
      application was display:none.

   2. It also overrode the bare Bootstrap classes .card-img, .card-img-bottom
      and .card-img-top, so every Bootstrap card image in the app changed size
      behaviour while an upload control happened to be mounted.

   3. LoadingOverlay and ProfileImage each defined @keyframes spin, and they
      are not the same animation. Keyframe names are global and the last
      definition in the document wins, so which spin a loader got depended on
      which of the two components rendered most recently.

   4. Both spinners were painted #003951 - a navy that is not even the old
      brand colour (#003665), so it survived the rebrand sweep by being a
      different wrong value.

   The named colours in here were invisible to the ratchet too: it counts hex
   literals, and darkblue, darkgray, black, white, lightgray and purple are
   not hex.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   SPIN

   One definition, one name, used by both spinners below.
   ---------------------------------------------------------------------------- */

@keyframes trs-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ----------------------------------------------------------------------------
   FILE PICKER

   The native input is hidden and driven by a <label for>, so it has to stay in
   the DOM. Scoping the rule to the wrapper is what stops it hiding every other
   file input in the app.
   ---------------------------------------------------------------------------- */

.trs-file-picker input[type="file"] {
    display: none;
}

.trs-file-upload-btn {
    display: inline-block;
    padding: var(--trs-space-2) var(--trs-space-4);
    border: 1px solid var(--trs-fill);
    border-radius: var(--trs-radius-sm);
    color: var(--trs-on-primary);
    font-weight: var(--trs-weight-medium);
    text-align: center;
    cursor: pointer;
}

.trs-file-gallery {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
}

.trs-file-gallery > div {
    margin: var(--trs-space-4) var(--trs-space-2);
    border: 1px solid var(--trs-border-strong);
    border-radius: var(--trs-radius-sm);
}

.trs-file-gallery img {
    max-width: 100%;
    max-height: 100%;
    height: auto;
    object-fit: contain;
}

.trs-file-header {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--trs-space-2);
    width: 200px;
    padding: var(--trs-space-2);
    text-align: center;
}

/* Fixed height because file names run long and the tiles have to stay level. */
.trs-file-name {
    height: 3em;
    padding-left: var(--trs-space-4);
    overflow: hidden;
    word-break: break-all;
    text-align: center;
    font-weight: var(--trs-weight-medium);
    color: var(--trs-text-primary);
}

.trs-file-thumb {
    display: flex;
    width: 200px;
    height: 150px;
    padding: 0 var(--trs-space-4);
    margin-bottom: var(--trs-space-4);
}

/* The placeholder glyph for a non-image attachment fills the tile. */
.trs-file-thumb > i {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    font-size: 5em;
}

/* Blazorise CardImage renders Bootstrap's .card-img-top. Scoped to the tile so
   it is a thumbnail rule and not an app-wide one. */
.trs-file-thumb .card-img,
.trs-file-thumb .card-img-bottom,
.trs-file-thumb .card-img-top {
    flex-shrink: initial;
    width: auto;
}

.trs-file-thumb .card-img-top {
    width: 100%;
    height: auto;
    object-fit: contain;
    cursor: pointer;
}

/* File types with no brand colour of their own - plain text, database. */
.trs-file-icon--neutral {
    color: var(--trs-text-secondary);
}

/* ----------------------------------------------------------------------------
   LOADING OVERLAY
   ---------------------------------------------------------------------------- */

.trs-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.trs-overlay--blocking {
    background: var(--trs-bg);
    opacity: .5;
    z-index: 100;
}

.trs-overlay-body {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.trs-overlay-body span {
    position: absolute;
    top: 45%;
    left: 45%;
}

/* Pulls the wordmark into the middle of the ring it is sitting behind. */
.trs-overlay-logo {
    margin-top: -60%;
    margin-left: -45%;
}

.trs-spinner {
    position: relative;
    width: 60px;
    height: 60px;
    border: 10px solid var(--trs-border);
    border-top: 10px solid var(--trs-fill);
    border-radius: 50%;
    animation: trs-spin 1200ms linear infinite;
}

/* ----------------------------------------------------------------------------
   AVATAR

   Driven by the TrsAvatar component, which is where the size modifiers finally
   got their callers. Three levels of content sit inside the same circle - a
   photo, initials, or an icon - so the holder centres its child rather than
   carrying a background-image, which is what it did when ProfileImage was
   building `background-image: url(...)` inline.
   ---------------------------------------------------------------------------- */

.trs-avatar {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
    width: 2.5rem;
    min-width: 2.5rem;
    height: 2.5rem;
    margin: 0;
    border: 1px solid var(--trs-border);
    border-radius: 50%;
    font-size: var(--trs-text-sm);
}

.trs-avatar--sm {
    width: 1.2rem;
    min-width: 1.2rem;
    height: 1.2rem;
    font-size: var(--trs-text-2xs);
}

.trs-avatar--md {
    width: 3rem;
    min-width: 3rem;
    height: 3rem;
    font-size: var(--trs-text-base);
}

.trs-avatar--lg {
    width: 5rem;
    min-width: 5rem;
    height: 5rem;
    font-size: var(--trs-text-xl);
}

.trs-avatar--xl {
    width: 8rem;
    min-width: 8rem;
    height: 8rem;
    font-size: var(--trs-text-2xl);
}

.trs-avatar--2xl {
    width: 16rem;
    min-width: 16rem;
    height: 16rem;
    font-size: var(--trs-text-3xl);
}

/* The photo fills the circle. object-fit stops a non-square upload from
   stretching, which the old background-size: cover was doing for free. */
/* Laid over the initials or icon rather than replacing them, so a photo that fails to
   load can just hide and reveal what is underneath. */
.trs-avatar-img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.trs-avatar-initials {
    font-weight: var(--trs-weight-semibold);
    line-height: 1;
    text-transform: uppercase;
    user-select: none;
}

.trs-avatar-icon {
    line-height: 1;
}

/* Tints for the two fallbacks only - a photo covers the ground, so tinting
   behind one would show as a rim. Each pair is a --trs-*-bg with its matching
   foreground, so both flip with the theme. */
.trs-avatar--tone-neutral {
    background: var(--trs-surface-sunken);
    color: var(--trs-text-secondary);
}

.trs-avatar--tone-primary {
    background: var(--trs-p-100);
    color: var(--trs-text-primary);
}

.trs-avatar--tone-success {
    background: var(--trs-success-bg);
    color: var(--trs-success);
}

.trs-avatar--tone-info {
    background: var(--trs-info-bg);
    color: var(--trs-info);
}

.trs-avatar--tone-warning {
    background: var(--trs-warning-bg);
    color: var(--trs-warning);
}

.trs-avatar--tone-danger {
    background: var(--trs-danger-bg);
    color: var(--trs-danger);
}

