﻿/*
    The console: the vendor-facing back office, as opposed to the shopfront.

    Everything here is scoped to body.console-shell so a page opts in and no
    other page moves. The product these screens manage is licences with clocks
    running down on identified machines, so the whole visual system is built to
    answer one question at a glance - which licence runs out next - and colour
    is spent only on that. Slate ground, warm paper text, and a three-stop ramp
    that appears nowhere except on runway.
*/

body.console-shell {
    --ink: #0F1B1E;
    --ink-raised: #16272B;
    --ink-row: #132225;
    --rule: #26393E;
    --rule-soft: #1D2E33;
    --paper: #E9E5DB;
    --muted: #8FA3A7;

    /* The ramp. Spent only on a thing that is running out or already wrong and
       needs a person to act: licence runway, and the two places an account
       cannot work yet (a customer with no company, on the roster and counted on
       the dashboard). Never for decoration, emphasis, or ordinary state. */
    --ok: #6E9E8A;
    --warn: #D9A441;
    --alert: #D6522F;

    --ui: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --data: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

    background-color: var(--ink) !important;
    color: var(--paper);
    font-family: var(--ui);
}

/* The shell's own chrome, so the console does not sit under a shopfront nav. */
body.console-shell nav.indigo {
    background-color: var(--ink-raised) !important;
    border-bottom: 1px solid var(--rule);
    box-shadow: none;
}

body.console-shell nav a,
body.console-shell #logo-container {
    font-family: var(--ui);
    font-weight: 500;
    letter-spacing: 0.01em;
}

body.console-shell nav .nav-wrapper > ul > li > a {
    padding: 0 0.65rem;
    font-size: 0.8125rem;
}

/* The account's email is the widest thing in the bar and the least useful when
   space runs out, so it is the first to go. */
@media (max-width: 1500px) {
    body.console-shell nav .nav-wrapper > ul > li > a[title] { display: none; }
}

body.console-shell nav .btn,
body.console-shell nav .btn-flat { margin-left: 0.5rem; }

/* The sign-out button arrives from _LoginPartial in Materialize blue, which is
   the one thing on the page loud enough to compete with an expiring licence. */
body.console-shell nav .btn,
body.console-shell nav .btn-flat {
    background-color: transparent !important;
    box-shadow: none;
    border: 1px solid var(--rule);
    border-radius: 2px;
    color: var(--muted) !important;
    font-family: var(--ui);
    font-weight: 500;
}

body.console-shell nav .btn:hover,
body.console-shell nav .btn:focus-visible {
    border-color: var(--muted);
    color: var(--paper) !important;
}

body.console-shell footer.page-footer {
    background-color: var(--ink-raised) !important;
    border-top: 1px solid var(--rule);
}

/* Materialize wraps RenderBody in .container > .row, whose negative margins
   otherwise pull the console a few pixels left of the nav above it. */
body.console-shell main .row {
    margin-left: 0;
    margin-right: 0;
}

.console {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    padding: 2.5rem 0 4rem;
}

/* ------------------------------------------------------------------ header */

.console-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.75rem 1.5rem;
    padding-bottom: 1.25rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--rule);
}

.console-title {
    margin: 0;
    font-family: var(--ui);
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.015em;
    line-height: 1.1;
    color: var(--paper);
}

