/* =================================================================================================
   GreenLoop Connect

   An operations console, not a marketing site. The people here are either collecting a file they
   were told to collect, or they are an MSP engineer doing the same job for the twentieth time
   today. So: dense but breathable, one accent, borders rather than shadows, and nothing that moves
   unless it is telling you something.

   Every color a customer can change comes from three tokens -- --glc-primary, --glc-accent and
   --glc-header -- which /css/branding.css sets per tenant. Everything derived from them uses
   color-mix() rather than a second hard-coded value, so dropping in a customer palette actually
   changes the product rather than changing three buttons and leaving the rest blue.

   Rules of the house:
     - Never hard-code a brand color below. Mix from a token.
     - Neutrals are cool and slightly desaturated; they are the paper, not the ink.
     - No inline styles anywhere in the views: the CSP is style-src 'self'.
   ============================================================================================== */

:root {
    /* Fallbacks. /css/branding.css overrides these three per tenant. */
    --glc-primary: #1f6feb;
    --glc-accent: #0b7a5a;
    --glc-header: #10243a;

    /* -- Neutrals ------------------------------------------------------------------------------
       Cool grays, warmed very slightly so a white page does not read as a clinical blue-white. */
    --glc-paper: #f6f7f9;
    --glc-surface: #ffffff;
    --glc-surface-sunken: #f1f3f6;
    --glc-ink: #16202b;
    --glc-ink-soft: #45535f;
    --glc-ink-faint: #6b7784;
    --glc-line: #dde2e8;
    --glc-line-soft: #e9edf1;

    /* -- Derived from the brand ---------------------------------------------------------------- */
    --glc-primary-ink: color-mix(in oklab, var(--glc-primary) 78%, #0b1620);
    --glc-primary-wash: color-mix(in oklab, var(--glc-primary) 8%, #ffffff);
    --glc-primary-edge: color-mix(in oklab, var(--glc-primary) 28%, #ffffff);
    --glc-accent-ink: color-mix(in oklab, var(--glc-accent) 76%, #0b1620);
    --glc-accent-wash: color-mix(in oklab, var(--glc-accent) 10%, #ffffff);

    /* -- Status --------------------------------------------------------------------------------
       Deliberately not brand-derived. "This failed" must not turn friendly because a customer
       chose a green primary. */
    --glc-warn: #9a5b00;
    --glc-warn-wash: #fff6e6;
    --glc-warn-edge: #f0dcb4;
    --glc-danger: #a11d1d;
    --glc-danger-wash: #fdf0f0;
    --glc-danger-edge: #f0c9c9;
    --glc-good: #1e6b34;
    --glc-good-wash: #e9f5ec;

    /* -- Shape --------------------------------------------------------------------------------- */
    --glc-radius: 8px;
    --glc-radius-sm: 5px;
    --glc-shadow: 0 1px 2px rgba(16, 36, 58, .05), 0 1px 1px rgba(16, 36, 58, .03);
    --glc-shadow-lift: 0 4px 16px rgba(16, 36, 58, .09), 0 1px 3px rgba(16, 36, 58, .06);

    /* -- Type ----------------------------------------------------------------------------------
       No webfont. Everyone who uses this is on Windows connecting to Windows, and Segoe UI
       Variable is both the best face on that machine and the one the rest of their day is set in.
       A downloaded font would cost a request and CSP surface to look slightly less native. */
    --glc-font: "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont,
        "Helvetica Neue", system-ui, sans-serif;
    --glc-font-display: "Segoe UI Variable Display", "Segoe UI Semibold", "Segoe UI",
        -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
    --glc-font-mono: ui-monospace, "Cascadia Mono", "Cascadia Code", SFMono-Regular, Menlo,
        Consolas, monospace;

    --glc-measure: 68ch;
}

/* -- Reset and page ---------------------------------------------------------------------------- */

html {
    font-size: 15px;
    min-height: 100%;
    position: relative;
    -webkit-text-size-adjust: 100%;
}

@media (min-width: 768px) {
    html { font-size: 16px; }
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--glc-paper);
    color: var(--glc-ink);
    font-family: var(--glc-font);
    font-size: 1rem;
    line-height: 1.55;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
    font-family: var(--glc-font-display);
    color: var(--glc-ink);
    letter-spacing: -.011em;
    text-wrap: balance;
}

p { text-wrap: pretty; }

a {
    color: var(--glc-primary-ink);
    text-underline-offset: .18em;
    text-decoration-thickness: from-font;
}

a:hover { color: var(--glc-primary); }

/* Bootstrap ships a pink for inline code. Almost every code span here is a hostname, and the accent
   is the color the rest of the product already uses for one. */
code, kbd, samp, pre {
    font-family: var(--glc-font-mono);
    --bs-code-color: var(--glc-accent-ink);
    color: var(--glc-accent-ink);
}

::selection {
    background: color-mix(in oklab, var(--glc-primary) 22%, #ffffff);
    color: var(--glc-ink);
}

:focus-visible {
    outline: 2px solid var(--glc-primary);
    outline-offset: 2px;
    border-radius: 3px;
}

.glc-container {
    width: 100%;
    max-width: 76rem;
    margin: 0 auto;
    padding: 0 1.25rem;
}

.glc-main {
    flex: 1 0 auto;
    padding: 2rem 1.25rem 4rem;
}

/* -- Header ------------------------------------------------------------------------------------
   The one place the brand color is allowed to fill a surface rather than tint one. */

.glc-header {
    background: var(--glc-header);
    color: color-mix(in oklab, #ffffff 88%, var(--glc-header));
    border-bottom: 1px solid color-mix(in oklab, var(--glc-header) 82%, #000000);
}

.glc-header__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 3.5rem;
    padding-top: .5rem;
    padding-bottom: .5rem;
}

.glc-brand {
    display: flex;
    align-items: center;
    gap: .625rem;
    color: #ffffff;
    text-decoration: none;
    font-family: var(--glc-font-display);
    font-size: 1.0625rem;
    letter-spacing: -.01em;
}

.glc-brand:hover { color: #ffffff; }

.glc-brand__name { font-weight: 400; }
.glc-brand__name strong { font-weight: 650; }

/* The default mark: a rounded tile carrying the primary color, with a notch cut out of it so it
   reads as a shape rather than as a colored square somebody forgot to replace. */
.glc-brand__mark {
    width: 1.5rem;
    height: 1.5rem;
    flex: none;
    border-radius: 6px;
    background:
        linear-gradient(140deg,
            color-mix(in oklab, var(--glc-primary) 88%, #ffffff),
            var(--glc-primary) 55%,
            color-mix(in oklab, var(--glc-primary) 70%, var(--glc-accent)));
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
    position: relative;
}

.glc-brand__mark::after {
    content: "";
    position: absolute;
    inset: 34% 30% 34% 30%;
    border-left: 2px solid rgba(255, 255, 255, .92);
    border-bottom: 2px solid rgba(255, 255, 255, .92);
    border-bottom-left-radius: 2px;
}

.glc-brand__logo {
    max-height: 1.75rem;
    max-width: 11rem;
    width: auto;
    display: block;
}

.glc-nav {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .25rem .5rem;
    font-size: .9375rem;
}

.glc-nav__link {
    margin: 0;
    padding: .3rem .6rem;
    border-radius: var(--glc-radius-sm);
    color: color-mix(in oklab, #ffffff 78%, var(--glc-header));
    text-decoration: none;
}

.glc-nav__link:hover {
    background: rgba(255, 255, 255, .1);
    color: #ffffff;
}

.glc-nav__user {
    padding: .3rem .6rem;
    border-radius: var(--glc-radius-sm);
    color: color-mix(in oklab, #ffffff 70%, var(--glc-header));
    font-size: .875rem;
    text-decoration: none;
    min-width: 0;
    max-width: 18rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.glc-nav__user:hover {
    background: rgba(255, 255, 255, .1);
    color: #ffffff;
}

.glc-nav__form { margin: 0; }

.glc-header .btn-outline-secondary {
    --bs-btn-color: color-mix(in oklab, #ffffff 82%, var(--glc-header));
    --bs-btn-border-color: rgba(255, 255, 255, .28);
    --bs-btn-hover-color: var(--glc-header);
    --bs-btn-hover-bg: #ffffff;
    --bs-btn-hover-border-color: #ffffff;
}

/* -- Footer ------------------------------------------------------------------------------------ */

.glc-footer {
    flex: none;
    padding: 1.25rem 0 2rem;
    border-top: 1px solid var(--glc-line);
    background: var(--glc-surface);
    color: var(--glc-ink-faint);
    font-size: .8125rem;
}

.glc-footer .glc-container {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem .5rem;
    align-items: baseline;
}

.glc-footer__sep { color: var(--glc-line); }
.glc-footer a { color: var(--glc-ink-soft); }

/* -- Page furniture ---------------------------------------------------------------------------- */

.glc-page-title {
    font-size: 1.5rem;
    font-weight: 650;
    margin: 0 0 .35rem;
}

.glc-section-title {
    font-size: 1rem;
    font-weight: 650;
    margin: 2rem 0 .75rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--glc-line-soft);
    color: var(--glc-ink);
}

.glc-breadcrumb {
    font-size: .875rem;
    margin-bottom: .75rem;
}

.glc-muted {
    display: block;
    color: var(--glc-ink-faint);
    font-size: .8125rem;
    max-width: var(--glc-measure);
}

.glc-hint { color: var(--glc-ink-faint); font-size: .8125rem; }

.glc-empty {
    color: var(--glc-ink-faint);
    padding: 1.5rem;
    border: 1px dashed var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface-sunken);
}

.glc-empty p { margin-bottom: .5rem; }
.glc-empty p:last-child { margin-bottom: 0; }

/* -- Sign-in hero -------------------------------------------------------------------------------
   The only page an unauthenticated person sees, so it carries the weight. Asymmetric: the text
   column stops well short of the page so it reads as a statement rather than a paragraph. */

.glc-hero {
    max-width: 40rem;
    padding: 3rem 0 2rem;
}

.glc-hero h1 {
    font-size: clamp(1.875rem, 1.3rem + 2.2vw, 2.75rem);
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -.022em;
    margin: 0 0 1rem;
}

.glc-hero__lead {
    font-size: 1.125rem;
    line-height: 1.55;
    color: var(--glc-ink-soft);
    margin: 0 0 2rem;
    max-width: 34rem;
}

.glc-hero .btn-lg {
    padding: .7rem 1.6rem;
    font-size: 1rem;
    font-weight: 600;
}

.glc-hero__note {
    margin: 1.75rem 0 0;
    padding-left: .875rem;
    border-left: 2px solid var(--glc-primary-edge);
    color: var(--glc-ink-faint);
    font-size: .875rem;
    max-width: 32rem;
}

/* -- Buttons ------------------------------------------------------------------------------------
   Bootstrap variables rather than overrides, so every button type stays consistent and the
   customer palette reaches all of them. */

.btn {
    --bs-btn-border-radius: var(--glc-radius-sm);
    --bs-btn-font-weight: 550;
    font-family: var(--glc-font);
}

.btn-primary {
    --bs-btn-bg: var(--glc-primary);
    --bs-btn-border-color: var(--glc-primary);
    --bs-btn-hover-bg: color-mix(in oklab, var(--glc-primary) 86%, #000000);
    --bs-btn-hover-border-color: color-mix(in oklab, var(--glc-primary) 86%, #000000);
    --bs-btn-active-bg: color-mix(in oklab, var(--glc-primary) 78%, #000000);
    --bs-btn-active-border-color: color-mix(in oklab, var(--glc-primary) 78%, #000000);
    --bs-btn-disabled-bg: color-mix(in oklab, var(--glc-primary) 45%, #ffffff);
    --bs-btn-disabled-border-color: color-mix(in oklab, var(--glc-primary) 45%, #ffffff);
}

.btn-outline-secondary {
    --bs-btn-color: var(--glc-ink-soft);
    --bs-btn-border-color: var(--glc-line);
    --bs-btn-bg: var(--glc-surface);
    --bs-btn-hover-color: var(--glc-ink);
    --bs-btn-hover-bg: var(--glc-surface-sunken);
    --bs-btn-hover-border-color: var(--glc-ink-faint);
    --bs-btn-active-color: var(--glc-ink);
    --bs-btn-active-bg: var(--glc-surface-sunken);
    --bs-btn-active-border-color: var(--glc-ink-faint);
}

.btn-outline-danger {
    --bs-btn-color: var(--glc-danger);
    --bs-btn-border-color: var(--glc-danger-edge);
    --bs-btn-hover-bg: var(--glc-danger);
    --bs-btn-hover-border-color: var(--glc-danger);
    --bs-btn-active-bg: var(--glc-danger);
    --bs-btn-active-border-color: var(--glc-danger);
}

.btn-link {
    --bs-btn-color: var(--glc-primary-ink);
    --bs-btn-hover-color: var(--glc-primary);
    --bs-btn-font-weight: 500;
}

.btn:focus, .btn:active:focus,
.btn-link.nav-link:focus,
.form-control:focus, .form-select:focus, .form-check-input:focus {
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--glc-primary) 26%, transparent);
}

/* -- Banners ------------------------------------------------------------------------------------
   Three severities plus success. A left rule rather than a full tint, so a page carrying two of
   them still reads as a page. */

.glc-banner {
    display: block;
    margin: 0 0 1.25rem;
    padding: .75rem 1rem;
    border: 1px solid var(--glc-line);
    border-left-width: 3px;
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface);
    font-size: .9375rem;
}

.glc-banner p:last-child { margin-bottom: 0; }

.glc-banner--info {
    background: var(--glc-primary-wash);
    border-color: var(--glc-primary-edge);
    border-left-color: var(--glc-primary);
}

.glc-banner--success {
    background: var(--glc-good-wash);
    border-color: color-mix(in oklab, var(--glc-good) 25%, #ffffff);
    border-left-color: var(--glc-good);
}

.glc-banner--warning {
    background: var(--glc-warn-wash);
    border-color: var(--glc-warn-edge);
    border-left-color: var(--glc-warn);
    color: color-mix(in oklab, var(--glc-warn) 80%, #1b1408);
}

.glc-banner--danger {
    background: var(--glc-danger-wash);
    border-color: var(--glc-danger-edge);
    border-left-color: var(--glc-danger);
    color: color-mix(in oklab, var(--glc-danger) 82%, #1b0c0c);
}

.glc-error-list { margin: .5rem 0 0; padding-left: 1.25rem; }
.glc-validation { color: var(--glc-danger); font-size: .875rem; }

/* -- Admin navigation --------------------------------------------------------------------------
   Segmented rather than tab-like: an underline tab strip implies the page below is a tab panel,
   and these are separate pages. */

.glc-adminnav {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin: 0 0 1.75rem;
    padding: .25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-adminnav__link {
    padding: .4rem .8rem;
    border-radius: var(--glc-radius-sm);
    text-decoration: none;
    color: var(--glc-ink-soft);
    font-size: .875rem;
    font-weight: 500;
    white-space: nowrap;
}

.glc-adminnav__link:hover {
    background: var(--glc-surface-sunken);
    color: var(--glc-ink);
}

.glc-adminnav__link.is-current {
    background: var(--glc-primary-wash);
    color: var(--glc-primary-ink);
    font-weight: 650;
    box-shadow: inset 0 0 0 1px var(--glc-primary-edge);
}

/* -- Statistics --------------------------------------------------------------------------------- */

.glc-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: .75rem;
    margin: 1.5rem 0;
}

.glc-stat {
    padding: .875rem 1rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-stat__value {
    display: block;
    font-family: var(--glc-font-display);
    font-size: 1.75rem;
    font-weight: 650;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.glc-stat__label {
    display: block;
    margin-top: .25rem;
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--glc-ink-faint);
}

/* -- Connection cards (the end-user page) -------------------------------------------------------
   The whole product, for the person it is actually for. One row per connection, the action on the
   right where the eye ends up, the hostname in monospace because that is the thing they check. */

.glc-connections {
    list-style: none;
    margin: 1.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .75rem;
}

.glc-connection {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
    transition: box-shadow .16s ease, border-color .16s ease;
}

.glc-connection:hover {
    border-color: var(--glc-primary-edge);
    box-shadow: var(--glc-shadow-lift);
}

.glc-connection__body { flex: 1 1 20rem; min-width: 0; }

.glc-connection__name {
    font-size: 1.0625rem;
    font-weight: 650;
    margin: 0 0 .15rem;
}

.glc-connection__host {
    margin: 0 0 .35rem;
    font-family: var(--glc-font-mono);
    font-size: .8125rem;
    color: var(--glc-accent-ink);
    overflow-wrap: anywhere;
}

.glc-connection__meta {
    margin: 0;
    font-size: .8125rem;
    color: var(--glc-ink-faint);
}

.glc-connection__sep { padding: 0 .35rem; color: var(--glc-line); }

.glc-connection__description {
    margin: .5rem 0 0;
    font-size: .875rem;
    color: var(--glc-ink-soft);
    max-width: var(--glc-measure);
}

.glc-connection__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: none;
}

.glc-download-form {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: flex-end;
    margin: 1.5rem 0;
}

.glc-details {
    margin: 1.5rem 0;
    max-width: var(--glc-measure);
}

.glc-flags {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin: .5rem 0 0;
    padding: 0;
    list-style: none;
}

/* -- Panels -------------------------------------------------------------------------------------
   Used as <details> around the provisioning forms, which are long and mostly not what you came
   for. Closed by default is the right state; make the summary look pressable. */

.glc-panel {
    margin: 1.25rem 0;
    padding: 1rem 1.25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-panel > summary {
    cursor: pointer;
    font-weight: 600;
    list-style-position: outside;
    padding: .1rem 0;
    color: var(--glc-ink);
}

.glc-panel > summary:hover { color: var(--glc-primary-ink); }
.glc-panel[open] > summary {
    margin-bottom: 1rem;
    padding-bottom: .75rem;
    border-bottom: 1px solid var(--glc-line-soft);
}

/* -- Forms --------------------------------------------------------------------------------------
   A single column at a comfortable measure. The inline variant wraps into a row for the short
   add-something forms, where a stacked column would be three times taller than the thing it does. */

.glc-form { max-width: 34rem; }
.glc-form .glc-field { margin-bottom: 1.125rem; }

.glc-form legend {
    font-size: .9375rem;
    font-weight: 650;
    margin-bottom: .35rem;
}

.glc-form--inline {
    max-width: none;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1rem;
    align-items: flex-end;
    padding: 1rem 1.25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
    margin: 1rem 0;
}

.glc-form--inline .glc-field {
    margin-bottom: 0;
    flex: 1 1 15rem;
    min-width: 0;
}

.glc-form--inline .btn { flex: none; }

.glc-field > .glc-muted { margin-top: .3rem; }

.glc-field--check { display: flex; align-items: center; gap: .5rem; }

.form-label {
    display: block;
    margin-bottom: .3rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--glc-ink-soft);
}

.form-control, .form-select {
    border-color: var(--glc-line);
    border-radius: var(--glc-radius-sm);
    color: var(--glc-ink);
    font-size: .9375rem;
}

.form-control:focus, .form-select:focus { border-color: var(--glc-primary); }
.form-control::placeholder { color: color-mix(in oklab, var(--glc-ink-faint) 65%, #ffffff); }
.form-control:disabled, .form-control[readonly] { background: var(--glc-surface-sunken); }

.form-check-input:checked {
    background-color: var(--glc-primary);
    border-color: var(--glc-primary);
}

.form-check-label { font-size: .9375rem; }

/* A color input rendered at Bootstrap's control height is mostly chrome. Make the swatch the
   control. */
.glc-colorrow {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.glc-colorrow .glc-field { flex: 0 0 auto; }

.glc-color {
    width: 4.5rem;
    height: 2.5rem;
    padding: .2rem;
    cursor: pointer;
}

.glc-logo-preview {
    max-height: 3.5rem;
    max-width: 16rem;
    padding: .5rem .75rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface-sunken);
}

/* -- Tables -------------------------------------------------------------------------------------
   Wide content scrolls inside its own container rather than pushing the page sideways.

   The scroll lives on a wrapper, not on the table. Putting overflow on the <table> itself forces
   display: block, which stops the rows from stretching to the width of the card -- the header
   background and the row rules end where the last column ends, leaving a pale strip down the right
   of every table. One extra div is cheaper than that. */

.glc-tablewrap {
    overflow-x: auto;
    margin-bottom: 1.5rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-table {
    width: 100%;
    margin-bottom: 0;
    white-space: nowrap;
    border-collapse: collapse;
    --bs-table-bg: transparent;
}

.glc-table thead th {
    background: var(--glc-surface-sunken);
    border-bottom: 1px solid var(--glc-line);
    font-size: .75rem;
    font-weight: 650;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--glc-ink-faint);
    padding: .55rem .875rem;
}

.glc-table thead th:first-child { border-top-left-radius: calc(var(--glc-radius) - 1px); }
.glc-table thead th:last-child { border-top-right-radius: calc(var(--glc-radius) - 1px); }

.glc-table tbody td {
    padding: .625rem .875rem;
    border-bottom: 1px solid var(--glc-line-soft);
    vertical-align: middle;
    font-size: .9375rem;
}

.glc-table tbody tr:last-child td { border-bottom: 0; }
.glc-table tbody tr:hover td { background: color-mix(in oklab, var(--glc-primary) 3.5%, #ffffff); }

.glc-table tbody td code {
    font-size: .8125rem;
    color: var(--glc-accent-ink);
}

.glc-table td .glc-muted {
    display: block;
    margin-top: .1rem;
}

.glc-table td form { margin: 0; }

.glc-table--audit { font-size: .8125rem; }
.glc-table--audit tbody td { font-size: .8125rem; padding: .45rem .875rem; }

/* The selected row carries a rule down its leading edge. On the FIRST cell only: an inset shadow
   on every cell draws that rule between every column instead, which reads as a gridded table. */
.glc-table tr.table-active > * {
    /* Bootstrap paints its own row states with an inset shadow the width of the cell rather than a
       background, so overriding background alone leaves its gray underneath. */
    --bs-table-bg-state: transparent;
    --bs-table-accent-bg: transparent;
    background: var(--glc-primary-wash);
}
.glc-table tr.table-active > *:first-child { box-shadow: inset 3px 0 0 var(--glc-primary); }

.glc-row--muted td { opacity: .58; }

.glc-row--failed td { background: var(--glc-danger-wash); }
.glc-row--failed td:first-child { box-shadow: inset 3px 0 0 var(--glc-danger); }

.glc-audit__meta {
    max-width: 32rem;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--glc-font-mono);
    font-size: .75rem;
    color: var(--glc-ink-soft);
}

/* -- Badges and pills --------------------------------------------------------------------------- */

.glc-badge, .glc-pill {
    display: inline-block;
    padding: .1rem .45rem;
    border-radius: 999px;
    font-size: .6875rem;
    font-weight: 650;
    letter-spacing: .02em;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: .05em;
}

.glc-badge--ok, .glc-pill--ok {
    background: var(--glc-good-wash);
    color: var(--glc-good);
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--glc-good) 22%, #ffffff);
}

.glc-badge--off, .glc-pill--off {
    background: var(--glc-surface-sunken);
    color: var(--glc-ink-faint);
    box-shadow: inset 0 0 0 1px var(--glc-line);
}

/* -- Search and action rows ---------------------------------------------------------------------- */

.glc-search {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 1.25rem 0;
}

.glc-search .form-control,
.glc-search .form-select { max-width: 22rem; }

.glc-admin-links {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    margin: 1.5rem 0;
}

.glc-admin-links form { margin: 0; }

/* -- Two-column admin layout ---------------------------------------------------------------------
   List on the left, detail on the right. Collapses to one column well before it gets cramped,
   because the detail side carries tables. */

.glc-admin-split {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    align-items: flex-start;
    margin-top: 1.5rem;
}

.glc-admin-list { flex: 1 1 22rem; min-width: 0; }
.glc-admin-detail { flex: 2 1 32rem; min-width: 0; }

.glc-admin-list .glc-section-title,
.glc-admin-detail .glc-section-title { margin-top: 0; }

/* -- One-time secret -----------------------------------------------------------------------------
   Shown once, and then never again, so it needs to look like the thing you are meant to copy. */

.glc-key {
    display: block;
    margin-top: .5rem;
    padding: .625rem .875rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface);
    font-family: var(--glc-font-mono);
    font-size: .8125rem;
    color: var(--glc-ink);
    overflow-wrap: anywhere;
    user-select: all;
}

/* -- Motion ------------------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* -- Narrow screens -------------------------------------------------------------------------------
   Not a phone product, but an engineer opens it on one, and a broken layout there reads as a broken
   product everywhere. */

@media (max-width: 36rem) {
    .glc-main { padding-top: 1.25rem; }
    .glc-connection { align-items: stretch; }
    .glc-connection__actions { width: 100%; }
    .glc-connection__actions .btn:first-child { flex: 1; }
    .glc-hero { padding-top: 2rem; }
    .glc-adminnav { overflow-x: auto; flex-wrap: nowrap; }
}

/* -- Definition list ------------------------------------------------------------------------------
   The connection detail page. Two columns where there is room, stacked where there is not: a
   label/value pair that wraps mid-pair reads as two unrelated lines. */

.glc-details {
    display: grid;
    grid-template-columns: minmax(7rem, max-content) 1fr;
    gap: .5rem 1.5rem;
    margin: 1.5rem 0 0;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
    max-width: 44rem;
}

.glc-details dt {
    font-size: .75rem;
    font-weight: 650;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--glc-ink-faint);
    align-self: baseline;
    padding-top: .1rem;
}

.glc-details dd {
    margin: 0;
    font-size: .9375rem;
    overflow-wrap: anywhere;
}

/* The host is the value someone actually checks before they connect. */
.glc-details dd:first-of-type {
    font-family: var(--glc-font-mono);
    font-size: .875rem;
    color: var(--glc-accent-ink);
}

@media (max-width: 30rem) {
    .glc-details { grid-template-columns: 1fr; gap: .15rem; }
    .glc-details dd { margin-bottom: .75rem; }
}

/* -- Flag chips ------------------------------------------------------------------------------------
   Redirection settings, which a user reads and cannot change. Chips rather than a list, because
   what matters is the on/off scan, not the sentence. */

.glc-flags li {
    padding: .3rem .7rem;
    border: 1px solid var(--glc-line);
    border-radius: 999px;
    background: var(--glc-surface);
    font-size: .8125rem;
    color: var(--glc-ink-soft);
}

.glc-flags li strong {
    font-weight: 650;
    color: var(--glc-ink);
}

/* -- Remaining button variant ---------------------------------------------------------------------- */

.btn-outline-primary {
    --bs-btn-color: var(--glc-primary-ink);
    --bs-btn-border-color: var(--glc-primary-edge);
    --bs-btn-bg: var(--glc-surface);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--glc-primary);
    --bs-btn-hover-border-color: var(--glc-primary);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: var(--glc-primary);
    --bs-btn-active-border-color: var(--glc-primary);
}

/* Labels written without Bootstrap's class still need to look like labels. */
.glc-field label:not(.form-check-label) {
    display: block;
    margin-bottom: .3rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--glc-ink-soft);
}

.glc-field--check label:not(.form-check-label) {
    margin-bottom: 0;
    font-weight: 500;
    font-size: .9375rem;
}

/* -- List filters ---------------------------------------------------------------------------------
   A row of controls above a table, in the same card language as the table itself so the two read as
   one thing rather than as a form that happens to sit above a list. */

.glc-listfilter {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1rem;
    align-items: flex-end;
    margin: 1.5rem 0 1rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-listfilter .glc-field {
    margin-bottom: 0;
    flex: 1 1 11rem;
    min-width: 0;
}

.glc-listfilter .glc-field--check {
    flex: 0 0 auto;
    align-self: center;
    padding-top: 1.1rem;
}

.glc-listfilter__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 0 0 auto;
}

/* -- Sortable headers -------------------------------------------------------------------------------
   The whole cell is the target, and the arrow occupies a fixed slot so the header does not shift
   sideways when the sorted column changes. */

.glc-sort {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.glc-sort:hover {
    color: var(--glc-primary-ink);
    text-decoration: underline;
}

.glc-table thead th:has(.glc-sort) { padding: 0; }
.glc-table thead th .glc-sort { padding: .55rem .875rem; }

/* -- Row actions --------------------------------------------------------------------------------
   Icons, because the column is the same three verbs on every row and the words would be louder than
   the data. Each carries a title and a visually-hidden label, so it is still a named control. */

.glc-rowactions {
    display: flex;
    align-items: center;
    gap: .25rem;
}

.glc-rowactions form { margin: 0; }

.glc-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--glc-radius-sm);
    background: transparent;
    color: var(--glc-ink-faint);
    cursor: pointer;
    transition: color .12s ease, background-color .12s ease, border-color .12s ease;
}

.glc-iconbtn:hover {
    background: var(--glc-primary-wash);
    border-color: var(--glc-primary-edge);
    color: var(--glc-primary-ink);
}

.glc-iconbtn--danger:hover {
    background: var(--glc-danger-wash);
    border-color: var(--glc-danger-edge);
    color: var(--glc-danger);
}

.glc-icon {
    display: block;
    flex: none;
}

/* -- Import results -------------------------------------------------------------------------------
   One line per record, because an import of forty is per-record work and a single "12 failed" tells
   an operator nothing they can act on. */

.glc-outcomes {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .3rem;
    font-size: .875rem;
    max-height: 22rem;
    overflow-y: auto;
}

.glc-outcomes li { padding-left: .75rem; border-left: 2px solid var(--glc-good); }
.glc-outcomes li.is-failed { border-left-color: var(--glc-danger); }

/* -- Lookup hints ---------------------------------------------------------------------------------
   What the remote system actually has, tucked beside a free-text field. Collapsed, because a list of
   forty configuration types is reference material, not part of the form. */

.glc-lookup {
    margin-top: .35rem;
    font-size: .8125rem;
}

.glc-lookup > summary {
    cursor: pointer;
    color: var(--glc-primary-ink);
}

.glc-lookup__values {
    margin: .35rem 0 0;
    padding: .5rem .75rem;
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface-sunken);
    color: var(--glc-ink-soft);
}

/* Checkbox cells in a selection table: the column is one control wide and should not stretch. */
.glc-table td .form-check-input { margin: 0; }

/* -- Multi-select pickers -------------------------------------------------------------------------
   A wrapped row of checkboxes rather than a multi-select list box: a list box hides its options
   behind a scroll and needs ctrl-click to deselect, which nobody discovers. */

.glc-picker {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem .5rem;
    margin-top: .35rem;
}

.glc-picker__option {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .7rem;
    border: 1px solid var(--glc-line);
    border-radius: 999px;
    background: var(--glc-surface);
    font-size: .875rem;
    cursor: pointer;
    user-select: none;
}

.glc-picker__option:hover { border-color: var(--glc-primary-edge); }

.glc-picker__option:has(input:checked) {
    background: var(--glc-primary-wash);
    border-color: var(--glc-primary-edge);
    color: var(--glc-primary-ink);
    font-weight: 550;
}

/* An explicit margin as well as the flex gap: Bootstrap's checkbox reset sets margins the gap then
   has to fight, and the two together are what actually separates the box from its label. */
.glc-picker__option input {
    margin: 0 .15rem 0 0;
    flex: none;
}

/* -- Action bar -----------------------------------------------------------------------------------
   The things you can do on a page, as one row of tiles rather than a stack of collapsed panels. Each
   opens an overlay, so the list underneath stays where it was and there is one obvious place to look
   for "what can I do here". */

.glc-actionbar {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 1.5rem 0;
}

.glc-actionbar__form { margin: 0; display: contents; }

.glc-action {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .3rem;
    min-width: 9.5rem;
    padding: .75rem .9rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
    color: var(--glc-ink-soft);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease, color .12s ease;
}

.glc-action:hover {
    border-color: var(--glc-primary-edge);
    box-shadow: var(--glc-shadow-lift);
    color: var(--glc-primary-ink);
}

.glc-action .glc-icon { color: var(--glc-primary); }

.glc-action__label {
    font-size: .9375rem;
    font-weight: 600;
    color: var(--glc-ink);
    line-height: 1.2;
}

.glc-action__note {
    font-size: .75rem;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--glc-ink-faint);
}

/* The one you reach for most often. Tinted rather than filled: five solid tiles in a row would be a
   wall, and none of them would read as the important one. */
.glc-action--primary {
    background: var(--glc-primary-wash);
    border-color: var(--glc-primary-edge);
}

/* -- Dialogs --------------------------------------------------------------------------------------
   A real <dialog>, so the browser handles the backdrop, focus trapping, Escape and returning focus.
   All of that is easy to do badly by hand. */

.glc-dialog {
    width: min(38rem, calc(100vw - 2rem));
    max-height: min(46rem, calc(100vh - 3rem));
    padding: 0;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: 0 18px 48px rgba(16, 36, 58, .22);
    color: var(--glc-ink);
    overflow: hidden;
}

.glc-dialog--wide { width: min(48rem, calc(100vw - 2rem)); }

.glc-dialog::backdrop { background: rgba(16, 36, 58, .38); }

.glc-dialog__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .875rem 1.25rem;
    border-bottom: 1px solid var(--glc-line-soft);
    background: var(--glc-surface-sunken);
}

.glc-dialog__title {
    margin: 0;
    font-size: 1.0625rem;
    font-weight: 650;
}

.glc-dialog__body {
    padding: 1.25rem;
    overflow-y: auto;
    max-height: calc(min(46rem, 100vh - 3rem) - 3.5rem);
}

.glc-dialog__body .glc-form { max-width: none; }
.glc-dialog__body .glc-section-title:first-of-type { margin-top: 1rem; }

.glc-dialog__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .5rem;
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--glc-line-soft);
}

.glc-dialog__footer {
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--glc-line-soft);
}

/* -- Wizard ---------------------------------------------------------------------------------------
   Four dependent choices. The crumbs are a progress indicator, not navigation: going back is a button
   inside the step, because skipping forward past a choice the next step depends on is not a thing to
   offer. */

.glc-steps {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

.glc-steps li {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .7rem;
    border-radius: 999px;
    background: var(--glc-surface-sunken);
    color: var(--glc-ink-faint);
    font-size: .8125rem;
    counter-increment: step;
}

.glc-steps li::before {
    content: counter(step);
    display: grid;
    place-items: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--glc-line);
    color: var(--glc-surface);
    font-size: .6875rem;
    font-weight: 700;
}

.glc-steps li.is-current {
    background: var(--glc-primary-wash);
    color: var(--glc-primary-ink);
    font-weight: 600;
}

.glc-steps li.is-current::before { background: var(--glc-primary); }

.glc-steps li.is-done::before {
    content: "✓";
    background: var(--glc-good);
}

.glc-wizard__status {
    margin: 0 0 .75rem;
    min-height: 1.25rem;
    font-size: .875rem;
    color: var(--glc-ink-faint);
}

.glc-wizard__status.is-error { color: var(--glc-danger); }

/* -- Choice lists ---------------------------------------------------------------------------------
   Radio or checkbox rows with room for a second line, because the second line is the part that
   decides: an email address, or the hostname a connection will actually point at. */

.glc-choices {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    max-height: 22rem;
    overflow-y: auto;
    padding: .25rem;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface-sunken);
}

.glc-choice {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .5rem .7rem;
    border-radius: var(--glc-radius-sm);
    background: var(--glc-surface);
    cursor: pointer;
}

.glc-choice:hover { background: var(--glc-primary-wash); }
.glc-choice:has(input:checked) { box-shadow: inset 0 0 0 1px var(--glc-primary-edge); }
.glc-choice:has(input:disabled) { opacity: .55; cursor: default; }

.glc-choice input { margin-top: .2rem; flex: none; }

.glc-choice__body {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}

.glc-choice__meta {
    font-size: .8125rem;
    color: var(--glc-ink-faint);
    overflow-wrap: anywhere;
}

/* -- Wizard summary --------------------------------------------------------------------------------- */

.glc-summary {
    margin: 0 0 1rem;
    padding: 1rem 1.25rem;
    list-style: none;
    border: 1px solid var(--glc-line);
    border-radius: var(--glc-radius);
    background: var(--glc-surface-sunken);
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.glc-summary li {
    display: grid;
    grid-template-columns: minmax(6rem, max-content) 1fr;
    gap: .25rem 1.25rem;
}

.glc-summary__label {
    font-size: .75rem;
    font-weight: 650;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--glc-ink-faint);
}

.glc-summary__machine {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: baseline;
}

.glc-summary__machine code { font-size: .8125rem; color: var(--glc-accent-ink); }

/* -- Detail header --------------------------------------------------------------------------------- */

.glc-detailhead {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.glc-detailhead .glc-section-title { margin-top: 0; }
.glc-detailhead form { margin: 0; }

/* Status banners that carry an icon put it on the same baseline as the text. */
.glc-banner .glc-icon {
    display: inline-block;
    vertical-align: -.15em;
    margin-right: .35rem;
}

@media (max-width: 36rem) {
    .glc-action { min-width: 0; flex: 1 1 8rem; }
    .glc-dialog { width: 100vw; max-width: 100vw; max-height: 100vh; border-radius: 0; border: 0; }
}

/* An empty validation summary still renders <ul><li hidden>, and the list marker shows even though
   the item does not. It is one stray bullet, and it is on every form that has not been submitted. */
.validation-summary-valid { display: none; }
.validation-summary-errors ul { margin: 0; padding-left: 1.1rem; }

/* -- Detail panel ---------------------------------------------------------------------------------
   Under the list rather than beside it: the list is the thing being worked through, and a third of
   the width is not enough for it. */

.glc-detail {
    margin-top: 2rem;
    padding: 1.25rem 1.5rem;
    border: 1px solid var(--glc-line);
    border-left: 3px solid var(--glc-primary);
    border-radius: var(--glc-radius);
    background: var(--glc-surface);
    box-shadow: var(--glc-shadow);
}

.glc-detail .glc-section-title:first-of-type { margin-top: 0; }

/* A company already assigned: a chip with a remove control rather than a checkbox, because the set
   is short and removing one is the only edit. */
.glc-picker__option.is-set {
    background: var(--glc-primary-wash);
    border-color: var(--glc-primary-edge);
    color: var(--glc-primary-ink);
    font-weight: 550;
    padding-right: .25rem;
}

.glc-picker__option.is-set form { margin: 0; display: flex; }

.glc-iconbtn--sm {
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 999px;
}

.glc-iconbtn--sm .glc-icon { width: 12px; height: 12px; }

/* -- Selection and bulk actions -------------------------------------------------------------------
   Appears only when something is ticked, so an empty list is not carrying a toolbar for an action
   nobody can take yet. */

.glc-bulkbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .5rem;
    padding: .6rem 1rem;
    border: 1px solid var(--glc-primary-edge);
    border-radius: var(--glc-radius);
    background: var(--glc-primary-wash);
    color: var(--glc-primary-ink);
    font-size: .875rem;
}

.glc-bulkbar__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

.glc-table th.glc-select,
.glc-table td.glc-select {
    width: 1px;
    padding-right: .35rem;
    white-space: nowrap;
}

.glc-table .glc-select .form-check-input { margin: 0; }

/* Redirection toggles: many short labels, so they read as a block rather than a long column. */
.glc-checkgrid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.15rem 1rem;
}
