/* /Components/Blocks/AttentionRail.razor.rz.scp.css */
/* Ink note. AdminTheme's semantic colours are already dark and low-chroma — Warning is
   #B8790A, Error #B33333 — so the earlier habit of mixing them 45-55% toward black left
   near-brown and near-maroon, which is where "subdued" came from. Measured against white:
   Error 6.1:1, Info 5.4:1, Success 5.4:1 all pass as text at full strength, so they are used
   as they are. Only Warning falls short at 3.6:1, and 85% of the hue is the least darkening
   that clears 4.5:1 while still reading amber. */

/* The attention rail.

   auto-fit rather than a fixed column count, because the number of lanes is not known until the
   data arrives: a coordinator holds no fees.view, and on a quiet afternoon there may be one lane
   or none. Columns drop rather than overflow. */

.rail[b-69q1fllhs6] {
    display: grid;
    /* auto-FILL, not auto-fit. auto-fit collapses the empty tracks and shares the whole width
       between whatever lanes exist, so a quiet morning with two lanes drew two enormous cards.
       auto-fill keeps the tracks, so a lane is the same size whether there are four of them
       or one, and the rail reads as a rail rather than as a banner. */
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
    margin-bottom: 20px;
}

.lane[b-69q1fllhs6] {
    position: relative;
    overflow: hidden;
    border-radius: 12px;
    padding: 15px 17px;
    min-height: 108px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-decoration: none;
    color: var(--mud-palette-text-primary);
    transition: border-color .15s;

    /* Every lane is tinted with its own colour, and the colour never changes. */
    --lane: var(--mud-palette-info);
    background: color-mix(in srgb, var(--lane) 11%, var(--mud-palette-surface));
    border: 1px solid color-mix(in srgb, var(--lane) 32%, var(--mud-palette-surface));
}

.lane--register[b-69q1fllhs6] { --lane: var(--mud-palette-warning);
                  --lane-ink: color-mix(in srgb, var(--mud-palette-warning) 85%, #000); }
.lane--fees[b-69q1fllhs6]     { --lane: var(--mud-palette-error); }
.lane--inbox[b-69q1fllhs6]    { --lane: var(--mud-palette-info); }
.lane--calendar[b-69q1fllhs6] { --lane: var(--mud-palette-success); }
/* Jade, the one semantic slot left. Not Primary, which already means "interactive" on every
   other element of this page. It sits nearer the calendar's forest green than five lanes
   would ideally allow — the icon and the kicker carry the difference. */
.lane--adm[b-69q1fllhs6]      { --lane: var(--mud-palette-secondary); }

.lane:hover[b-69q1fllhs6] {
    border-color: var(--mud-palette-primary);
}

.lane:focus-visible[b-69q1fllhs6] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

.lane[b-69q1fllhs6]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 5px;
    background: var(--lane);
}

/* Severity leans in; it never changes the hue. */
.lane--critical[b-69q1fllhs6] {
    background: color-mix(in srgb, var(--lane) 19%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--lane) 50%, var(--mud-palette-surface));
}

.lane--critical[b-69q1fllhs6]::before {
    width: 7px;
}

/* The kicker sits on its own tint, so the hue is mixed toward black to carry small bold text
   at 4.5:1 rather than being used at full strength. */
.lane-kick[b-69q1fllhs6] {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--lane-ink, var(--lane));
}

.lane-head[b-69q1fllhs6] {
    font-size: 16.5px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.28;
}

.lane-sub[b-69q1fllhs6] {
    font-size: 12px;
    color: var(--mud-palette-text-secondary);
}

/* ── quiet morning ──────────────────────────────────────────────────────── */
.rail-clear[b-69q1fllhs6] {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 12px;
    padding: 13px 18px;
    margin-bottom: 20px;
    font-size: 13.5px;
    color: var(--mud-palette-text-secondary);
}

.rail-clear-dot[b-69q1fllhs6] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--mud-palette-success);
    flex: 0 0 auto;
}

.att-card-skeleton[b-69q1fllhs6] {
    border-radius: 12px;
    padding: 15px 17px;
    min-height: 108px;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
}
/* /Components/Blocks/ClassAttendanceStatus.razor.rz.scp.css */
/* Attendance status card.

   One rendering at every width. There used to be two — a MudDataGrid on desktop and a hand-built
   list on phones — which meant the same information was written twice and only one copy could be
   right at a time. A two-line row works at both sizes, so the grid is gone.

   The card no longer carries a hardcoded 500px list either. It fills the height its grid cell
   gives it and the list scrolls inside; that fixed height was what forced the dashboard's left
   column to ~560px and left the quad beside it fighting for room. */