.console-summary {
    margin: 0;
    font-family: var(--data);
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.console-head-spacer { flex: 1 1 auto; }

.console-action {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 1.1rem;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background: transparent;
    color: var(--paper);
    font-family: var(--ui);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.console-action:hover,
.console-action:focus-visible {
    background-color: var(--ink-raised);
    border-color: var(--muted);
    color: var(--paper);
}

/* ------------------------------------------------------------------ roster */

.roster {
    list-style: none;
    margin: 0;
    padding: 0;
}

.roster-row {
    display: grid;
    grid-template-columns: 7.5rem minmax(0, 1fr) auto;
    align-items: center;
    gap: 0 1.75rem;
    padding: 1.15rem 0 1.35rem;
    border-bottom: 1px solid var(--rule-soft);
}

/* Every child must be allowed to shrink or the clock is pushed off-screen. */
.roster-row > * { min-width: 0; }

.roster-row:hover { background-color: var(--ink-row); }

/*
    The signature. Each row's remaining licence term, drawn on the rule that
    already separates the rows, so it costs no extra structure. Length is the
    runway against a 180-day horizon; colour is the same three stops used by
    the figure beside it. Read down the column and the shop's renewals are a
    staircase.
*/
.runway {
    display: block;
    width: 100%;
    height: 2px;
    margin-top: 0.6rem;
    background-color: var(--rule);
    overflow: hidden;
}

.runway-fill {
    display: block;
    height: 100%;
    width: var(--pct, 0%);
    background-color: var(--ok);
    transform: scaleX(0);
    transform-origin: left center;
    animation: runway-in 620ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes runway-in { to { transform: scaleX(1); } }

.roster-row[data-state="warn"]   .runway-fill { background-color: var(--warn); }
.roster-row[data-state="alert"]  .runway-fill,
.roster-row[data-state="expired"] .runway-fill { background-color: var(--alert); }

/* ------------------------------------------------------------------- clock */

.clock {
    text-align: right;
    font-family: var(--data);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.clock-figure {
    display: block;
    font-size: 2.125rem;
    font-weight: 500;
    letter-spacing: -0.03em;
    color: var(--ok);
}

.roster-row[data-state="warn"]  .clock-figure { color: var(--warn); }
.roster-row[data-state="alert"] .clock-figure { color: var(--alert); }

.clock-unit {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.clock-word {
    display: block;
    font-family: var(--ui);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--alert);
}

.clock-date {
    display: block;
    margin-top: 0.45rem;
    font-size: 0.75rem;
    color: var(--muted);
}

/* -------------------------------------------------------------------- body */

.roster-name {
    margin: 0 0 0.5rem;
    font-family: var(--ui);
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--paper);
}

.roster-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.75rem;
    margin: 0;
}

.roster-meta div { display: flex; align-items: baseline; gap: 0.5rem; }

.roster-meta dt {
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

.roster-meta dd {
    margin: 0;
    font-family: var(--data);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--paper);
    /* Documents and phone numbers carry no break opportunities of their own. */
    overflow-wrap: break-word;
}

/* ----------------------------------------------------------------- actions */

.roster-actions { display: flex; gap: 0.4rem; }

.icon-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--rule);
    border-radius: 2px;
    color: var(--muted);
    text-decoration: none;
    transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease;
}

.icon-action .material-icons { font-size: 1.15rem; }

/* Materialize paints bare <button>s; an icon action is an icon action whichever
   element it happens to be. */
button.icon-action {
    background-color: transparent;
    box-shadow: none;
    padding: 0;
    line-height: 1;
    cursor: pointer;
    text-transform: none;
}

.icon-action:hover,
.icon-action:focus-visible {
    color: var(--paper);
    border-color: var(--muted);
    background-color: var(--ink-raised);
}

.icon-action.is-destructive:hover,
.icon-action.is-destructive:focus-visible {
    color: var(--alert);
    border-color: var(--alert);
}

body.console-shell a:focus-visible,
body.console-shell button:focus-visible {
    outline: 2px solid var(--paper);
    outline-offset: 2px;
}

/* -------------------------------------------------------------------- form */

.console--narrow { max-width: 34rem; }

.console-form { display: flex; flex-direction: column; gap: 1.25rem; }

.field { display: flex; flex-direction: column; gap: 0.4rem; }

