@font-face {
    font-family: "Neulis Alt";
    src: url("/fonts/neulis-alt/NeulisAlt-SemiBold.woff2") format("woff2"),
         url("/fonts/neulis-alt/NeulisAlt-SemiBold.woff") format("woff");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

:root {
    accent-color: #7F00FF;
    --font-display: "Neulis Alt", "General Sans", "Gilroy", "Poppins", "Sora",
                    system-ui, sans-serif;
    --nav-width-expanded: 240px;
    --nav-width-mini: 88px;
    --nav-transition-duration: 200ms;
    --nav-transition-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Evidence file chips (all four report forms): keep a chip within the card and shorten a long file
   name with an ellipsis, while leaving the file size fully visible. */
.evidence-chips .mud-chip {
    max-width: 100%;
}

.evidence-chip-name {
    display: inline-block;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

html[data-nav-layout="mini"] {
    /* Mini nav layout hook — wired up in a later step; no visual change here. */
    --nav-layout: mini;
}

/* ============================================================================
   Nav collapse/expand motion.

   These target MudBlazor 8.12.0 layout elements (.mud-drawer mini variant and
   .mud-main-content). They live in this GLOBAL sheet — not in NavMenu's or
   SidebarProfileMenu's isolated CSS — because those elements are outside both
   components' isolation scope, so ::deep cannot reach them.
   THEY TARGET MUDBLAZOR INTERNALS AND MAY NEED REVIEW ON A MUDBLAZOR UPGRADE.

   Keyed off our data-nav-layout attribute (present in both states) rather than
   ="mini" so width and content offset animate in step in BOTH directions; a
   ="mini"-only gate would drop the transition the instant the attribute flips to
   "expanded" and kill the expand animation. .mud-drawer-mini exists only on
   desktop and .mud-main-content's margin only changes on desktop, so mobile is
   unaffected.
   ============================================================================ */
html[data-nav-layout] .mud-drawer.mud-drawer-mini {
    transition: width var(--nav-transition-duration) var(--nav-transition-easing);
}

html[data-nav-layout] .mud-main-content {
    transition: margin var(--nav-transition-duration) var(--nav-transition-easing);
}

/* Collapsed-rail width guard. The width normally comes from MudDrawer's
   MiniWidth="88px", which MudLayout emits as --mud-drawer-width-mini-left (that
   variable has no CSS default/fallback). This pins the collapsed desktop rail to
   our --nav-width-mini token so the rail is exactly 88px even if that inline
   variable is ever absent. Collapsed desktop only (data-nav-layout="mini" +
   closed mini drawer); expanded and mobile are untouched. No hardcoded literal. */
html[data-nav-layout="mini"] .mud-drawer.mud-drawer-mini.mud-drawer--closed {
    width: var(--nav-width-mini);
}

@media (prefers-reduced-motion: reduce) {
    html[data-nav-layout] .mud-drawer.mud-drawer-mini,
    html[data-nav-layout] .mud-main-content {
        transition: none;
    }
}

/* ============================================================================
   Sidebar edge collapse/expand control.

   A 26px circle straddling the drawer's right edge. It tracks the edge in both
   states by reusing the same width tokens (--nav-width-expanded / --nav-width-mini)
   and the same transition duration/easing the drawer width uses, keyed off the
   existing data-nav-layout attribute. Desktop only (Md+); below Md the app bar
   hamburger stays as the sole control.

   z-index targets MudBlazor 8.12 internals: the drawer is 1100, so 1101 sits one
   above it (so the circle is never clipped by the drawer) and below popovers (1200)
   and dialogs (1400). The notifications panel (1000, top-right) never overlaps this
   top-left circle.
   ============================================================================ */
.nav-collapse-toggle {
    display: none; /* shown at Md+ only (below) */
    position: fixed;
    left: var(--nav-width-expanded);
    top: calc(var(--mud-appbar-height, 64px) + 13px); /* first nav link row centre (~90px), minus half the circle */
    transform: translateX(-50%);
    z-index: 1101;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    color: #6B7280;
    box-shadow: var(--mud-elevation-1, 0 2px 1px -1px rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12));
    place-items: center;
    cursor: pointer;
    transition: left var(--nav-transition-duration) var(--nav-transition-easing),
                color 130ms,
                border-color 130ms;
}

@media (min-width: 960px) {
    .nav-collapse-toggle {
        display: grid; /* Md and up: the circle is the only collapse control */
    }
}

html[data-nav-layout="mini"] .nav-collapse-toggle {
    left: var(--nav-width-mini);
}

.nav-collapse-toggle:hover {
    color: #111827;
    border-color: #9CA3AF;
}

.nav-collapse-toggle:focus-visible {
    outline: 2px solid #7F00FF;
    outline-offset: 2px;
}

/* The chevron is never swapped, only mirrored to point the other way when collapsed. */
html[data-nav-layout="mini"] .nav-collapse-toggle svg {
    transform: scaleX(-1);
}

@media (prefers-reduced-motion: reduce) {
    .nav-collapse-toggle {
        transition: none;
    }
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: #fff;
    border-top: 1px solid #e5e7eb;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-splash {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    gap: 0.75rem;
    font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
}

.loading-logo {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 8.25rem;
    height: 8.25rem;
    border-radius: 50%;
    background: var(--mud-palette-primary, #7F00FF);
    overflow: hidden;
}

.loading-logo-symbol {
    position: relative;
    z-index: 1;
    width: 52%;
    height: auto;
    display: block;
}

.loading-logo::after {
    content: "";
    position: absolute;
    inset: -40%;
    background: linear-gradient(
        135deg,
        transparent 35%,
        rgba(255, 255, 255, 0.45) 50%,
        transparent 65%
    );
    animation: loading-shimmer 1.8s ease-in-out infinite;
}

@keyframes loading-shimmer {
    0% {
        transform: translate(-35%, -35%);
    }

    100% {
        transform: translate(35%, 35%);
    }
}

.loading-progress-text {
    text-align: center;
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: #6B7280;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

/* Shared auth / signup surfaces (Neulis Alt SemiBold for display titles) */
.auth-choice-page {
    font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px 48px 60px;
    background: #FFFFFF;
}

@media (max-width: 599.98px) {
    .auth-choice-page {
        padding: 16px 16px 48px;
    }
}

.auth-choice-container {
    max-width: 580px;
    width: 100%;
    text-align: center;
}

.auth-choice-title,
.auth-status-title {
    font-family: var(--font-display);
    font-size: 30px;
    font-weight: 600;
    color: #111827;
    margin: 0 0 8px;
    letter-spacing: -0.02em;
}

.auth-status-title {
    margin: 0;
}

.auth-choice-subtitle {
    font-size: 16px;
    color: #6B7280;
    margin: 0 0 40px;
}

.auth-choice-prompt {
    font-size: 16px;
    color: #6B7280;
    margin: 0 0 16px;
}

.login-primary-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 100%;
    max-width: 320px;
    margin: 0 auto 40px;
    padding: 14px 28px;
    border: none;
    border-radius: 10px;
    background: #7F00FF;
    color: #FFFFFF;
    font: inherit;
    font-size: 16px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.15s ease;
}

.login-primary-btn:hover {
    background: #6B00DD;
    color: #FFFFFF;
    transform: translateY(-1px);
}

.auth-choice-alt {
    font-size: 14px;
    color: #6B7280;
    margin: 0 0 8px;
}

.auth-alt-link {
    color: #7F00FF;
    text-decoration: none;
    font-weight: 600;
}

.auth-alt-link:hover {
    text-decoration: underline;
}

.auth-alt-link-btn {
    display: inline;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    font-weight: 600;
    line-height: inherit;
    vertical-align: baseline;
    cursor: pointer;
}

.auth-choice-note {
    font-size: 13px;
    color: #9CA3AF;
    margin: 0;
}

.signup-form-page .auth-choice-container {
    max-width: 520px;
    text-align: left;
}

.signup-form-page .mud-input-helper-text {
    color: #6B7280 !important;
}

.signup-back {
    display: inline-block;
    font-size: 13px;
    margin-bottom: 16px;
}

.signup-page-title {
    font-family: var(--font-display);
    font-size: 32px;
    font-weight: 600;
    color: #111827;
    margin: 0 0 12px;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.signup-page-subtitle {
    font-size: 15px;
    line-height: 1.6;
    color: #374151;
    margin: 0 0 28px;
}

.signup-submit-btn {
    border-radius: 10px !important;
    min-height: 48px;
    font-weight: 600;
    font-size: 15px;
}

.signup-footer-alt {
    margin-top: 20px;
    text-align: center;
}

/* Analytics: Students who need attention grid column alignment */
.students-attention-grid th.analytics-grid-col-center,
.students-attention-grid td.analytics-grid-col-center {
    text-align: center !important;
}

.students-attention-grid th.analytics-grid-col-center .column-header {
    justify-content: center !important;
}

.students-attention-grid th.analytics-grid-col-left,
.students-attention-grid td.analytics-grid-col-left {
    text-align: left !important;
}

.students-attention-grid th.analytics-grid-col-left .column-header {
    justify-content: flex-start !important;
}

/* Multi-select filter checkboxes — match MudCheckBox Outlined Primary (#7F00FF) */
.uspeak-primary-checkbox-icons .mud-list-item-icon {
    color: var(--mud-palette-primary, #7F00FF) !important;
}

/* ============================================================================
   iOS safe area (status bar / notch / home indicator).

   The native shell (mobile/capacitor.config.ts) sets ios.contentInset:'never' and
   index.html sets viewport-fit=cover, so the web app owns the safe area via env().
   The fixed app bar grows upward by the top inset in its own colour, so the status
   bar strip always shows the bar colour, and the main content is pushed down by the
   same amount, so content scrolls beneath the bar and never appears above it. On
   desktop and in browsers env(safe-area-inset-*) is 0, so these rules are inert
   there and the layout is unchanged. FullBleedLayout's sticky .landing-nav handles
   its own top inset in that layout's own style block; :not(.mud-main-content-full)
   keeps this fixed-bar content offset off that layout.
   ============================================================================ */
.mud-appbar.mud-appbar-fixed-top {
    padding-top: env(safe-area-inset-top);
}

.mud-main-content:not(.mud-main-content-full) {
    margin-top: env(safe-area-inset-top);
}

.mud-main-content {
    padding-bottom: env(safe-area-inset-bottom);
}

/* Phone app bar drill-down title: keep it on one line and ellipsis if it is too long to fit
   between the back arrow and the bell. min-width:0 lets it shrink inside the flex toolbar. */
.usp-appbar-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex-shrink: 1;
}

/* ============================================================================
   Phone layout polish (below 600px). Desktop and tablet are unchanged.
   ============================================================================ */
@media (max-width: 599.98px) {
    /* One consistent 12px side gutter for every page, set on the shared
       MainLayout content container. Pages that nest their own full width
       container zero that container's horizontal padding (in their own style
       blocks) so this gutter is never doubled. */
    .mud-container.usp-page-gutter {
        padding-left: 12px;
        padding-right: 12px;
        /* Tighten the gap under the app bar to match the 12px side gutter (desktop keeps my-4's
           16px). The two-class selector outranks MudBlazor's .my-4 so no !important is needed. */
        margin-top: 12px;
    }

    /* Pages that nest their own MudContainer zero its horizontal padding here so the shared 12px
       gutter above is never doubled (same approach as .usp-form-outer in ReportIncident, but shared
       so any school page can use it). The two-class selector outranks .mud-container, no !important. */
    .mud-container.usp-page-flush {
        padding-left: 0;
        padding-right: 0;
    }

    /* Slimmer app bar on phones. MudBlazor derives both the toolbar height and
       the main content top offset from --mud-appbar-height with the same scaling,
       so overriding them together keeps content clear of the bar with no gap. The
       toolbar also carries a min-height of min(appbar-height, 56px), so that is
       pinned too. The iOS safe-area rules above still add env(safe-area-inset-top)
       on top of this. */
    .mud-appbar .mud-toolbar-appbar {
        height: 52px;
        min-height: 52px;
    }

    .mud-main-content {
        padding-top: 52px;
    }
}