/* The card's own height, flex and overflow live inline on the MudCard rather than here.
   Scoped CSS is stamped onto HTML elements in this file, not onto a child component's root,
   so .att-card would never have matched the element MudCard renders — which is exactly what
   went wrong: the card had no height to fill, .att-list had no flex parent to scroll inside,
   and the whole thing grew to its content and out of its grid cell. */

.att-count[b-liezzfbznn] {
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* ── legend ─────────────────────────────────────────────────────────────── */
/* The shared card head reserves 12px under itself for a body. Here the legend follows
   immediately and belongs to the head, so that gap is taken back. */
.dash-card-head[b-liezzfbznn] {
    margin-bottom: 4px;
}

.att-legend[b-liezzfbznn] {
    display: flex;
    gap: 13px;
    padding: 0 0 6px;
}

.att-legend span[b-liezzfbznn] {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 10.5px;
    color: var(--mud-palette-text-secondary);
}

.att-swatch[b-liezzfbznn] {
    width: 3px;
    height: 11px;
    border-radius: 2px;
    display: block;
}

.att-swatch--todo[b-liezzfbznn]  { background: var(--mud-palette-warning); }
.att-swatch--unver[b-liezzfbznn] { background: var(--mud-palette-info); }
.att-swatch--ok[b-liezzfbznn]    { background: var(--mud-palette-success); }

/* ── the list ───────────────────────────────────────────────────────────── */
/* No overflow of its own. The card body is already the scroll container, and nesting a
   second one here meant the pointer sat over an element that could not scroll while its
   overscroll-behavior:contain stopped the wheel reaching the element that could. The
   scrollbar was visible and the wheel did nothing. */
/* Tight. Twenty-four classes is the normal case, and every pixel of row padding costs a
   class off the bottom of the card. */
.att-list[b-liezzfbznn] {
    padding: 0 0 4px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* Where the to-do list ends. Two pixels of gap separates rows; this separates GROUPS. */
.att-split[b-liezzfbznn] {
    height: 1px;
    background: var(--mud-palette-lines-default);
    margin: 5px 0;
    flex: 0 0 auto;
}

/* The list starts where the card's heading starts.

   No left padding on the row at all, so the accent bar sits on the body's left edge — the
   same x as "Attendance status" above it — instead of the list being stepped in under its own
   heading. A negative margin would have aligned the class NAME rather than the bar, but the
   card body scrolls, and once one axis of overflow is not visible the other clips too: the
   bar would have been shaved off or bought a horizontal scrollbar. */
.att-row[b-liezzfbznn] {
    display: flex;
    align-items: center;
    gap: 9px;
    /* The accent is the row's own left border rather than a span inside it. Same three
       colours, one element fewer, and the rule runs the full height of the row on its own
       instead of needing align-self: stretch to fake it. No radius — a square edge is what
       lets the border read as a rule down the side of the list rather than as a pill. */
    /* Asymmetric on purpose: the chip on the first line needs clearance above it, and the
       sub-line beneath needs less. 6 and 4 rather than 8 and 8 — same breathing room where
       it is wanted, and it buys back the row that the symmetric version cost. */
    padding: 6px 6px 4px 9px;
    border-left: 3px solid transparent;
    transition: background-color .12s;
}

.att-row--todo[b-liezzfbznn]  { border-left-color: var(--mud-palette-warning); }
.att-row--unver[b-liezzfbznn] { border-left-color: var(--mud-palette-info); }
.att-row--ok[b-liezzfbznn]    { border-left-color: var(--mud-palette-success); }
.att-row--off[b-liezzfbznn]   { border-left-color: var(--mud-palette-lines-default); }

.att-row:hover[b-liezzfbznn] {
    background: var(--mud-palette-action-default-hover);
}

/* An unmarked row carries no fill. The amber bar already says it, and so do the chip and the
   bell — three signals for one fact, of which the fill was the loudest and the least precise,
   since it tinted the whole row including the parts that are not the problem. Dropping it also
   buys the height back: with no block of colour to keep compact, the rows can breathe. */

/* The row is a real link, so it is reachable by Tab and opens in a new tab on middle click.
   Remind is a sibling button rather than a nested one — a button inside an anchor is invalid
   and the browser picks a winner for you. */
.att-main[b-liezzfbznn] {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}

.att-text[b-liezzfbznn] {
    flex: 1;
    min-width: 0;
}

/* Figure, tick and chevron as one block, centred against both lines of the row — which is
   what puts them level with the bell beside them. Inside the link, so the whole right-hand
   side still navigates. */
.att-right[b-liezzfbznn] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

.att-main:focus-visible[b-liezzfbznn] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 3px;
    border-radius: 6px;
}

.att-top[b-liezzfbznn] {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.att-top b[b-liezzfbznn] {
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.35;
    flex: 0 0 auto;
}

.att-fig[b-liezzfbznn] {
    font-size: 11.5px;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex: 0 0 auto;
}

.att-go[b-liezzfbznn] {
    color: var(--mud-palette-text-secondary);
    opacity: .5;
    flex: 0 0 auto;
}

.att-row:hover .att-go[b-liezzfbznn] {
    opacity: 1;
    color: var(--mud-palette-primary);
}

/* min-width:0 is what lets the ellipsis engage on a long teacher name. */
.att-sub[b-liezzfbznn] {
    font-size: 10.5px;
    line-height: 1.3;
    color: var(--mud-palette-text-secondary);
    margin-top: 2px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── chips ──────────────────────────────────────────────────────────────── */
.att-chip[b-liezzfbznn] {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 5px;
    flex: 0 0 auto;
    background: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-text-secondary);
}

/* Warning and info at full strength fail contrast under small bold text, so the chip keeps the
   hue as a wash and darkens the ink to carry it. */
.att-chip--todo[b-liezzfbznn] {
    background: color-mix(in srgb, var(--mud-palette-warning) 38%, var(--mud-palette-surface));
    color: color-mix(in srgb, var(--mud-palette-warning) 85%, #000);
}

.att-chip--unver[b-liezzfbznn] {
    background: color-mix(in srgb, var(--mud-palette-info) 32%, var(--mud-palette-surface));
    color: var(--mud-palette-info);
}

/* ── the one action an admin gets ───────────────────────────────────────── */
/* The per-row bell is a plain MudIconButton now, styled by MudBlazor: no border, and the
   default round grey hover. A permanently outlined box on every unmarked row read as a
   form control rather than an action, and repeated the alarm the amber row already raises. */

/* Remind all, in the card head beside the count it acts on. */
.att-remind-all[b-liezzfbznn] {
    flex: 0 0 auto;
    height: 24px;
    padding: 0 9px;
    display: flex;
    align-items: center;
    gap: 5px;
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    background: color-mix(in srgb, var(--mud-palette-warning) 18%, var(--mud-palette-surface));
    border: 1px solid color-mix(in srgb, var(--mud-palette-warning) 45%, var(--mud-palette-surface));
    color: color-mix(in srgb, var(--mud-palette-warning) 85%, #000);
}

.att-remind-all:hover:not(:disabled)[b-liezzfbznn] {
    background: color-mix(in srgb, var(--mud-palette-warning) 30%, var(--mud-palette-surface));
}

.att-remind-all:disabled[b-liezzfbznn] { opacity: .55; cursor: default; }

.att-remind:disabled[b-liezzfbznn] {
    opacity: .55;
    cursor: default;
}

/* Phones: finger-sized, and the figure drops rather than squeezing the class name. */
@media (max-width: 599px) {
    .att-fig[b-liezzfbznn] {
        display: none;
    }
}
/* /Components/Blocks/FeesToday.razor.rz.scp.css */
/* The ledger grid. Two columns of figure-and-label pairs rather than full-width rows: across
   half a dashboard a label/value row leaves the value stranded from its own label. */

.led[b-kvpb8wpoqa] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 15px 18px;
}

.led-k[b-kvpb8wpoqa] {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 4px;
}

.led-v[b-kvpb8wpoqa] {
    font-size: 19px;
    font-weight: 800;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

/* Only the figure that means somebody is owed money takes a colour. */
.led-v--bad[b-kvpb8wpoqa] {
    color: var(--mud-palette-error);
}

.led-recent[b-kvpb8wpoqa] {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.led-row[b-kvpb8wpoqa] {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 3px 0;
}

.led-row-t[b-kvpb8wpoqa] {
    flex: 1;
    min-width: 0;
    font-size: 12.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.led-row-s[b-kvpb8wpoqa] {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* The collection bar, full width across both ledger columns. */
.led-wide[b-kvpb8wpoqa] {
    grid-column: 1 / -1;
}

.meter[b-kvpb8wpoqa] {
    height: 8px;
    border-radius: 5px;
    background: var(--mud-palette-lines-default);
    overflow: hidden;
}

.meter i[b-kvpb8wpoqa] {
    display: block;
    height: 8px;
    border-radius: 5px;
    background: var(--mud-palette-success);
}

.led-meter-note[b-kvpb8wpoqa] {
    font-size: 11.5px;
    color: var(--mud-palette-text-secondary);
    margin-top: 6px;
}

/* Today / month / year sit as one group across the full width: they are the same figure at
   three ranges, so they read as a row rather than as three unrelated tiles. */
.led-spans[b-kvpb8wpoqa] {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}
/* /Components/Blocks/RecentActivity.razor.rz.scp.css */
/* The feed. A dot, then two lines: what happened, and who did it when. */

.feed[b-4gprvwqhgn] {
    display: flex;
    flex-direction: column;
    gap: 11px;
}

.feed-row[b-4gprvwqhgn] {
    display: flex;
    gap: 10px;
}

/* One neutral dot rather than a per-entry icon. The icon was decoration — it told you an
   event had an icon, not what kind of event it was — and it cost four times the width. */
.feed-dot[b-4gprvwqhgn] {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    margin-top: 6px;
    flex: 0 0 auto;
    background: var(--mud-palette-primary);
}

.feed-text[b-4gprvwqhgn] {
    min-width: 0;
}

.feed-text p[b-4gprvwqhgn] {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.35;
}

.feed-text span[b-4gprvwqhgn] {
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Blocks/SchoolMetrics.razor.rz.scp.css */
/* Metric tiles.

   The tiles previously carried `style="flex:1"` inline, which silently beat the flex-basis in
   the media queries below — so they never actually reflowed on a phone and three tiles kept
   sharing one line. All tile styling lives here now; nothing inline is left to override it. */

.metric-row[b-2qw30gfeem] {
    display: flex;
    gap: 0;
}

/* column-reverse puts the caption above the figure without touching the markup: the label is
   what you scan for, and the number is what you then read. It also lets the strip lose a few
   pixels of height, which is the point — this band sits above the attention rail, and the rail
   is the part that asks for a decision, so the rail is what has to clear the fold. */
.metric-tile[b-2qw30gfeem] {
    flex: 1;
    padding: 4px 16px;
    /* min-width:0 stops a long figure from forcing the row wider than its container. */
    min-width: 0;
    border-right: 1px solid var(--mud-palette-lines-default);
}

.metric-k[b-2qw30gfeem] {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 5px;
}

/* Figure and its caption on one line, baseline-aligned: the caption is an annotation on the
   number, not a second fact underneath it. */
.metric-fig[b-2qw30gfeem] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.metric-v[b-2qw30gfeem] {
    font-size: 18px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    flex: 0 0 auto;
}

.metric-v--muted[b-2qw30gfeem] { color: var(--mud-palette-text-secondary); font-weight: 600; }
.metric-v--warn[b-2qw30gfeem]  { color: color-mix(in srgb, var(--mud-palette-warning) 85%, #000); }
.metric-v--good[b-2qw30gfeem]  { color: var(--mud-palette-success); }

.metric-s[b-2qw30gfeem] {
    font-size: 11.5px;
    color: var(--mud-palette-text-secondary);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A square-ish dot rather than a round one: at 8px a circle reads as a bullet, which invites
   you to look for a list. This is a key, not a list marker. */
.metric-dot[b-2qw30gfeem] {
    width: 8px;
    height: 8px;
    border-radius: 2.5px;
    flex: 0 0 auto;
    display: block;
}

.metric-dot--brand[b-2qw30gfeem] { background: var(--mud-palette-primary); }
.metric-dot--good[b-2qw30gfeem]  { background: var(--mud-palette-success); }
.metric-dot--warn[b-2qw30gfeem]  { background: var(--mud-palette-warning); }
.metric-dot--bad[b-2qw30gfeem]   { background: var(--mud-palette-error); }
.metric-dot--info[b-2qw30gfeem]  { background: var(--mud-palette-info); }

/* The divider belongs BETWEEN tiles. Doing it here rather than inline also copes with the
   tile count changing, since several tiles are behind AuthorizeView. */
.metric-row > .metric-tile:last-child[b-2qw30gfeem] {
    border-right: none;
}

.metric-tile--span2[b-2qw30gfeem] {
    flex: 2;
}

/* Today's Attendance: peer figures across, subordinate detail beneath its parent.

   Gaps rather than "|" separators — a pipe spanning a two-line group looks broken, and the
   spacing already reads as separation. align-items:baseline keeps P, A and L on one optical
   line even though only P carries a second row underneath. */
.att-stats[b-2qw30gfeem] {
    display: flex;
    align-items: baseline;
    gap: 14px;
    flex-wrap: wrap;
}

.att-stat[b-2qw30gfeem] {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
}

/* Tablet and below: two per row, with a single rule down the middle. Bottom borders are
   deliberately dropped — with a variable number of tiles they end up dangling under a
   half-empty row. */
@media (max-width: 899px) {
    .metric-row[b-2qw30gfeem] {
        flex-wrap: wrap;
    }

    .metric-tile[b-2qw30gfeem] {
        flex: 1 1 50%;
        box-sizing: border-box;
        border-right: none;
        padding: 8px 12px;
    }

    .metric-row > .metric-tile:nth-child(odd)[b-2qw30gfeem] {
        border-right: 1px solid var(--mud-palette-lines-default);
    }

    /* Today's Attendance carries four figures — give it the whole row so P/A/L/Lt stay on
       one line instead of breaking with the separators stranded at the line ends. */
    .metric-tile--wide[b-2qw30gfeem] {
        flex: 1 1 100%;
        border-right: none !important;
    }
}

/* Narrow phones: one per row, no vertical rules. */
@media (max-width: 479px) {
    .metric-tile[b-2qw30gfeem] {
        flex: 1 1 100%;
    }

    .metric-row > .metric-tile:nth-child(odd)[b-2qw30gfeem] {
        border-right: none;
    }
}

/* "39/42" — same size as the figure, weight and ink carry the difference. Shrinking the
   denominator made the pair read as two unrelated numbers. */
.metric-of[b-2qw30gfeem] {
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Blocks/UpcomingEvents.razor.rz.scp.css */
/* Upcoming events.

   A date block beside a two-line entry. The date is the thing you scan the card for, so it is
   the only part that gets a box of its own. */

.ev-list[b-zwoxl01f5d] {
    display: flex;
    flex-direction: column;
    gap: 11px;
}

.ev[b-zwoxl01f5d] {
    display: flex;
    gap: 12px;
    align-items: center;
}

.ev-when[b-zwoxl01f5d] {
    width: 40px;
    flex: 0 0 auto;
    text-align: center;
    border-radius: 8px;
    padding: 4px 0;
    background: color-mix(in srgb, var(--mud-palette-primary) 12%, var(--mud-palette-surface));
}

.ev-when b[b-zwoxl01f5d] {
    display: block;
    font-size: 14px;
    font-weight: 800;
    line-height: 1.1;
    color: color-mix(in srgb, var(--mud-palette-primary) 78%, #000);
}

.ev-when i[b-zwoxl01f5d] {
    display: block;
    font-size: 9.5px;
    font-style: normal;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* A closed day is not a thing to look forward to, so it steps back to neutral rather than
   wearing the brand colour like an event you are meant to prepare for. */
.ev-when--off[b-zwoxl01f5d] {
    background: var(--mud-palette-action-default-hover);
}

.ev-when--off b[b-zwoxl01f5d] {
    color: var(--mud-palette-text-secondary);
}

.ev-what[b-zwoxl01f5d] {
    min-width: 0;
}

.ev-what p[b-zwoxl01f5d] {
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.3;
}

.ev-what span[b-zwoxl01f5d] {
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-xy7j2745ei] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-xy7j2745ei] {
    flex: 1;
}

.sidebar[b-xy7j2745ei] {
    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row[b-xy7j2745ei] {
    background-color: #f7f7f7;
    border-bottom: 1px solid #d6d5d5;
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    .top-row[b-xy7j2745ei]  a, .top-row[b-xy7j2745ei]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
    }

    .top-row[b-xy7j2745ei]  a:hover, .top-row[b-xy7j2745ei]  .btn-link:hover {
        text-decoration: underline;
    }

    .top-row[b-xy7j2745ei]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 640.98px) {
    .top-row[b-xy7j2745ei] {
        justify-content: space-between;
    }

    .top-row[b-xy7j2745ei]  a, .top-row[b-xy7j2745ei]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-xy7j2745ei] {
        flex-direction: row;
    }

    .sidebar[b-xy7j2745ei] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .top-row[b-xy7j2745ei] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-xy7j2745ei]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-xy7j2745ei], article[b-xy7j2745ei] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

#blazor-error-ui[b-xy7j2745ei] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-xy7j2745ei] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Section labels between nav groups */
.nav-section-label[b-nu3u9vhjjf] {
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--mud-palette-text-disabled);
    padding: 18px 20px 5px;
    pointer-events: none;
    user-select: none;
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* Dashboard layout.

   Figures, then decisions, then detail: the metric strip is read, the attention rail is acted
   on, and the cards below are where you go to look something up. Each of those three is a
   band across the full width, with a label over the ones that are not self-evident.

   The cards themselves are not styled here. They share one anatomy that lives in
   wwwroot/css/app.css, because the class sits on the card element INSIDE each block and a
   component's scope attribute is stamped only on its own markup — a scoped rule here could
   never reach it. */

/* Section labels. Without them the rail and the cards below read as one undifferentiated
   field of boxes; the label is what says "this part is asking you for something, that part is
   there to be looked up". Small, spaced and quiet — a signpost, not a heading. */
.dash-label[b-7gjmti4zh7] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    margin: 0 0 8px;
}

/* Paired lanes.

   Two equal columns rather than the old 5/7 split wrapped around a 2x2 quad. The quad handed
   four cards the same quarter of the screen whatever they held, which is how a register of
   twenty-four classes came to share its billing with a four-link shortcut panel.

   Every track is minmax(0, …) deliberately. A bare `1fr` is `minmax(auto, 1fr)`, and that
   `auto` floor is the min-content size of the card in it — so the track never caps the card,
   the card pushes the track past its share, and the row spills over whatever sits below. That
   is the card-on-card overlap. minmax(0, …) drops the floor; the card's own `min-height: 0`
   and `overflow` in app.css keep the content inside it.

   The height is stated here rather than left to the tallest card, because how much of the
   fold the dashboard spends is a page decision. */
.dash-lanes[b-7gjmti4zh7] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: minmax(0, 1fr);
    gap: 16px;
    /* Sized to the row: seven classes visible, with the eighth just showing at the cut so
       the list reads as scrollable. 420 was too short at 8px symmetric padding and 460 more
       than the 6/4 row needs, which is why it went up and has come back. */
    height: 420px;
    margin-bottom: 16px;
}

/* Activity and upcoming events are reference, not work in hand, so they get the shorter row. */
.dash-lanes--short[b-7gjmti4zh7] {
    height: 260px;
}

/* The coordinator board has no second lane beside the register. */
.dash-single[b-7gjmti4zh7] {
    height: 460px;
    margin-bottom: 16px;
}

/* Tablet: two lanes side by side stop earning their keep. Stacked, each needs its own
   height back — they can no longer share one row's worth. */
@media (max-width: 1279px) {
    .dash-lanes[b-7gjmti4zh7] {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto;
        height: auto;
    }

    .dash-lanes > *[b-7gjmti4zh7] {
        height: 420px;
    }

    .dash-lanes--short > *[b-7gjmti4zh7] {
        height: 280px;
    }
}

/* Phone: one long page beats a column of little scroll wells, so every card sizes to its
   content and the page scrolls instead. */
@media (max-width: 767px) {
    .dash-lanes > *[b-7gjmti4zh7],
    .dash-lanes--short > *[b-7gjmti4zh7],
    .dash-single[b-7gjmti4zh7] {
        height: auto;
    }
}
/* /Components/Pages/Settings/SchoolInfo.razor.rz.scp.css */
/* Each tab panel's MudGrid carries a negative top margin (MudBlazor offsets the item
   gutters that way). As the panel's top child it bleeds up over the tab bar and steals
   hover/clicks from the lower half of the tab headers. Lift the bar above that bleed so
   the whole header stays interactive. */
[b-lx743hr70n] .mud-tabs-tabbar {
    position: relative;
    z-index: 1;
}