.field label {
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Materialize styles bare inputs globally, so these need to win on specificity
   without !important - hence the .console-form ancestor on every rule. */
.console-form .field input[type="text"],
.console-form .field input[type="email"],
.console-form .field input[type="password"],
.console-form .field input:not([type]),
.console-form .field select {
    box-sizing: border-box;
    width: 100%;
    height: auto;
    margin: 0;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    border-radius: 2px;
    background-color: var(--ink-raised);
    color: var(--paper);
    font-family: var(--data);
    font-size: 0.9375rem;
}

/* Direct child only. Materialize builds its own control as
   .select-wrapper > input + select and hides that inner select; a descendant
   selector here re-showed it, so the datepicker drew month and year twice. */
.console-form .field > select { display: block; }

.console-form .field input:focus,
.console-form .field select:focus {
    outline: none;
    border-color: var(--muted);
    box-shadow: none;
}

.field-hint {
    margin: 0;
    font-size: 0.75rem;
    color: var(--muted);
}

.console-form .field span.field-validation-error,
.console-form-errors {
    font-family: var(--ui);
    font-size: 0.8125rem;
    color: var(--alert);
}

.console-form-errors:empty { display: none; }

.console-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding-top: 0.5rem;
}

.console-action--primary {
    border-color: var(--muted);
    background-color: var(--ink-raised);
    cursor: pointer;
}

/* A gap that has to be filled before the account is usable. */
.roster-meta dd.is-missing { color: var(--warn); }

/* The users roster carries an action on the left where the companies roster carries
   the runway, so the row keeps its three columns and the two lists stay in step. */
.roster-row--compact { padding: 0.95rem 0 1.05rem; grid-template-columns: 2.25rem minmax(0, 1fr) auto; }

.roster-lead { display: flex; justify-content: flex-start; }

/* ------------------------------------------------------------------- empty */

.console-empty {
    padding: 4rem 2rem;
    border: 1px dashed var(--rule);
    border-radius: 2px;
    text-align: center;
}

.console-empty h2 {
    margin: 0 0 0.6rem;
    font-family: var(--ui);
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--paper);
}

.console-empty p {
    margin: 0 0 1.75rem;
    font-size: 0.9375rem;
    color: var(--muted);
}

/* ------------------------------------------------------------- dashboard */

.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 1px;
    list-style: none;
    margin: 2rem 0 0;
    padding: 0;
    background-color: var(--rule);
    border: 1px solid var(--rule);
}

.stat { background-color: var(--ink); }

.stat a {
    display: block;
    padding: 1.4rem 1.25rem;
    color: inherit;
    text-decoration: none;
}

.stat a:hover { background-color: var(--ink-raised); }

.stat-figure {
    display: block;
    font-family: var(--data);
    font-size: 1.875rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--paper);
}

.stat-label {
    display: block;
    margin-top: 0.5rem;
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Only the two that mean work carry colour. */
.stat.is-warn .stat-figure { color: var(--warn); }
.stat.is-alert .stat-figure { color: var(--alert); }

.links { display: flex; flex-wrap: wrap; gap: 0.6rem; }

.inline-form { display: inline; margin: 0; }

.tag {
    margin-left: 0.6rem;
    padding: 0.1rem 0.45rem;
    border-radius: 2px;
    font-family: var(--ui);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    vertical-align: middle;
}

.tag--alert { background-color: var(--alert); color: var(--ink); }

/* ------------------------------------------------------- the shop's own page */

/*
    The licence block is the only place on the customer page that carries the signal
    colour. Everything below it is deliberately quiet: a shop should be able to tell
    at a glance whether it can trade, without reading anything.
*/
.licence {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 1rem 3rem;
    margin: 2.5rem 0 0;
    padding: 1.75rem 0;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}

.licence-clock { font-family: var(--data); line-height: 1; }

.licence-figure {
    font-size: 3.25rem;
    font-weight: 500;
    letter-spacing: -0.035em;
    color: var(--ok);
}

.licence[data-state="warn"]  .licence-figure { color: var(--warn); }
.licence[data-state="alert"] .licence-figure { color: var(--alert); }

.licence-unit {
    margin-left: 0.6rem;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.licence-word {
    font-family: var(--ui);
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--alert);
}

.licence-facts { display: flex; flex-wrap: wrap; gap: 0.5rem 2.5rem; margin: 0; }
.licence-facts div { display: flex; align-items: baseline; gap: 0.6rem; }

.licence-facts dt {
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

.licence-facts dd {
    margin: 0;
    font-family: var(--data);
    font-size: 0.9375rem;
    font-variant-numeric: tabular-nums;
    color: var(--paper);
}

.licence-facts dd.is-over { color: var(--alert); }

.panel { padding: 2.25rem 0; border-bottom: 1px solid var(--rule-soft); }

.panel-title {
    margin: 0 0 0.4rem;
    font-family: var(--ui);
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--paper);
}

.panel-hint,
.panel-empty { margin: 0 0 1.25rem; font-size: 0.875rem; color: var(--muted); }
.panel-empty { margin-bottom: 0; }

.panel .console-form { max-width: 28rem; }

.field-readonly {
    margin: 0;
    padding: 0.6rem 0;
    font-family: var(--data);
    font-size: 0.9375rem;
    color: var(--muted);
}

.machines { list-style: none; margin: 0 0 1.25rem; padding: 0; }

.machine {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--rule-soft);
}

.machine-main { display: flex; flex: 1 1 18rem; align-items: baseline; gap: 1rem; min-width: 0; }

.console-shell .machine-alias {
    box-sizing: border-box;
    flex: 1 1 auto;
    min-width: 0;
    height: auto;
    margin: 0;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background-color: var(--ink-raised);
    color: var(--paper);
    font-family: var(--ui);
    font-size: 0.9375rem;
}

.machine-version {
    font-family: var(--data);
    font-size: 0.8125rem;
    color: var(--muted);
    white-space: nowrap;
}

.machine-toggle { display: flex; align-items: center; gap: 0.55rem; cursor: pointer; }

.console-shell .machine-toggle input[type="checkbox"] {
    /* Materialize hides bare checkboxes and draws its own; this page wants the real one. */
    position: static;
    opacity: 1;
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    pointer-events: auto;
    accent-color: var(--ok);
}

.machine-toggle span {
    font-family: var(--ui);
    font-size: 0.6875rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

.payments { list-style: none; margin: 0; padding: 0; }

.payment {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 2rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--rule-soft);
    font-family: var(--data);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
}

.payment-date { color: var(--paper); min-width: 6rem; }
.payment-value { color: var(--paper); min-width: 6rem; }
.payment-until { color: var(--muted); }

/* The last row's rule and the panel's own sit a few pixels apart and read as a
   double line. The panel already closes the section. */
.payment:last-child { border-bottom: none; }
.panel:last-child { border-bottom: none; }

@media (max-width: 640px) {
    .licence { gap: 0.75rem 1.5rem; }
    .licence-figure { font-size: 2.5rem; }
    .machine-main { flex: 1 1 100%; }
}

/* ------------------------------------------- pages still on Materialize markup

    The CRUD and detail pages keep their tables and fields; these rules give them
    the console's palette and type without rewriting fourteen views. Anything that
    grows a roster of its own later simply stops matching these.

    Scoping to `main` keeps these off the header, the footer and anything
    Materialize appends to <body>. It is not enough on its own: the datepicker
    modal is inserted into the field it belongs to, so it sits inside main and
    inherits every rule written for the page's own tables and buttons. It did -
    day numbers took --paper on the picker's near-white panel and the calendar
    went blank. Materialize's own widgets are skinned explicitly further down;
    that skin, not this scope, is what keeps them readable.
*/

body.console-shell main h1,
body.console-shell main h2,
body.console-shell main h3 {
    font-family: var(--ui);
    font-weight: 700;
    letter-spacing: -0.015em;
    color: var(--paper) !important;
}

body.console-shell main h1 { font-size: 1.75rem; margin: 2.5rem 0 1.25rem; }
body.console-shell main h2 { font-size: 1.25rem; }

body.console-shell main table {
    border-collapse: collapse;
    font-family: var(--ui);
}

body.console-shell main table thead tr,
body.console-shell main table thead th {
    background-color: transparent !important;
    border-bottom: 1px solid var(--rule);
}

body.console-shell main table th {
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted) !important;
}

body.console-shell main table tbody {
    background-color: transparent !important;
}

body.console-shell main table tbody tr {
    border-bottom: 1px solid var(--rule-soft);
}

body.console-shell main table tbody tr:hover { background-color: var(--ink-row); }

body.console-shell main table td {
    font-family: var(--data);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
    color: var(--paper);
}

/* Materialize's own colour helpers are how these pages were painted; inside the
   console they would each bring their own palette. */
body.console-shell main .indigo,
body.console-shell main .indigo-text,
body.console-shell main .bg-dark-light {
    background-color: transparent !important;
    color: var(--paper) !important;
}

body.console-shell main .card,
body.console-shell main .card-panel {
    background-color: var(--ink-raised) !important;
    border: 1px solid var(--rule);
    border-radius: 2px;
    box-shadow: none;
    color: var(--paper);
}

/* The message panel keeps meaning something, so it keeps its colour. */
body.console-shell main .card-panel.red { background-color: var(--alert) !important; color: var(--ink) !important; }
body.console-shell main .card-panel.yellow { background-color: var(--warn) !important; color: var(--ink) !important; }

body.console-shell main .input-field input,
body.console-shell main .input-field textarea,
body.console-shell main select.browser-default {
    box-sizing: border-box;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background-color: var(--ink-raised);
    color: var(--paper) !important;
    font-family: var(--data);
    padding: 0.5rem 0.6rem;
    height: auto;
}

body.console-shell main .input-field label {
    color: var(--muted) !important;
    font-family: var(--ui);
}

body.console-shell main .btn,
body.console-shell main .btn-large,
body.console-shell main .btn-flat {
    background-color: transparent !important;
    border: 1px solid var(--rule);
    border-radius: 2px;
    box-shadow: none;
    color: var(--paper) !important;
    font-family: var(--ui);
    font-weight: 600;
    letter-spacing: 0.04em;
}

body.console-shell main .btn:hover,
body.console-shell main .btn-large:hover { border-color: var(--muted); background-color: var(--ink-raised) !important; }

body.console-shell main .btn.red,
body.console-shell main .btn-floating.red { border-color: var(--alert); color: var(--alert) !important; }

body.console-shell main .btn-floating {
    background-color: transparent !important;
    border: 1px solid var(--rule);
    box-shadow: none;
    color: var(--muted) !important;
}

body.console-shell main .btn-floating:hover { border-color: var(--muted); color: var(--paper) !important; }

/* An empty list says so, rather than showing a header row over nothing. */
.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin: 1.5rem 0 3rem;
}

.pager-count {
    font-family: var(--data);
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
}

.pager-links { display: flex; gap: 0.5rem; }

.list-empty {
    padding: 3rem 1.5rem;
    border: 1px dashed var(--rule);
    border-radius: 2px;
    text-align: center;
    font-size: 0.9375rem;
    color: var(--muted);
}

/* -------------------------------------------------------------- responsive */

@media (max-width: 860px) {
    .roster-row {
        grid-template-columns: 1fr;
        gap: 0.85rem 0;
        padding: 1.4rem 0 1.5rem;
    }

    /* The clock leads: it is the reason to look at the row at all. */
    .clock {
        order: -1;
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0 0.5rem;
        text-align: left;
    }

    .clock-figure { font-size: 1.75rem; }

    .clock-unit,
    .clock-date { margin-top: 0; }

    /* No auto margin here: on a wrapping flex line it pushes the date past
       the edge instead of on to the next line. */
    .clock-date { margin-left: 0; }

    /* Still full-bleed on its own line, so the staircase survives the stack. */
    .runway {
        flex: 1 0 100%;
        margin-top: 0.55rem;
    }

    .roster-meta {
        flex-direction: column;
        gap: 0.3rem;
    }
}

@media (max-width: 520px) {
    .console-title { font-size: 1.375rem; }
    .roster-meta { gap: 0.25rem 1rem; }
}

@media (prefers-reduced-motion: reduce) {
    .runway-fill {
        animation: none;
        transform: scaleX(1);
    }
}


/* ----------------------------------------------------- the section bar

    Every admin section, always present, so moving between two of them is one
    click rather than a trip back through the dashboard.

    The current section is not marked with colour. In this console a hue means
    licence runway and nothing else, so "you are here" is carried by the label
    going from muted to paper and by a rule flush with the bar's bottom edge -
    the active tab reads as the page already beginning underneath it.

    The labels borrow the table header's treatment on purpose: both are labels
    for a column of things.
*/

body.console-shell .console-nav {
    background-color: var(--ink);
    border-bottom: 1px solid var(--rule);
    /* Materialize gives every <nav> a fixed 56px height and line-height. Left alone,
       the tabs overflow it and the current-section rule floats ~24px below the bar. */
    height: auto;
    line-height: 1;
}

body.console-shell .console-nav ul {
    display: flex;
    align-items: stretch;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scrollbar-width: none;
}

body.console-shell .console-nav ul::-webkit-scrollbar { display: none; }

body.console-shell .console-nav li { flex: 0 0 auto; }

body.console-shell .console-nav a {
    display: block;
    padding: 0.85rem 0.9rem 0.7rem;
    border-bottom: 2px solid transparent;
    color: var(--muted);
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: color 120ms ease, border-color 120ms ease;
}

body.console-shell .console-nav a:hover {
    color: var(--paper);
    border-bottom-color: var(--rule);
}

body.console-shell .console-nav a.is-current {
    color: var(--paper);
    border-bottom-color: var(--paper);
}

@media (prefers-reduced-motion: reduce) {
    body.console-shell .console-nav a { transition: none; }
}

/* ------------------------------------------- Materialize's own overlays

    The datepicker, the select dropdown and the modals are appended to <body>,
    outside main, so nothing above reaches them. They arrive in stock Material
    white-and-teal, which is the loudest thing on a slate page and reads as a
    different product. Skinned here to match the console.

    Selection is shown by inverting value - paper ground, ink text - rather
    than by introducing an accent, because the accents mean runway.
*/

body.console-shell .datepicker-modal,
body.console-shell .dropdown-content,
body.console-shell .modal {
    background-color: var(--ink-raised);
    border: 1px solid var(--rule);
    border-radius: 2px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    color: var(--paper);
}

/* The date the picker is currently sitting on. */
body.console-shell .datepicker-date-display {
    background-color: var(--ink);
    border-bottom: 1px solid var(--rule);
    color: var(--paper);
    font-family: var(--ui);
}

body.console-shell .datepicker-date-display .year-text { color: var(--muted); }

body.console-shell .datepicker-table th,
body.console-shell .datepicker-table abbr {
    color: var(--muted);
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

body.console-shell .datepicker-table td {
    color: var(--paper);
    font-family: var(--data);
    font-variant-numeric: tabular-nums;
}

body.console-shell .datepicker-day-button:hover {
    background-color: var(--ink-row);
    border-radius: 50%;
}

/* Today is a landmark, not a disabled day: muting it made it read as the one
   date you cannot pick. It keeps full contrast and is ringed instead. */
body.console-shell .datepicker-table td.is-today {
    color: var(--paper);
    box-shadow: inset 0 0 0 1px var(--rule);
}

body.console-shell .datepicker-table td.is-selected {
    background-color: var(--paper);
    color: var(--ink);
}

body.console-shell .datepicker-table td.is-outside-current-month,
body.console-shell .datepicker-table td.is-disabled {
    color: var(--rule);
}

/* Cancel / Clear / OK. Stock Materialize renders these as teal .btn-flat; on the
   console's ground they were paper text on a near-white panel, i.e. invisible. */
body.console-shell .datepicker-footer .btn-flat,
body.console-shell .datepicker-cancel,
body.console-shell .datepicker-clear,
body.console-shell .datepicker-done {
    background-color: transparent;
    color: var(--paper) !important;
    font-family: var(--ui);
    font-weight: 600;
    letter-spacing: 0.04em;
}

body.console-shell .datepicker-clear { color: var(--alert) !important; }

body.console-shell .datepicker-controls .select-dropdown,
body.console-shell .datepicker-controls .month-prev,
body.console-shell .datepicker-controls .month-next {
    color: var(--paper);
    font-family: var(--ui);
}

body.console-shell .datepicker-controls .select-dropdown li span { color: var(--paper); }

/* The select dropdown, same reasoning. */
body.console-shell .dropdown-content li > a,
body.console-shell .dropdown-content li > span {
    color: var(--paper);
    font-family: var(--ui);
    font-size: 0.875rem;
}

body.console-shell .dropdown-content li:hover,
body.console-shell .dropdown-content li.active { background-color: var(--ink-row); }

/* The mobile menu is in the header, outside main, so it keeps the shopfront's
   blue buttons unless it is told otherwise. */
body.console-shell .sidenav {
    background-color: var(--ink-raised);
    border-right: 1px solid var(--rule);
}

body.console-shell .sidenav .btn {
    background-color: transparent !important;
    border: 1px solid var(--rule);
    border-radius: 2px;
    box-shadow: none;
    color: var(--paper) !important;
    font-family: var(--ui);
    font-weight: 600;
    letter-spacing: 0.04em;
}


/* ------------------------------------------------------------ filter bars

    A filter row is a form laid on its side: same fields, same labels above
    them, so the controls line up on one baseline and the two buttons sit with
    the fields rather than drifting onto a row of their own.
*/

.console-filters {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1rem;
    margin-bottom: 2.5rem;
}

.console-filters .field { flex: 0 1 11rem; }
.console-filters .field--grow { flex: 1 1 14rem; }

.console-filters .filter-actions {
    display: flex;
    gap: 0.5rem;
    flex: 0 0 auto;
}

body.console-shell main .console-filters .filter-actions .btn {
    height: auto;
    padding: 0.6rem 1.1rem;
    line-height: 1.35;
}

@media (max-width: 600px) {
    .console-filters .field,
    .console-filters .field--grow { flex: 1 1 100%; }
    .console-filters .filter-actions { flex: 1 1 100%; }
    .console-filters .filter-actions .btn { flex: 1 1 0; text-align: center; }
}


/* --------------------------------------------------- running as someone else

    An administrator viewing the portal as one of its owners. The bar is the only
    way back out, so it is fixed to the top of every page for as long as the
    session lasts, and it uses --warn: this is a state that is wrong to leave
    running, which is the one thing that ramp is for.
*/

.impersonation-bar {
    background-color: var(--warn);
    color: #1A1204;
}

.impersonation-bar .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.6rem 0;
}

.impersonation-note {
    flex: 1 1 auto;
    font-family: var(--ui);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.impersonation-bar form { margin: 0; }

.impersonation-exit {
    padding: 0.35rem 0.9rem;
    border: 1px solid rgba(26, 18, 4, 0.55);
    border-radius: 2px;
    background: transparent;
    color: inherit;
    font-family: var(--ui);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
}

.impersonation-exit:hover,
.impersonation-exit:focus-visible {
    background-color: rgba(26, 18, 4, 0.12);
    border-color: #1A1204;
}

@media (max-width: 600px) {
    .roster-row--compact { grid-template-columns: 2.25rem minmax(0, 1fr); }
    .roster-row--compact .roster-actions { grid-column: 2; justify-content: flex-start; }
}
