/* School system — app-specific styles. The look (tokens, shell, Tabler
   re-skin) lives in design.css; keep this file for the few things that
   belong to this app only. Use Bootstrap/Tabler utility classes first. */

/* Dashboard quick actions */
.quick-action .avatar { width: 3.25rem; height: 3.25rem; }
.quick-action:focus-visible { outline: 2px solid var(--tw-primary); outline-offset: 2px; }

/* Profile header used by detail pages. */
.profile-photo {
    width: 5.5rem;
    height: 5.5rem;
    object-fit: cover;
    border-radius: var(--tw-radius-card);
}

/* Wide data-entry grids (scores, skills, attendance) keep their header row in view. */
.grid-sticky thead th { position: sticky; top: 0; z-index: 2; background: var(--tw-surface); }
.grid-sticky td:first-child, .grid-sticky th:first-child { position: sticky; left: 0; z-index: 1; background: var(--tw-surface-raised); }

/* HTMX: thin progress bar along the top while a request runs. */
.htmx-progress {
    position: fixed;
    top: 0;
    inset-inline-start: 0;
    height: 3px;
    width: 0;
    background: var(--tw-accent);
    z-index: 2000;
    opacity: 0;
    transition: width .4s ease, opacity .3s ease;
}
body.htmx-busy .htmx-progress { width: 70%; opacity: 1; transition: width 4s cubic-bezier(.1, .7, .3, 1); }
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { display: inline-block; }

.notification-menu { width: min(22rem, 92vw); }

/* ---------- Photos ----------
   One frame for every person photo (partials/components/photo.html).
   Photos are stored as 3:4 portraits; object-position keeps the face in
   view when a round avatar crops them. */
.tw-photo {
    display: inline-flex;
    flex-shrink: 0;
    overflow: hidden;
    background: #E4E8F0;
    vertical-align: middle;
}
.tw-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; display: block; }
.tw-photo-xs { width: 28px; height: 28px; border-radius: 50%; }
.tw-photo-sm { width: 36px; height: 36px; border-radius: 50%; }
.tw-photo-md { width: 48px; height: 48px; border-radius: 50%; box-shadow: 0 0 0 2px var(--tw-surface-raised, #fff); }
.tw-photo-lg, .tw-photo-xl {
    border-radius: 14px;
    border: 4px solid #fff;
    box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.08), 0 10px 28px rgba(15, 23, 42, 0.16);
}
.tw-photo-lg { width: 96px; height: 128px; }
.tw-photo-xl { width: 150px; height: 200px; border-radius: 18px; }
[data-bs-theme="dark"] .tw-photo-lg, [data-bs-theme="dark"] .tw-photo-xl { border-color: #2A3040; }
@media (max-width: 575.98px) { .tw-photo-xl { width: 120px; height: 160px; } }

/* ---------- Student profile dashboard ---------- */
.pd-stat .card-body { position: relative; padding: 18px 20px; }
.pd-stat-label { font-size: 12px; font-weight: 600; color: var(--tw-muted); margin-bottom: 4px; padding-right: 44px; }
.pd-stat-value { font-size: 22px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; padding-right: 44px; overflow-wrap: anywhere; }
.pd-stat-note { font-size: 12px; color: var(--tw-muted); margin-top: 4px; }
.pd-stat-icon {
    position: absolute; top: 16px; right: 16px; width: 38px; height: 38px; border-radius: 12px;
    display: inline-flex; align-items: center; justify-content: center; font-size: 18px;
}
@media (max-width: 575.98px) { .pd-stat-value { font-size: 18px; padding-right: 0; } .pd-stat-icon { display: none; } }

.pd-ring {
    width: 146px; height: 146px; padding: 2px; border-radius: 50%;
    background: var(--tw-primary, var(--brand-primary));
}
.tw-photo-ring { width: 142px; height: 142px; border-radius: 50%; border: 4px solid var(--tw-surface-raised, #fff); }
.pd-name { font-size: 20px; font-weight: 700; line-height: 1.25; }
.pd-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; border-top: 1px solid var(--tw-border); padding-top: 12px; }
.pd-facts dt { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--tw-muted); }
.pd-facts dd { margin: 0; font-weight: 600; }
.pd-contact { background: color-mix(in srgb, var(--brand-primary) 6%, transparent); border-radius: 12px; padding: 10px 12px; }
.pd-icon-btn {
    width: 40px; height: 40px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
    color: var(--brand-primary); background: color-mix(in srgb, var(--brand-primary) 9%, transparent);
    font-size: 17px; text-decoration: none; transition: background .15s, color .15s, transform .15s;
}
.pd-icon-btn:hover { background: var(--brand-primary); color: #fff; transform: translateY(-1px); }

.pd-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 10px; }
.pd-tile {
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px;
    padding: 12px 8px; border: 1px solid var(--tw-border); border-radius: 14px; color: inherit; text-decoration: none;
    background: var(--tw-surface); transition: border-color .15s, box-shadow .15s;
}
a.pd-tile:hover { border-color: var(--brand-primary); box-shadow: 0 6px 16px rgba(15, 23, 42, .08); }
.pd-tile-name { font-weight: 600; font-size: 13px; line-height: 1.2; }
.pd-tile-note { font-size: 12px; color: var(--tw-muted); line-height: 1.2; }
.pd-tile-icon { width: 40px; height: 40px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 18px; }

.pd-calendar { background: var(--brand-primary); color: var(--brand-on-primary, #fff); border: 0; }
.pd-calendar .card-title { color: inherit; }
:root.glass .card.pd-calendar { background-color: color-mix(in srgb, var(--brand-primary) 90%, transparent); }
.pd-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; text-align: center; }
.pd-cal-head { font-size: 11px; font-weight: 600; opacity: .7; padding: 4px 0; }
.pd-cal-day {
    font-size: 12px; font-weight: 600; line-height: 30px; height: 30px; border-radius: 9px;
    background: rgba(255, 255, 255, .08); font-variant-numeric: tabular-nums;
}
.pd-cal-day.is-none { opacity: .55; background: transparent; }
.pd-cal-day.is-present { background: rgba(47, 179, 68, .9); color: #fff; }
.pd-cal-day.is-absent { background: #F9C6A8; color: #7A2E0B; }
.pd-cal-day.is-today { box-shadow: 0 0 0 2px #fff inset; }
.pd-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.pd-dot.is-present { background: #2fb344; }
.pd-dot.is-absent { background: #F9C6A8; }

.pd-pill { font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 8px; flex-shrink: 0; }
.pd-pill.is-paid { background: #D3F4DC; color: #1B7A35; }
.pd-pill.is-part { background: #FFF1D0; color: #8A5A00; }
.pd-pill.is-due { background: #FDE0CF; color: #A23E0B; }
[data-bs-theme="dark"] .pd-pill.is-paid { background: rgba(47, 179, 68, .2); color: #7EE29A; }
[data-bs-theme="dark"] .pd-pill.is-part { background: rgba(245, 159, 0, .2); color: #FFD27A; }
[data-bs-theme="dark"] .pd-pill.is-due { background: rgba(253, 126, 20, .2); color: #FFB48A; }

/* All tabs visible: they wrap onto a second line instead of scrolling. */
.pd-tabs { flex-wrap: wrap; row-gap: 2px; }
.pd-tabs .nav-link { white-space: nowrap; }
@media (max-width: 575.98px) {
    .pd-tabs .nav-item { flex: 1 1 50%; }
    .pd-tabs .nav-link { justify-content: flex-start; }
}
@media print {
    .pd-calendar { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .pd-icon-btn { display: none; }
}

/* ---------- Money figures always on one line ----------
   Figures shrink with their card (container query units) instead of
   wrapping or being cut off with "...". */
.pd-stat .card-body, .stat-card .card-body, .tw-kpi-card { container-type: inline-size; }
.pd-stat-value {
    white-space: nowrap; overflow-wrap: normal;
    font-size: clamp(13px, calc(10cqi - 5px), 24px);
}
/* Browsers without container queries (some school computers, seen over Tailscale
   2026-10-17): the figure may wrap and never runs out of its card. */
@supports not (container-type: inline-size) {
    .pd-stat-value, .stat-card .tw-fit-value, .tw-kpi-value { white-space: normal; overflow-wrap: anywhere; font-size: 18px; }
}
.pd-stat .card-body, .stat-card .card-body { min-width: 0; overflow: hidden; }
.stat-card .tw-fit-value, .tw-kpi-value {
    white-space: nowrap; overflow: visible; text-overflow: clip;
    font-size: clamp(13px, calc(9cqi - 4px), 22px);
}

/* Long forms split into steps (app.js): one screen at a time. */
[data-step-hidden] { display: none !important; }
.tw-form-steps .step-item { cursor: pointer; text-decoration: none; color: inherit; }
.tw-step-nav .btn { min-width: 7rem; }
/* A step taller than the screen keeps Back / Next in reach at the bottom. */
.tw-stepped .tw-step-nav {
    position: sticky; bottom: 0; z-index: 5;
    padding: .5rem; border-radius: 10px;
    background: color-mix(in srgb, var(--tblr-body-bg) 80%, transparent);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
@media (max-width: 575.98px) {
    .tw-form-steps .step-item:not(.active) { font-size: 0; }   /* numbers only on phones */
    .tw-form-steps .step-item.active { flex-basis: 40%; }
}


/* Scuola, the system's own logo (partials/scuola_logo.html): footer and sign-in. */
.tw-powered { display: inline-flex; align-items: center; gap: .4rem; color: var(--tblr-secondary); font-size: .75rem; text-decoration: none; }
.tw-powered:hover { color: var(--tblr-secondary); opacity: .85; }
.tw-powered.justify-content-center { display: flex; }
.tw-scuola-logo { width: auto; display: inline-block; }
.tw-scuola-dark { display: none; }
[data-bs-theme="dark"] .tw-scuola-light { display: none; }
[data-bs-theme="dark"] .tw-scuola-dark { display: inline-block; }

/* Demonstration notice (tenancy/partials/subscription_banner.html): one slim line, the link on the
   right; on phones only a short label shows, cut with "…" rather than wrapping. */
.tw-demo-banner { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 7px 16px; font-size: 13px; line-height: 1.4; }
.tw-demo-banner-text { min-width: 0; }
.tw-demo-banner .alert-link { flex-shrink: 0; white-space: nowrap; }
@media (max-width: 767.98px) {
  .tw-demo-banner { justify-content: flex-start; }
  .tw-demo-banner-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* Accounting hub (Phase 58, templates/finance/accounting.html): the money cycles as steps joined by arrows. */
.tw-acc-search { position: relative; }
.tw-acc-search .bi { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--tw-muted); pointer-events: none; }
.tw-acc-search .form-control { padding-left: 2.3rem; min-width: 0; width: 100%; height: 44px; }
.tw-acc-new { padding: .5rem; }
@media (min-width: 768px) { .tw-acc-new.show { display: flex; gap: .25rem; } }
.tw-acc-new-col { min-width: 13rem; }
/* Money cycles (2026-10-29, reviewed for a professional finish). Each cycle is its own white panel on the card's
   grey, headed by a grey band (user: "use grey for tab color") with the icon in the school's colour. Its steps sit on one grid shared by every cycle, so tiles are the
   same size and line up from cycle to cycle; an arrow in the gap joins them. A tile holds its name and one line:
   what is waiting there (a soft coloured pill) or else what the step is for. The cycle's other pages follow in a
   row of links. */
.tw-acc-flow { overflow: hidden; }
.tw-acc-flow > .card-body { display: flex; flex-direction: column; gap: .85rem; padding: .85rem !important; background: var(--tw-surface); }
.tw-acc-lane, .tw-acc-lane:first-child {
    --lane: var(--brand-primary, #206bc4);
    display: block; border: 1px solid var(--tw-border); border-radius: var(--tw-radius-card); overflow: hidden;
    background: var(--tw-surface-raised); box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}
.tw-acc-lane-title {
    display: flex; align-items: center; gap: .6rem; padding: .8rem 1rem;
    font-size: .95rem; font-weight: 700; letter-spacing: 0; text-transform: none;
    background: #eceff3; color: var(--tw-text); border-bottom: 1px solid var(--tw-border);
}
.tw-acc-lane-title .bi {
    width: 1.75rem; height: 1.75rem; border-radius: .5rem; display: inline-flex; align-items: center; justify-content: center;
    font-size: .95rem; background: var(--lane); color: var(--brand-on-primary, #fff);
}
[data-bs-theme="dark"] .tw-acc-lane-title {
    background: #262b36; color: var(--tw-text);
}
.tw-acc-lane-body { padding: .9rem 1rem 1rem; min-width: 0; }
.tw-acc-steps {
    list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem 1.4rem;
    grid-template-columns: repeat(var(--steps, 4), minmax(0, 1fr));
}
.tw-acc-steps li { position: relative; display: flex; min-width: 0; max-width: none; flex: none; }
.tw-acc-steps li + li::before {
    content: "\f285"; font-family: "bootstrap-icons"; position: absolute; left: -1.1rem; top: 50%; transform: translateY(-50%);
    margin: 0; font-size: .8rem; color: var(--tw-muted); opacity: .8;
}
.tw-acc-step {
    display: flex; align-items: center; gap: .6rem; width: 100%; height: 100%; min-width: 0; padding: .6rem .7rem;
    border: 1px solid var(--tw-border); border-radius: var(--tw-radius-card); background: #f7f8fa;
    color: var(--tw-text); text-decoration: none; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.tw-acc-step:hover, .tw-acc-step:hover * { text-decoration: none; }
.tw-acc-step:hover { background: var(--tw-surface-raised); }
[data-bs-theme="dark"] .tw-acc-step { background: #1f2430; }
.tw-acc-step:hover { border-color: var(--lane); box-shadow: var(--tw-shadow-md); transform: translateY(-1px); color: var(--tw-text); }
.tw-acc-step-icon {
    width: 2rem; height: 2rem; flex-shrink: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    font-size: .95rem; background: color-mix(in srgb, var(--lane) 10%, transparent); color: var(--lane);
}
.tw-acc-step-text { display: flex; flex-direction: column; flex: 1 1 0; min-width: 0; line-height: 1.25; }
.tw-acc-step-label { font-weight: 600; font-size: .85rem; }
.tw-acc-step-hint { font-size: .75rem; color: var(--tw-muted); margin-top: .1rem; }
.tw-acc-queue {
    align-self: flex-start; max-width: 100%; margin-top: .25rem; padding: .1rem .5rem; border-radius: .4rem;
    font-size: .7rem; font-weight: 600; line-height: 1.35; font-variant-numeric: tabular-nums;
    color: var(--tw-muted); background: var(--tw-surface);
}
.tw-acc-queue::before {
    content: ""; display: inline-block; vertical-align: middle; width: .4rem; height: .4rem;
    margin: -.1rem .35rem 0 0; border-radius: 50%; background: currentColor;
}
.tw-acc-step.is-ok .tw-acc-queue { color: #2b8a3e; background: rgba(47, 158, 68, .1); }
.tw-acc-step.is-info .tw-acc-queue { color: #1971c2; background: rgba(28, 126, 214, .1); }
.tw-acc-step.is-warn .tw-acc-queue { color: #b35c00; background: rgba(245, 159, 0, .14); }
.tw-acc-step.is-danger .tw-acc-queue { color: #c92a2a; background: rgba(224, 49, 49, .1); }
.tw-acc-more {
    display: flex; flex-wrap: wrap; gap: .3rem 1.1rem; margin-top: .8rem; padding-top: .65rem;
    border-top: 1px solid var(--tw-border); font-size: .8125rem;
}
.tw-acc-more::before { content: "More:"; color: var(--tw-muted); }
.tw-acc-more a { white-space: nowrap; }
@media (max-width: 991.98px) { .tw-acc-steps { grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); } }
@media (max-width: 575.98px) {
    .tw-acc-steps { grid-template-columns: 1fr; gap: 1.1rem; }
    .tw-acc-steps li + li::before { content: "\f282"; left: 50%; top: -.95rem; transform: translateX(-50%); }
}
/* Account balances grouped like a balance sheet. */
.tw-acc-group {
    padding: .5rem 1rem .3rem; font-size: .7rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
    color: var(--tw-muted); border-bottom: 1px solid var(--tw-border);
}
.tw-acc-group:not(:first-child) { border-top: 1px solid var(--tw-border); margin-top: -1px; }
.tw-acc-balances .list-group-item { padding-top: .6rem; padding-bottom: .6rem; }
.tw-acc-total { font-size: 1rem; }
.tw-acc-balances .list-group-item { display: flex; justify-content: space-between; gap: 1rem; }
.tw-acc-balances .money { font-variant-numeric: tabular-nums; white-space: nowrap; }
.tw-acc-subtotal { font-weight: 700; background: var(--tw-surface); }
.tw-acc-report-list li { padding: .2rem 0; }
.tw-acc-report-list a { color: var(--tw-text); text-decoration: none; }
.tw-acc-report-list a:hover { color: var(--tw-primary); text-decoration: underline; }
@media (max-width: 767.98px) {
    .tw-acc-search .form-control { min-width: 0; }
}

/* A page inside a pop-up frame (html.tw-in-frame, set in layouts/app.html): the page alone. */
html.tw-in-frame .tw-sidebar, html.tw-in-frame .tw-sidebar-scrim, html.tw-in-frame .tw-navbar,
html.tw-in-frame .tw-footer, html.tw-in-frame .tw-breadcrumbs, html.tw-in-frame .tw-page-title,
html.tw-in-frame .tw-workspace-tabs, html.tw-in-frame form[action$="/pin/"],
html.tw-in-frame [data-bs-target="#page-help"] { display: none !important; }   /* only the page that was clicked */
html.tw-in-frame .tw-tab-content { border-top-left-radius: var(--tw-radius-card); }
html.tw-in-frame .tw-shell, html.tw-in-frame.sidebar-collapsed .tw-shell { display: block; }
html.tw-in-frame .tw-main { min-height: 0; }
html.tw-in-frame .tw-content { padding: 16px 20px 24px; max-width: none; }
html.tw-in-frame body { background: var(--tw-surface-raised); }

/* The Accounting page's pop-up (templates/finance/accounting.html, static/js/app.js "Pages in a pop-up frame"). */
.tw-frame-modal .modal-dialog { max-width: min(1200px, 96vw); }
.tw-frame-modal .modal-content { height: min(88vh, 960px); overflow: hidden; }
.tw-frame-modal .modal-header { gap: .5rem; padding: .75rem 1rem; }
.tw-frame-modal .modal-header .btn-close { position: static; margin: 0 0 0 .25rem; }   /* Tabler pins it to the corner */
.tw-frame-modal .modal-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-frame-modal .modal-body { padding: 0; position: relative; flex: 1; min-height: 0; }
.tw-frame-modal iframe { border: 0; width: 100%; height: 100%; display: block; background: var(--tw-surface-raised); }
.tw-frame-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--tw-surface-raised); }
@media (max-width: 575.98px) { .tw-frame-modal .modal-content { height: 100%; } }


/* Budget editor (Phase 59, templates/expenses/budgets/edit.html, static/js/budget.js), laid out like QuickBooks Online. */
.tw-bud-head { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; }
.tw-bud-name { display: flex; align-items: center; gap: .5rem; min-width: 0; flex: 1; }
.tw-bud-name h1 { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-bud-name input { max-width: 28rem; }
html.tw-in-frame .tw-bud-close { display: none; }      /* the pop-up has its own close */
.tw-bud-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem 1.5rem; margin-bottom: 1rem; }
.tw-bud-controls .form-select { min-width: 14rem; }
.tw-bud-compare { padding-bottom: .45rem; }
.tw-bud-views .btn.active { background: var(--tw-secondary); color: #fff; border-color: var(--tw-secondary); }
.tw-bud-card { overflow: hidden; }
.tw-bud-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; padding: .6rem .75rem; border-bottom: 1px solid var(--tw-border); }
.tw-bud-find { position: relative; }
.tw-bud-find .bi { position: absolute; left: .55rem; top: 50%; transform: translateY(-50%); color: var(--tw-muted); }
.tw-bud-find input { padding-left: 1.8rem; width: 15rem; }
.tw-bud-status { white-space: nowrap; }
.tw-bud-scroll { overflow: auto; max-height: calc(100vh - 21rem); min-height: 18rem; }
html.tw-in-frame .tw-bud-scroll { max-height: calc(100vh - 17rem); }
.tw-bud-grid { border-collapse: separate; border-spacing: 0; width: max-content; font-size: .8125rem; font-variant-numeric: tabular-nums; }
.tw-bud-grid th, .tw-bud-grid td { border-bottom: 1px solid var(--tw-border); padding: 0 .4rem; height: 2.5rem; white-space: nowrap; background: var(--tw-surface-raised); }
.tw-bud-grid thead th { position: sticky; top: 0; z-index: 3; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .02em;
    color: var(--tw-muted); background: var(--tw-surface); vertical-align: middle; }
.tw-bud-check { position: sticky; left: 0; z-index: 2; width: 2.5rem; text-align: center; }
.tw-bud-acc { position: sticky; left: 2.5rem; z-index: 2; min-width: 15rem; max-width: 15rem; overflow: hidden; text-overflow: ellipsis;
    border-right: 1px solid var(--tw-border); }
thead .tw-bud-check, thead .tw-bud-acc { z-index: 4; }
.tw-bud-ref { min-width: 7rem; text-align: right; color: var(--tw-muted); background: var(--tw-surface) !important; }
.tw-bud-total { min-width: 8.5rem; text-align: right; border-right: 1px solid var(--tw-border); }
.tw-bud-num { min-width: 7rem; text-align: right; }
.tw-bud-row .tw-bud-acc { padding-left: 1.6rem; }
.tw-bud-acc-name { overflow: hidden; text-overflow: ellipsis; }
.tw-bud-hint { display: block; font-size: .65rem; color: var(--tw-muted); line-height: 1; margin-top: -.15rem; }
.tw-bud-group td { background: var(--tw-surface); font-weight: 700; }
.tw-bud-toggle { border: 0; background: none; padding: 0; font-weight: 700; color: var(--tw-text); display: inline-flex; align-items: center; gap: .4rem; }
.tw-bud-sum td { font-weight: 700; border-top: 1px solid var(--tw-text); text-align: right; }
.tw-bud-sum .tw-bud-acc, .tw-bud-net .tw-bud-acc { text-align: left; }
.tw-bud-net td { font-weight: 700; text-align: right; position: sticky; bottom: 0; z-index: 1; background: var(--tw-surface); border-top: 2px solid var(--tw-text); }
.tw-bud-net .tw-bud-check, .tw-bud-net .tw-bud-acc { z-index: 3; }
.tw-bud-input { width: 6.5rem; height: 1.9rem; border: 1px solid color-mix(in srgb, var(--tw-border) 60%, transparent); border-radius: 4px; background: transparent; text-align: right;
    padding: 0 .4rem; font: inherit; color: var(--tw-text); }
.tw-bud-row:hover .tw-bud-input { border-color: var(--tw-border); background: var(--tw-surface-raised); }
.tw-bud-input:focus { outline: none; border-color: var(--tw-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--tw-success) 25%, transparent); background: var(--tw-surface-raised); }
.tw-bud-total-cell { display: flex; align-items: center; justify-content: flex-end; gap: .25rem; }
.tw-bud-total .tw-bud-input { width: 7.5rem; }
.tw-bud-split { flex-shrink: 0; width: 1.4rem; height: 1.4rem; border-radius: 50%; border: 0; background: var(--tw-info); color: #fff;
    display: inline-flex; align-items: center; justify-content: center; font-size: .7rem; padding: 0; }
.tw-bud-refline { display: block; font-size: .65rem; color: var(--tw-muted); text-align: right; padding-right: .45rem; margin-top: -.25rem; line-height: 1; }
.tw-bud-foot { display: flex; align-items: center; gap: 1rem; margin-top: 1rem; }
/* Every line grid (expenses, bills, requisitions, LPOs, Pay bills, budget by item) looks like the
   budget grid (product owner, 2026-10-29); .tw-grid gives any other table of figures to
   type in the same look (fee structures, payments, opening balances, salaries, stock take...). */
.tw-bud-items, .tw-lines, .tw-grid { width: 100%; margin: 0; border-collapse: separate; border-spacing: 0; font-size: .8125rem; font-variant-numeric: tabular-nums; }
.tw-bud-items th, .tw-bud-items td, .tw-lines th, .tw-lines td, .tw-grid th, .tw-grid td { border-bottom: 1px solid var(--tw-border) !important; padding: 0 .4rem !important; height: 2.5rem; vertical-align: middle;
    background: var(--tw-surface-raised); }
.tw-bud-items thead th, .tw-lines thead th, .tw-grid thead th { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--tw-muted); background: var(--tw-surface);
    white-space: nowrap; }
.tw-bud-items .form-control, .tw-bud-items .form-select, .tw-lines .form-control, .tw-lines .form-select, .tw-grid .form-control, .tw-grid .form-select { height: 1.9rem; min-height: 0; padding-top: 0; padding-bottom: 0; font: inherit; border-radius: 4px;
    border-color: color-mix(in srgb, var(--tw-border) 60%, transparent); background-color: transparent; }
.tw-bud-items tr:hover .form-control, .tw-bud-items tr:hover .form-select, .tw-lines tr:hover .form-control, .tw-lines tr:hover .form-select, .tw-grid tr:hover .form-control, .tw-grid tr:hover .form-select { border-color: var(--tw-border); background-color: var(--tw-surface-raised); }
.tw-bud-items .form-control:focus, .tw-bud-items .form-select:focus, .tw-lines .form-control:focus, .tw-lines .form-select:focus, .tw-grid .form-control:focus, .tw-grid .form-select:focus { border-color: var(--tw-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--tw-success) 25%, transparent);
    background-color: var(--tw-surface-raised); }
.tw-bud-items .tw-lines-no, .tw-lines .tw-lines-no { color: var(--tw-muted); text-align: center; }
.tw-bud-items tfoot td { font-weight: 700; border-top: 1px solid var(--tw-text); text-align: right; white-space: nowrap; }
.tw-bud-summary td, .tw-bud-summary th { white-space: nowrap; }
/* A row editor in the grid look: the column headings name the fields, so each cell shows only its box. */
.tw-grid-bare td .form-label, .tw-grid-bare td .form-text { display: none; }
.tw-grid-bare td .mb-3, .tw-grid-bare td .mb-2 { margin-bottom: 0 !important; }
.tw-grid-bare td select[multiple] { height: auto; min-height: 1.9rem; }
@media (max-width: 767.98px) {
    .tw-bud-acc { min-width: 10rem; max-width: 10rem; }
    .tw-bud-find input { width: 11rem; }
    .tw-bud-foot { flex-direction: column; align-items: stretch; }
}
@media print {
    .tw-bud-toolbar, .tw-bud-controls .tw-bud-views, .tw-bud-foot, [data-name-edit], .tw-bud-close, .tw-bud-check { display: none !important; }
    .tw-bud-scroll { max-height: none; overflow: visible; }
    .tw-bud-acc { position: static; }
    .tw-bud-input { border: 0 !important; }
}

/* Budget reports (templates/expenses/budgets/vs_actuals.html, overview.html). */
.tw-bva { font-variant-numeric: tabular-nums; font-size: .8125rem; }
.tw-bva th { white-space: nowrap; }
.tw-bva .tw-bva-acc { position: sticky; left: 0; background: var(--tw-surface-raised); min-width: 13rem; z-index: 1; }
.tw-bva-period { border-left: 1px solid var(--tw-border); }
.tw-bva-group td { font-weight: 700; background: var(--tw-surface); }
.tw-bva-total td { font-weight: 700; border-top: 1px solid var(--tw-text); }
.tw-bva-net td { font-weight: 700; border-top: 2px solid var(--tw-text); background: var(--tw-surface); }
.tw-bva-pct { color: var(--tw-muted); }


/* Transaction forms (Phase 60, QuickBooks' Expense and the purchase request): header, big amount, line grid. */
.tw-txn { overflow: visible; }
.tw-txn-head { display: flex; gap: 1.5rem; padding: 1.25rem; border-bottom: 1px solid var(--tw-border); background: var(--tw-surface); border-radius: var(--tw-radius-card) var(--tw-radius-card) 0 0; }
.tw-txn-fields { flex: 1; min-width: 0; }
.tw-txn-amount { text-align: right; min-width: 12rem; }
.tw-txn-amount-label { font-size: .7rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--tw-muted); }
.tw-txn-amount-value { font-size: 2rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2; }
.tw-txn-section { padding: 1.25rem; border-bottom: 1px solid var(--tw-border); }
.tw-txn-title { font-size: 1rem; font-weight: 600; margin-bottom: .75rem; }
.tw-txn-total { font-size: 1rem; font-variant-numeric: tabular-nums; }
.tw-txn-foot { display: flex; align-items: center; gap: .75rem; padding: 1rem 1.25rem; }
.tw-lines { margin-bottom: 0; }
.tw-lines th { font-size: .7rem; text-transform: uppercase; letter-spacing: .03em; color: var(--tw-muted); white-space: nowrap; }
.tw-lines td { vertical-align: middle; padding: .35rem .4rem; }
.tw-lines-no { width: 2.5rem; text-align: center; color: var(--tw-muted); }
.tw-lines-acc { min-width: 13rem; }
.tw-lines-amt { width: 10rem; }
.tw-lines-qty { width: 6rem; }
.tw-lines-budget { min-width: 13rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tw-line-left { font-weight: 600; color: var(--tw-success); }
.tw-lines-del { width: 3rem; text-align: center; }
/* Phase 61: requisitions paid on an expense, petty cash, budget status */
.tw-lines-req { min-width: 11rem; font-variant-numeric: tabular-nums; }
.tw-lines-item { min-width: 13rem; }
.tw-lines td .form-control { min-width: 5.5rem; }
.tw-lines-qty { min-width: 6rem; }
.tw-lines-amt { min-width: 8.5rem; }
.tw-lines-ref { min-width: 7rem; white-space: nowrap; }
.tw-lines-petty td { border-top: 1px dashed var(--tw-border, #dce1e7); background: var(--tw-surface-2, transparent); }
.tw-req-panel { border: 1px solid var(--tw-border, #dce1e7); border-radius: .5rem; padding: .5rem .75rem; height: 100%; }
.tw-req-panel.is-over { border-color: var(--tblr-danger, #d63939); }
.tw-budget-summary td, .tw-budget-summary th { white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 767.98px) {
    .tw-txn-head { flex-direction: column-reverse; gap: .5rem; }
    .tw-txn-amount { text-align: left; }
    .tw-txn-foot { flex-wrap: wrap; }
}

/* An open menu in a table is never cut off by the table's scroll box or its card (e.g. a budget's
   Actions menu on a short list, inside the pop-up; 2026-10-29). */
.table-responsive:has(.dropdown-menu.show),
.card:has(> .table-responsive .dropdown-menu.show),
.card:has(> .table-responsive .dropdown-menu.show) .table-responsive { overflow: visible !important; }
.card:has(.table-responsive .dropdown-menu.show) { z-index: 5; }

/* Boxes Scuola filled in (from the budget, past prices, earlier requisitions): marked until the user
   types in them; the note under the grid counts them (2026-10-29). */
.tw-autofilled { background-color: color-mix(in srgb, var(--tw-primary) 7%, var(--tw-surface-raised, #fff)) !important;
    border-color: color-mix(in srgb, var(--tw-primary) 35%, var(--tw-border, #dce1e7)) !important; }
.tw-autofill-note { font-size: .8125rem; color: var(--tw-primary); background: color-mix(in srgb, var(--tw-primary) 6%, transparent);
    border-radius: .5rem; padding: .4rem .65rem; margin-top: .6rem; }
.tw-autofill-tip { display: flex; gap: .6rem; align-items: flex-start; font-size: .875rem; border: 1px dashed
    color-mix(in srgb, var(--tw-primary) 40%, transparent); border-radius: .6rem; padding: .55rem .75rem; margin: 0 0 1rem;
    background: color-mix(in srgb, var(--tw-primary) 4%, var(--tw-surface-raised, #fff)); }
.tw-autofill-tip .bi-stars { color: var(--tw-primary); font-size: 1.1rem; }

/* Text fits its button or badge (review 2026-10-29): in a flex row they were squeezed below their
   label's width, so "Show who will be charged" or "Never reconciled" spilled out or was cut off on
   phones. They keep their width; on phones a row of buttons wraps onto a second line instead. */
.d-flex > .btn, .d-flex > .badge, .card-footer > .btn, .card-actions > .btn, .tw-step-nav > .btn { flex-shrink: 0; }
@media (max-width: 575.98px) {
    .d-flex:has(> .btn), .card-footer:has(> .btn), .tw-step-nav { flex-wrap: wrap; }
}
/* Equal-width choices in a full-width group: a long label wraps inside its segment. */
.btn-group.w-100 > .btn { white-space: normal; min-width: 0; }

/* The pop-ups' Back button turns red on hover (product owner, 2026-10-29). */
.tw-modal-back { transition: color .15s, background-color .15s, border-color .15s; }
.tw-modal-back:hover, .tw-modal-back:focus-visible { color: #fff !important; background-color: var(--tblr-danger, #d63939) !important;
    border-color: var(--tblr-danger, #d63939) !important; }

/* A pop-up keeps the page where it was (2026-10-29, static/js/app.js): pinned at its scroll position while open.
   Bootstrap's overflow:hidden would cut the shifted page off at one window's height. */
body.tw-scroll-pinned { position: fixed; left: 0; right: 0; height: auto !important; overflow: visible !important; }

/* Staff sign-up (2026-10-29): the robot trap field stays out of sight and out of reach. */
.tw-join-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.tw-signup-code { font: 600 2rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .12em; }
.tw-join-link { font-size: .75rem; color: var(--tw-muted); text-decoration: none; opacity: .85; }
.tw-join-link:hover { color: var(--tw-primary); text-decoration: underline; opacity: 1; }

/* The updater's log (Developer > System updates > a version), 2026-10-29: a fixed dark panel so it reads the same in
   every theme; each step's state in colour. */
.tw-update-log {
    max-height: 28rem; overflow: auto; padding: 1rem 1.1rem; margin: 0;
    font: .78rem/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    background: #0f172a; color: #cbd5e1; border-radius: 0 0 var(--tw-radius-card) var(--tw-radius-card);
    white-space: pre-wrap; word-break: break-word;
}
.tw-update-log > div { min-height: 1.2em; }
.tw-update-log .is-step { color: #93c5fd; font-weight: 600; }
.tw-update-log .is-ok { color: #86efac; font-weight: 700; }
.tw-update-log .is-bad { color: #fca5a5; font-weight: 700; }
.tw-update-log .is-undo { color: #fcd34d; font-weight: 600; }

/* ---- The menu stands out from the page (product owner, 2026-10-29: "make the navigation bar stand out like in
   most systems, to differentiate it from the content, especially on the PC layout") ----
   A solid panel in the school's main colour with white text; the current page on a lighter band with the school's
   accent colour beside it. Fly-out sub-menus stay light: they float over the page. */
.tw-sidebar, :root.glass .tw-sidebar {
    --nav-bg: color-mix(in srgb, var(--brand-primary, #1e2a78) 18%, #1e2533);   /* calm dark slate with a hint of the school colour (2026-10-29: "not shouting") */
    background: var(--nav-bg);
    -webkit-backdrop-filter: none; backdrop-filter: none;
    color: rgba(255, 255, 255, .88);
    border: 0;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .14);
}
.tw-sidebar .tw-brand-name { color: #fff; }
.tw-sidebar .tw-brand-tagline { color: rgba(255, 255, 255, .65); }
.tw-sidebar .tw-brand-logo { background: #fff; padding: 2px; }
.tw-sidebar .tw-brand-underline { background: var(--brand-accent, #f5b400); }
.tw-sidebar .tw-sidebar-toggle { color: rgba(255, 255, 255, .7); }
.tw-sidebar .tw-sidebar-toggle:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.tw-sidebar .tw-nav-link, .tw-sidebar .tw-nav-group-btn { color: rgba(255, 255, 255, .86) !important; }
.tw-sidebar .tw-nav-link i, .tw-sidebar .tw-nav-group-btn > i:first-child { color: rgba(255, 255, 255, .72) !important; }
.tw-sidebar .tw-nav-chevron { color: rgba(255, 255, 255, .5) !important; }
.tw-sidebar .tw-nav-link:hover, .tw-sidebar .tw-nav-group-btn:hover,
.tw-sidebar .tw-nav-group.is-open > .tw-nav-group-btn {
    background: rgba(255, 255, 255, .10) !important; color: #fff !important; box-shadow: none !important;
}
.tw-sidebar .tw-nav-link.active, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn {
    background: rgba(255, 255, 255, .17) !important; color: #fff !important; font-weight: 600;
    box-shadow: inset 3px 0 0 var(--brand-accent, #f5b400) !important;
}
.tw-sidebar .tw-nav-link.active i, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn i { color: #fff !important; }
.tw-sidebar .text-secondary { color: rgba(255, 255, 255, .6) !important; }
.tw-sidebar .border-bottom, .tw-sidebar .tw-sidebar-footer, :root.glass .tw-sidebar-footer { border-color: rgba(255, 255, 255, .14) !important; }
.tw-sidebar a:not(.tw-nav-link):not(.tw-brand) { color: #fff; }
/* The top bar: white and lifted, so it too is set apart from the page. */
.tw-navbar, :root.glass .tw-navbar { box-shadow: 0 2px 14px rgba(15, 23, 42, .08); }
/* The Accounting page's budget card on a phone (2026-10-29): title and dates on their lines, buttons in a full row. */
@media (max-width: 767.98px) {
    .tw-acc-budget-head { flex-wrap: wrap; row-gap: .4rem; }
    .tw-acc-budget-head .card-title { flex: 1 1 auto; white-space: nowrap; }
    .tw-acc-budget-head .card-subtitle { flex: 1 1 100%; margin-left: 0 !important; }
    .tw-acc-budget-head .card-actions { flex: 1 1 100%; margin: 0; }
    .tw-acc-budget-head .btn-group { display: flex; width: 100%; }
    .tw-acc-budget-head .btn-group > .btn { flex: 1 1 0; padding-left: .3rem; padding-right: .3rem; font-size: .75rem; white-space: normal; }
}
/* Phones (review 2026-10-29): a page's pin and help icons stay small at the end of its buttons, not stretched. */
@media (max-width: 767.98px) {
    .tw-page-actions > .btn-icon, .tw-page-actions > form, .tw-page-actions > a.btn-icon { flex: 0 0 auto !important; }
    .tw-page-actions > form.d-inline { margin-left: auto; }
}
/* On phones a group's pages open inside the dark menu, not as a light fly-out (review 2026-10-29). */
@media (max-width: 991.98px) {
    .tw-sidebar .tw-nav-flyout { background: transparent !important; border: 0 !important; box-shadow: none !important;
        -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
    .tw-sidebar .tw-nav-flyout-title { color: rgba(255, 255, 255, .55) !important; }
    .tw-sidebar .tw-nav-flyout-link { color: rgba(255, 255, 255, .86) !important; background: transparent !important; box-shadow: none !important; }
    .tw-sidebar .tw-nav-flyout-link i { color: rgba(255, 255, 255, .6) !important; }
    .tw-sidebar .tw-nav-flyout-link:hover { background: rgba(255, 255, 255, .10) !important; color: #fff !important; }
    .tw-sidebar .tw-nav-flyout-link.active { background: rgba(255, 255, 255, .17) !important; color: #fff !important;
        box-shadow: inset 3px 0 0 var(--brand-accent, #f5b400) !important; }
}

/* Phones (2026-10-30: "the menu should match the colour of the app, maybe a faint grey"): the menu that grows out of
   the Menu tab is a white panel like the Profile panel, its pages in dark text, the current one on faint grey with
   the school colour; computers keep the dark sidebar. */
@media (max-width: 575.98px) {
    .tw-sidebar, :root.glass .tw-sidebar { --nav-bg: var(--tw-surface-raised); background: var(--tw-surface-raised); color: var(--tw-text); }
    .tw-sidebar .tw-brand-name { color: var(--tw-text); }
    .tw-sidebar .tw-brand-tagline { color: var(--tw-muted); }
    .tw-sidebar .tw-brand-logo { box-shadow: 0 0 0 1px var(--tw-border); }
    .tw-sidebar .tw-nav-link, .tw-sidebar .tw-nav-group-btn { color: var(--tw-text) !important; }
    .tw-sidebar .tw-nav-link i, .tw-sidebar .tw-nav-group-btn > i:first-child { color: var(--brand-primary, #1e2a78) !important; }
    .tw-sidebar .tw-nav-chevron { color: var(--tw-muted) !important; }
    .tw-sidebar .tw-nav-link:hover, .tw-sidebar .tw-nav-group-btn:hover,
    .tw-sidebar .tw-nav-group.is-open > .tw-nav-group-btn { background: var(--tw-surface) !important; color: var(--tw-text) !important; }
    .tw-sidebar .tw-nav-link.active, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn {
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 9%, var(--tw-surface)) !important;
        color: var(--brand-primary, #1e2a78) !important; box-shadow: none !important;
    }
    [data-bs-theme="dark"] .tw-sidebar .tw-nav-link.active,
    [data-bs-theme="dark"] .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn { color: var(--tw-text) !important; }
    .tw-sidebar .tw-nav-link.active i, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn i { color: var(--brand-primary, #1e2a78) !important; }
    .tw-sidebar .text-secondary { color: var(--tw-muted) !important; }
    .tw-sidebar .border-bottom, .tw-sidebar .tw-sidebar-footer { border-color: var(--tw-border) !important; }
    .tw-sidebar a:not(.tw-nav-link):not(.tw-brand) { color: var(--tw-text); }
    .tw-sidebar .tw-nav-flyout-title { color: var(--tw-muted) !important; }
    .tw-sidebar .tw-nav-flyout-link { color: var(--tw-text) !important; }
    .tw-sidebar .tw-nav-flyout-link i { color: var(--tw-muted) !important; }
    .tw-sidebar .tw-nav-flyout-link:hover { background: var(--tw-surface) !important; color: var(--tw-text) !important; }
    .tw-sidebar .tw-nav-flyout-link.active { background: color-mix(in srgb, var(--brand-primary, #1e2a78) 9%, var(--tw-surface)) !important;
        color: var(--brand-primary, #1e2a78) !important; box-shadow: none !important; }
    /* The pages in a group sit on a faint grey card, as grouped lists do on phones. */
    .tw-sidebar .tw-nav-group.is-open > .tw-nav-flyout { background: var(--tw-surface) !important; border-radius: 12px; margin: 2px 4px 6px; padding: 4px 0 4px 10px; }
}

/* Phones (2026-10-30: "menu items in a grid view, the best phone app experience"): the menu is a grid of app tiles,
   three to a row, each a coloured rounded icon with its name under it, as on a phone's home screen. A group's tile
   opens its pages on a grey card across the row below it (the group itself steps aside: display: contents). */
@media (max-width: 575.98px) {
    .tw-sidebar .tw-sidebar-nav {
        display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: row dense;
        gap: 6px; padding: 8px 10px 14px;
    }
    .tw-sidebar .tw-nav-group { display: contents; }
    .tw-sidebar .tw-nav-pinned { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px;
        margin: 0 0 4px !important; padding: 0 0 10px !important; }
    .tw-sidebar .tw-nav-pinned > .tw-nav-label { grid-column: 1 / -1; padding: 0 4px !important; margin-bottom: 2px !important; }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link, .tw-sidebar .tw-nav-group-btn {
        flex-direction: column; align-items: center; justify-content: flex-start; gap: 7px; min-height: 92px; padding: 10px 4px 8px;
        border-radius: 16px; text-align: center; font-size: 12px; font-weight: 500; line-height: 1.2; box-shadow: none !important;
    }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link > i:first-child, .tw-sidebar .tw-nav-group-btn > i:first-child {
        width: 46px; height: 46px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; margin: 0;
        border-radius: 15px; font-size: 21px; color: var(--tile) !important; background: color-mix(in srgb, var(--tile) 13%, transparent);
    }
    .tw-sidebar .tw-sidebar-nav .tw-nav-label {
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; max-width: 100%;
    }
    .tw-sidebar .tw-nav-chevron { display: none !important; }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link, .tw-sidebar .tw-nav-group-btn { border: 0 !important; }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link::before, .tw-sidebar .tw-nav-group-btn::before { display: none !important; }
    /* The page you are on, and the open group: the icon filled with its colour. */
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn,
    .tw-sidebar .tw-nav-group.is-open > .tw-nav-group-btn { background: var(--tw-surface) !important; color: var(--tw-text) !important; }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active > i:first-child, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn > i:first-child,
    .tw-sidebar .tw-nav-group.is-open > .tw-nav-group-btn > i:first-child { background: var(--tile); color: #fff !important; }
    .tw-sidebar .tw-nav-link:active, .tw-sidebar .tw-nav-group-btn:active { transform: scale(.95); }
    .tw-sidebar .tw-nav-flyout { grid-column: 1 / -1; }
    /* The current page's tile (2026-10-30): plain like the rest, with a small mark under its name; only the tile whose
       pop-up is open is filled. */
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active:not(:hover), .tw-sidebar .tw-nav-group.is-current:not(.is-open) > .tw-nav-group-btn {
        background: transparent !important; color: var(--tw-text) !important;
    }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active > i:first-child,
    .tw-sidebar .tw-nav-group.is-current:not(.is-open) > .tw-nav-group-btn > i:first-child {
        background: color-mix(in srgb, var(--tile) 13%, transparent); color: var(--tile) !important;
    }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn { position: relative; }
    .tw-sidebar .tw-sidebar-nav .tw-nav-link.active::after, .tw-sidebar .tw-nav-group.is-current > .tw-nav-group-btn::after {
        content: ""; position: absolute; left: 50%; bottom: 3px; width: 16px; height: 4px; margin-left: -8px;
        border-radius: 2px; background: var(--tile);
    }
    .tw-sidebar .tw-nav-group.is-open > .tw-nav-flyout { margin: 0 0 6px !important; padding: 6px 4px !important; }
    .tw-sidebar .tw-nav-flyout-title { padding: 2px 10px 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
    .tw-sidebar .tw-nav-flyout-link { min-height: 42px; padding: 8px 10px; border-radius: 10px; font-size: 14px; }
    /* Each tile its own colour, as app icons are. */
    .tw-sidebar-nav > :nth-child(8n+1) { --tile: #2563eb; }
    .tw-sidebar-nav > :nth-child(8n+2) { --tile: #16a34a; }
    .tw-sidebar-nav > :nth-child(8n+3) { --tile: #ea580c; }
    .tw-sidebar-nav > :nth-child(8n+4) { --tile: #9333ea; }
    .tw-sidebar-nav > :nth-child(8n+5) { --tile: #0891b2; }
    .tw-sidebar-nav > :nth-child(8n+6) { --tile: #db2777; }
    .tw-sidebar-nav > :nth-child(8n+7) { --tile: #ca8a04; }
    .tw-sidebar-nav > :nth-child(8n+8) { --tile: #4f46e5; }
    .tw-nav-pinned > .tw-nav-link { --tile: #d97706; }
    .tw-nav-pinned > .tw-nav-link > i.text-warning { color: var(--tile) !important; }
}

/* Phones: a group's pages pop up in a small card from its tile (2026-10-30), springing out from the tile, with an
   arrow pointing at it; above the tile when there is no room below (static/js/app.js places it). */
@media (max-width: 575.98px) {
    .tw-sidebar .tw-sidebar-nav { position: relative; }
    .tw-sidebar .tw-nav-flyout, .tw-sidebar .tw-nav-group.is-open > .tw-nav-flyout {
        position: absolute; z-index: 6; grid-column: auto; margin: 0 !important; padding: 6px !important;
        background: var(--tw-surface-raised) !important; border: 1px solid var(--tw-border) !important; border-radius: 16px;
        box-shadow: 0 14px 34px rgba(15, 23, 42, .22) !important;
        transform-origin: var(--tw-pop-x, 50%) 0; animation: tw-pop-in .24s cubic-bezier(.2, .9, .3, 1.25) both;
    }
    .tw-sidebar .tw-nav-flyout.is-up { transform-origin: var(--tw-pop-x, 50%) 100%; }
    .tw-sidebar .tw-nav-flyout::before {
        content: ""; position: absolute; top: -7px; left: calc(var(--tw-pop-x, 50%) - 7px); width: 14px; height: 14px;
        background: inherit; border-left: 1px solid var(--tw-border); border-top: 1px solid var(--tw-border); transform: rotate(45deg);
    }
    .tw-sidebar .tw-nav-flyout.is-up::before { top: auto; bottom: -7px; transform: rotate(225deg); }
    .tw-sidebar .tw-nav-flyout-title { position: relative; }
    .tw-sidebar .tw-nav-flyout-link { position: relative; }
}
@keyframes tw-pop-in { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .tw-sidebar .tw-nav-flyout { animation: none !important; } }

/* Phones (2026-10-30: "money in a grid to save space and avoid over-scrolling"): money tiles two to a row,
   the icon above the label and figure; the figure still shrinks to fit its tile (container query above). */
@media (max-width: 575.98px) {
    .tw-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .tw-kpi-card { flex-direction: column; gap: 8px; padding: 12px; }
    .tw-kpi-card > div:last-child { min-width: 0; width: 100%; }
    .tw-kpi-icon { width: 32px; height: 32px; font-size: 15px; }
    .tw-kpi-label { font-size: 11.5px; line-height: 1.25; margin-bottom: 2px; }
    .stat-card .tw-fit-value, .tw-kpi-value { font-size: clamp(12px, calc(11cqi - 2px), 20px); }
}

/* Phones (2026-10-30: "the money cycle should also display in an app form"): each cycle is a card of app tiles,
   four to a row, numbered in their order; what waits at a step shows as a coloured dot on its icon and one short
   line under its name; the cycle's other pages are chips that scroll sideways. */
@media (max-width: 575.98px) {
    .tw-acc-flow > .card-body { padding: 0 !important; background: transparent; gap: 12px; }
    .tw-acc-lane, .tw-acc-lane:first-child { border: 0; border-radius: 18px; box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 2px 10px rgba(15, 23, 42, .04); }
    .tw-acc-lane-title { padding: 12px 14px 4px; background: transparent !important; border-bottom: 0; font-size: 16px; }
    .tw-acc-lane-body { padding: 6px 8px 12px; }
    .tw-acc-steps { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; gap: 6px 2px; counter-reset: tw-step; }
    .tw-acc-steps li + li::before { display: none; }
    .tw-acc-step, [data-bs-theme="dark"] .tw-acc-step {
        flex-direction: column; align-items: center; gap: 6px; padding: 6px 2px; border: 0; background: transparent;
        text-align: center; border-radius: 14px; counter-increment: tw-step;
    }
    .tw-acc-step:hover { box-shadow: none; transform: none; background: transparent; }
    .tw-acc-step:active { transform: scale(.94); background: var(--tw-surface); }
    .tw-acc-step-icon {
        position: relative; width: 50px; height: 50px; border-radius: 16px; font-size: 22px;
        background: color-mix(in srgb, var(--lane) 12%, transparent);
    }
    /* The step's number, as a small badge on its icon. */
    .tw-acc-step-icon::before {
        content: counter(tw-step); position: absolute; left: -4px; top: -4px; min-width: 18px; height: 18px; padding: 0 4px;
        border-radius: 9px; background: var(--tw-surface-raised); color: var(--tw-muted); box-shadow: 0 0 0 1px var(--tw-border);
        font-size: 10.5px; font-weight: 700; line-height: 18px; font-style: normal;
    }
    /* What waits: a dot on the icon in the step's colour. */
    .tw-acc-step[class*=" is-"] .tw-acc-step-icon::after {
        content: ""; position: absolute; right: -2px; top: -2px; width: 12px; height: 12px; border-radius: 50%;
        border: 2px solid var(--tw-surface-raised); background: #868e96;
    }
    .tw-acc-step.is-ok .tw-acc-step-icon::after { background: #2f9e44; }
    .tw-acc-step.is-info .tw-acc-step-icon::after { background: #1c7ed6; }
    .tw-acc-step.is-warn .tw-acc-step-icon::after { background: #f59f00; }
    .tw-acc-step.is-danger .tw-acc-step-icon::after { background: #e03131; }
    .tw-acc-step-text { align-items: center; width: 100%; }
    .tw-acc-step-label { font-size: 11.5px; font-weight: 600; line-height: 1.2;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
    .tw-acc-step-hint { display: none; }
    .tw-acc-queue { align-self: center; margin-top: 3px; padding: 0; background: none !important; font-size: 10px; line-height: 1.2;
        max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .tw-acc-queue::before { display: none; }
    .tw-acc-more { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 6px; margin: 8px -8px 0; padding: 8px 8px 0; }
    .tw-acc-more::-webkit-scrollbar { display: none; }
    .tw-acc-more::before { display: none; }
    .tw-acc-more a { flex: 0 0 auto; padding: 6px 12px; border-radius: 999px; background: var(--tw-surface);
        border: 1px solid var(--tw-border); color: var(--tw-text); font-size: 12.5px; text-decoration: none; }
}

/* Phones: the More tile's pop-up, as the menu's (2026-10-30); the row of More links is for computers. */
.tw-acc-more-pop { display: none; }
@media (max-width: 575.98px) {
    .tw-acc-more { display: none; }
    .tw-acc-lane-body { position: relative; }
    .tw-acc-lane { overflow: visible !important; }
    /* The pop-up is placed against the cycle's card (static/js/app.js measures from it), not against the tile. */
    .tw-acc-steps li.tw-acc-more-tile { position: static; }
    .tw-acc-more-tile .tw-acc-step { width: 100%; cursor: pointer; }
    .tw-acc-more-tile .tw-acc-step-icon { background: var(--tw-surface); color: var(--tw-muted); }
    .tw-acc-more-tile .tw-acc-step-icon::before { display: none; }
    .tw-acc-more-tile [aria-expanded="true"] .tw-acc-step-icon { background: var(--lane); color: #fff; }
    .tw-acc-more-pop:not([hidden]) {
        display: flex; flex-direction: column; position: absolute; z-index: 20; padding: 6px;
        background: var(--tw-surface-raised); border: 1px solid var(--tw-border); border-radius: 16px;
        box-shadow: 0 14px 34px rgba(15, 23, 42, .22); transform-origin: var(--tw-pop-x, 50%) 0;
        animation: tw-pop-in .24s cubic-bezier(.2, .9, .3, 1.25) both;
    }
    .tw-acc-more-pop::before {
        content: ""; position: absolute; top: -7px; left: calc(var(--tw-pop-x, 50%) - 7px); width: 14px; height: 14px;
        background: inherit; border-left: 1px solid var(--tw-border); border-top: 1px solid var(--tw-border); transform: rotate(45deg);
    }
    .tw-acc-more-pop a { position: relative; padding: 10px 12px; border-radius: 10px; color: var(--tw-text); font-size: 14px; text-decoration: none; }
    .tw-acc-more-pop a:active { background: var(--tw-surface); }
    .tw-acc-more-pop a + a { border-top: 1px solid var(--tw-border); }
}

/* Phones (2026-10-30: "every search field should be a phone app search field"): a rounded pill on soft grey with
   a magnifier inside, a thumb's height; white with the school colour when typing. A search box with its own icon
   and Search button becomes one pill. The top bar's search has its own (design.css). */
@media (max-width: 575.98px) {
    input[type="search"].form-control:not(.tw-search-input), input[name="q"].form-control:not(.tw-search-input), .input-icon > input.form-control {
        height: 44px; min-height: 44px; border-radius: 999px !important; border: 1px solid transparent !important; font-size: 16px;
        padding-left: 42px !important; background-color: var(--tw-surface) !important;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23868e96'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0'/%3E%3C/svg%3E");
        background-repeat: no-repeat; background-position: 15px center; background-size: 16px 16px;
    }
    input[type="search"].form-control:not(.tw-search-input):focus, input[name="q"].form-control:not(.tw-search-input):focus, .input-icon > input.form-control:focus {
        background-color: var(--tw-surface-raised) !important; border-color: var(--brand-primary, #1e2a78) !important;
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #1e2a78) 16%, transparent) !important;
    }
    .input-icon > .input-icon-addon { z-index: 5; padding-left: 15px; color: #868e96; }
    /* An icon, a field and a Search button: one pill. */
    .input-group:has(> .input-group-text > .bi-search) {
        flex-wrap: nowrap; border-radius: 999px; background: var(--tw-surface); border: 1px solid transparent; overflow: hidden;
    }
    .input-group:has(> .input-group-text > .bi-search):focus-within {
        background: var(--tw-surface-raised); border-color: var(--brand-primary, #1e2a78);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #1e2a78) 16%, transparent);
    }
    .input-group:has(> .input-group-text > .bi-search) > .input-group-text { border: 0; background: transparent; padding-left: 15px; padding-right: 4px; }
    .input-group:has(> .input-group-text > .bi-search) > .form-control {
        border: 0 !important; background: transparent !important; box-shadow: none !important; padding-left: 6px !important; background-image: none !important;
        height: 44px; font-size: 16px; border-radius: 0 !important;
    }
    .input-group:has(> .input-group-text > .bi-search) > .btn { border-radius: 999px !important; margin: 3px; min-height: 38px; padding: 0 16px; }
    /* The pill shows the focus ring; the field inside it draws none (the search-field ring above won over the
       rule before and drew a rectangle inside the pill, product owner 2026-10-30). */
    .input-group:has(> .input-group-text > .bi-search) > .form-control:focus,
    .tw-content .input-group.input-group-flat > .form-control:focus {
        border-color: transparent !important; box-shadow: none !important; outline: none !important;
    }
}

/* Phones (2026-10-30: "requisitions, budgets and all grids should have a phone app view"): a table's rows are app
   cards (static/js/app.js cardTables), each on its own with round corners and space between; the box around the
   table steps aside; nothing runs off the card. */
@media (max-width: 575.98px) {
    .card:has(> .table-responsive > table.tw-cards), .card:has(> table.tw-cards),
    :root.glass .card:has(> .table-responsive > table.tw-cards), :root.glass .card:has(> table.tw-cards) {
        background: transparent !important; border: 0 !important; box-shadow: none !important;
        -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
    }
    .card:has(> .table-responsive > table.tw-cards) > .card-header, .card:has(> table.tw-cards) > .card-header,
    .card:has(> .table-responsive > table.tw-cards) > .card-footer, .card:has(> table.tw-cards) > .card-footer {
        background: transparent; border: 0; padding-left: 2px; padding-right: 2px;
    }
    .card:has(> .table-responsive > table.tw-cards) > .card-body, .card:has(> table.tw-cards) > .card-body { padding-left: 0; padding-right: 0; }
    table.tw-cards { background: transparent; margin: 0; }
    table.tw-cards tr {
        margin: 0 0 10px; padding: 14px 16px; border: 0 !important; border-radius: 16px; background: var(--tw-surface-raised);
        box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 2px 10px rgba(15, 23, 42, .05);
    }
    table.tw-cards tfoot tr { background: color-mix(in srgb, var(--brand-primary, #1e2a78) 6%, var(--tw-surface-raised)); }
    table.tw-cards tr:has(a.stretched-link, td a[href]):active { background: var(--tw-surface); }
    table.tw-cards td, table.tw-cards th, table.tw-cards .text-nowrap { white-space: normal !important; }
    table.tw-cards > :not(caption) > * > * { background: transparent !important; --tblr-table-accent-bg: transparent; box-shadow: none !important; }
    table.tw-cards td > *, table.tw-cards th > * { max-width: 100%; }
    table.tw-cards .tw-card-title { font-size: 16px; }
    table.tw-cards td:has(> .btn-group:only-child), table.tw-cards td:has(> .btn:only-child), table.tw-cards td:has(> form:only-child) {
        grid-column: 1 / -1; display: flex; justify-content: flex-end;
    }
    table.tw-cards td:has(> .btn-group:only-child)::before, table.tw-cards td:has(> .btn:only-child)::before,
    table.tw-cards td:has(> form:only-child)::before { content: none; }
}

/* Phones: a budget's grid, one card per account (cardTables): the account name, then each period's figure with its
   label, still editable; section rows (Income, Spending) are headings between the cards; the tick boxes stay on
   computers. And a search box that draws its own magnifier keeps only that one. */
@media (max-width: 575.98px) {
    .tw-bud-scroll:has(> table.tw-cards) { overflow: visible !important; max-height: none !important; }
    table.tw-bud-grid.tw-cards .tw-bud-check { display: none !important; }
    table.tw-bud-grid.tw-cards tr.tw-bud-group { background: transparent; box-shadow: none; padding: 14px 4px 2px; margin: 0; }
    table.tw-bud-grid.tw-cards tr.tw-bud-group td:empty, table.tw-bud-grid.tw-cards tr.tw-bud-group td:not(.tw-card-title) { display: none; }
    table.tw-bud-grid.tw-cards tr.tw-bud-group .tw-card-title { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--tw-muted); }
    table.tw-bud-grid.tw-cards td, table.tw-bud-grid.tw-cards th {
        position: static !important; left: auto !important; width: auto !important; max-width: none !important; height: auto !important;
        overflow: visible !important; border: 0 !important; background: transparent !important;
    }
    table.tw-bud-grid.tw-cards .tw-bud-acc-name { white-space: normal; overflow: visible; text-overflow: clip; max-width: none; }
    table.tw-bud-grid.tw-cards tr { row-gap: 10px; }
    table.tw-bud-grid.tw-cards td::before { margin-bottom: 3px; }
    table.tw-bud-grid.tw-cards .tw-bud-ref { align-self: start; font-weight: 600; }
    table.tw-bud-grid.tw-cards input.tw-bud-input { border: 1px solid var(--tw-border) !important; border-radius: 10px !important; padding: 8px 10px; background: var(--tw-surface-raised); }
    table.tw-bud-grid.tw-cards input.form-control, table.tw-bud-grid.tw-cards input { width: 100%; min-height: 40px; text-align: right; }
    *:has(> i.bi-search) > input[type="search"].form-control, *:has(> .input-icon-addon) > input.form-control,
    *:has(> i.bi-search) > input[name="q"].form-control { background-image: none !important; }
}

/* Phones: a budget account's card reads like a settings list (2026-10-30, "revise the budget grid"): the account
   and its total on the top line, last year's figure in one small line, then one row per period with its figure. */
@media (max-width: 575.98px) {
    table.tw-bud-grid.tw-cards tr.tw-bud-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 8px; padding: 14px 16px 10px; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-acc { grid-column: 1; grid-row: 1; align-self: center; font-size: 16px; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-total { grid-column: 2; grid-row: 1; align-self: center; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-total::before { content: none; }
    table.tw-bud-grid.tw-cards .tw-bud-total input, table.tw-bud-grid.tw-cards .tw-bud-total .tw-bud-total-cell {
        width: 132px; min-height: 36px; border: 0 !important; background: transparent !important; padding: 0;
        font-size: 16px; font-weight: 700; text-align: right; box-shadow: none !important;
    }
    table.tw-bud-grid.tw-cards .tw-bud-total input:focus { background: var(--tw-surface) !important; border-radius: 8px !important; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-ref {
        grid-column: 1 / -1; display: flex; gap: 6px; margin-top: -4px; font-size: 12.5px; font-weight: 400; color: var(--tw-muted);
    }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-ref::before { content: "Last year:"; display: inline; font-size: 12.5px; margin: 0; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-num {
        grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 12px;
        padding-top: 8px !important; border-top: 1px solid var(--tw-border) !important;
    }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-num::before { display: inline; margin: 0; font-size: 14px; color: var(--tw-text); font-weight: 500; }
    table.tw-bud-grid.tw-cards tr.tw-bud-row > .tw-bud-num input { width: 55%; flex: 0 0 55%; font-size: 16px; }   /* 16px: iPhones zoom in on smaller fields */
}

/* Phones, from the page-by-page review (2026-10-30, 85 pages):
   - filter bars (dates, search, Show) wrap two to a row with full-height fields, none past the edge;
   - a card header's buttons go onto their own row instead of running off the side;
   - small buttons are still a thumb's size (36px);
   - a card inside a card loses its own frame. */
@media (max-width: 575.98px) {
    .tw-content form.d-flex { flex-wrap: wrap; }
    .tw-content form.d-flex > * { flex: 1 1 140px; min-width: 0; }
    .tw-content form.d-flex > .btn, .tw-content form.d-flex > button { flex: 1 1 100%; }
    .tw-content form.d-flex .form-control, .tw-content form.d-flex .form-select { width: 100%; min-width: 0; }
    .tw-content .form-control-sm, .tw-content .form-select-sm { min-height: 44px; font-size: 16px; border-radius: 12px; }
    .tw-content .card-header { flex-wrap: wrap; row-gap: 8px; }
    .tw-content .card-header > .card-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }
    .tw-content .card-header > .card-actions.btn-group, .tw-content .card-header > .card-actions .btn-group { display: flex; width: 100%; }
    .tw-content .card-header > .card-actions .btn-group > .btn, .tw-content .card-header > .card-actions.btn-group > .btn { flex: 1 1 0; }
    .tw-content .btn-sm { min-height: 36px; padding-top: 6px; padding-bottom: 6px; }
    .tw-content .btn-icon.btn-sm, .tw-content .btn-sm.btn-icon { min-width: 36px; }
    .tw-content .card .card { border: 0; box-shadow: none; background: var(--tw-surface); }
}

/* Phones (2026-10-30: "the calendar on a student's profile should match a modern phone calendar"): a white card,
   the month as its title, weekday letters, days in circles: present a soft green circle with a dot, absent soft
   red, today filled with the school colour; the totals as two small pills. */
@media (max-width: 575.98px) {
    .pd-calendar, :root.glass .card.pd-calendar { background: var(--tw-surface-raised) !important; color: var(--tw-text); }
    .pd-calendar .card-title { font-size: 17px; font-weight: 700; }
    .pd-calendar .card-body > .d-flex:first-child { flex-direction: column; align-items: flex-start !important; gap: 0; }
    .pd-calendar .card-body > .d-flex:first-child > .small { order: -1; opacity: 1 !important; font-size: 12px; font-weight: 600;
        text-transform: uppercase; letter-spacing: .05em; color: var(--brand-primary, #1e2a78); }
    .pd-cal-grid { gap: 2px 0; margin-top: 6px; }
    .pd-cal-head { font-size: 11px; color: var(--tw-muted); opacity: 1; text-transform: uppercase; }
    .pd-cal-day, .pd-cal-day.is-none, .pd-cal-day.is-present, .pd-cal-day.is-absent {
        position: relative; justify-self: center; width: 38px; height: 38px; line-height: 38px; padding: 0; border-radius: 50%;
        font-size: 15px; font-weight: 500; opacity: 1; background: transparent; color: var(--tw-text); box-shadow: none;
    }
    .pd-cal-day.is-none { color: var(--tw-muted); }
    .pd-cal-day.is-present { background: rgba(47, 158, 68, .12); color: #2b8a3e; font-weight: 600; }
    .pd-cal-day.is-absent { background: rgba(224, 49, 49, .12); color: #c92a2a; font-weight: 600; }
    .pd-cal-day.is-present::after, .pd-cal-day.is-absent::after {
        content: ""; position: absolute; left: 50%; bottom: 4px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: currentColor;
    }
    .pd-cal-day.is-today { background: var(--brand-primary, #1e2a78) !important; color: #fff !important; box-shadow: none !important; }
    .pd-cal-day.is-today::after { background: #fff; }
    .pd-calendar .d-flex.gap-3.small { opacity: 1 !important; gap: 8px !important; margin-top: 12px !important; }
    .pd-calendar .d-flex.gap-3.small > span { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px;
        background: var(--tw-surface); font-size: 13px; font-weight: 500; }
}

/* Phones (2026-10-30: "match buttons as well, some look like website buttons"): buttons as in phone apps.
   The main action solid in the school colour; outlined and plain buttons become soft tinted ones without a
   border (the school colour, grey, or red for removing); round corners and a thumb's height; icon-only buttons
   round. Tabs inside a card are a row of pills that scrolls sideways. */
@media (max-width: 575.98px) {
    .tw-content .btn:not(.btn-link):not(.btn-close):not([class*="btn-ghost"]) { border-radius: 14px; min-height: 46px; font-weight: 600; box-shadow: none; }
    .tw-content .btn-sm:not(.btn-link):not([class*="btn-ghost"]) { border-radius: 11px; min-height: 38px; }
    .tw-content .btn-primary { box-shadow: 0 6px 16px color-mix(in srgb, var(--brand-primary, #1e2a78) 25%, transparent); }
    .tw-content .btn-outline-primary, .tw-content .btn-outline-info, .tw-content .btn-outline-azure, .tw-content .btn-outline-blue {
        border-color: transparent !important; color: var(--brand-primary, #1e2a78);
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 9%, transparent);
    }
    .tw-content .btn-outline-secondary, .tw-content .btn-white, .tw-content .btn-light, .tw-content .tw-btn-secondary, .tw-content .btn-outline-dark,
    .tw-content .btn-default, .tw-content .btn-secondary:not(.active) {
        border-color: transparent !important; color: var(--tw-text); background: color-mix(in srgb, var(--tw-text) 7%, transparent);
    }
    [data-bs-theme="dark"] .tw-content .btn-outline-secondary, [data-bs-theme="dark"] .tw-content .btn-white { background: rgba(255, 255, 255, .08); }
    .tw-content .btn-outline-danger, .tw-content .btn-outline-red { border-color: transparent !important; color: #c92a2a; background: rgba(224, 49, 49, .09); }
    .tw-content .btn-outline-success, .tw-content .btn-outline-green { border-color: transparent !important; color: #2b8a3e; background: rgba(47, 158, 68, .1); }
    .tw-content .btn-outline-warning, .tw-content .btn-outline-orange { border-color: transparent !important; color: #b35c00; background: rgba(245, 159, 0, .13); }
    .tw-content .btn:not(.btn-link):active { transform: scale(.96); }
    .tw-content .btn-icon:not(.btn-link):not([class*="btn-ghost"]) { border-radius: 50%; min-width: 44px; padding: 0; }
    /* A segmented choice (Month/List, Total/Termly): one grey track, the chosen one lifted. */
    .tw-content .btn-group:is(:has(> .btn-check), :has(> .btn.active), [role=group]:has(> .btn-primary + .btn-outline-primary), [role=group]:has(> .btn-outline-primary + .btn-primary)) { background: color-mix(in srgb, var(--tw-text) 7%, transparent); border-radius: 14px; padding: 3px; gap: 2px; }
    .tw-content .btn-group:is(:has(> .btn-check), :has(> .btn.active), [role=group]:has(> .btn-primary + .btn-outline-primary), [role=group]:has(> .btn-outline-primary + .btn-primary)) > .btn { border-radius: 11px !important; min-height: 40px; background: transparent; border: 0 !important; color: var(--tw-text); }
    .tw-content .btn-group:is(:has(> .btn-check), :has(> .btn.active), [role=group]:has(> .btn-primary + .btn-outline-primary), [role=group]:has(> .btn-outline-primary + .btn-primary)) > .btn.active, .tw-content .btn-group:is(:has(> .btn-check), :has(> .btn.active), [role=group]:has(> .btn-primary + .btn-outline-primary), [role=group]:has(> .btn-outline-primary + .btn-primary)) > .btn-primary,
    .tw-content .btn-group:is(:has(> .btn-check), :has(> .btn.active), [role=group]:has(> .btn-primary + .btn-outline-primary), [role=group]:has(> .btn-outline-primary + .btn-primary)) > .btn-check:checked + .btn {
        background: var(--tw-surface-raised); color: var(--brand-primary, #1e2a78); box-shadow: 0 1px 4px rgba(15, 23, 42, .15);
    }
    /* Page buttons share the row. */
    .tw-page-actions { flex-wrap: wrap; }
    /* auto, not 0: with many buttons (Kitchen book has six) a 0 basis squeezed them onto one row over each other. */
    .tw-page-actions > .btn, .tw-page-actions > a.btn, .tw-page-actions > .dropdown { flex: 1 1 auto; }
    .tw-page-actions > .dropdown > .btn { width: 100%; }
    /* Tabs inside a card: a row of pills. */
    .tw-content .card-header .nav-tabs, .tw-content .card-header-tabs {
        flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 6px; margin: 0; border: 0; padding: 2px 0;
    }
    .tw-content .card-header .nav-tabs::-webkit-scrollbar { display: none; }
    .tw-content .card-header .nav-tabs .nav-link, .tw-content .card-header-tabs .nav-link {
        white-space: nowrap; border: 0 !important; border-radius: 999px; padding: 7px 14px; background: var(--tw-surface); color: var(--tw-text); font-size: 13.5px;
    }
    .tw-content .card-header .nav-tabs .nav-link.active, .tw-content .card-header-tabs .nav-link.active {
        background: var(--brand-primary, #1e2a78); color: #fff;
    }
}
/* Phones: a button with no style of its own (the PDF, Email and print buttons) gets the soft grey one too. */
@media (max-width: 575.98px) {
    .tw-content .btn:not([class*=" btn-"]):not([class^="btn-"]), .tw-content .btn.w-100:not([class*=" btn-"]) {
        background: color-mix(in srgb, var(--tw-text) 7%, transparent); color: var(--tw-text); border-color: transparent;
    }
    .tw-content .dropdown-toggle.btn:not([class*=" btn-"]) { background: color-mix(in srgb, var(--tw-text) 7%, transparent); }
}
/* Phones: a choice of buttons sitting among a card's tab pills gets a row of its own under them. */
@media (max-width: 575.98px) {
    .tw-content .card-header-tabs:has(> li > .btn-group), .tw-content .card-header .nav-tabs:has(> li > .btn-group) { flex-wrap: wrap; overflow: visible; }
    .tw-content .card-header-tabs > li:has(> .btn-group), .tw-content .card-header .nav-tabs > li:has(> .btn-group) { flex: 1 1 100%; margin: 4px 0 0 !important; }
    .tw-content .card-header-tabs > li > .btn-group, .tw-content .card-header .nav-tabs > li > .btn-group { display: flex; width: 100%; }
    .tw-content .card-header-tabs > li > .btn-group > .btn { flex: 1 1 0; }
}
@media (max-width: 575.98px) {
    table.tw-cards .badge { white-space: normal; text-align: left; max-width: 100%; }
}
@media (max-width: 575.98px) {
    /* A filter form among the page's buttons (Results analysis, quick reference) takes the row and shares it. */
    .tw-page-actions > form.d-flex, .tw-page-actions > form:not(.d-inline) { flex: 1 1 100% !important; min-width: 0; margin-left: 0 !important; }
    .tw-content form.d-flex .form-select, .tw-content form.d-flex .form-control { min-width: 0 !important; }
    .tw-content form.d-flex .flex-fill { min-width: 0; flex: 1 1 140px; }
}

/* Phones: the New options as a card of app tiles that grows from the New button, the page dimmed behind it
   (2026-10-30); grouped under their headings, three tiles to a row. */
@media (max-width: 575.98px) {
    .tw-acc-new.show {
        position: fixed !important; inset: var(--tw-new-top, 120px) 12px auto 12px !important; transform: none !important; margin: 0 !important;
        display: block; max-height: calc(100dvh - var(--tw-new-top, 120px) - 90px); overflow-y: auto; padding: 8px 10px 12px;
        border: 0; border-radius: 22px; background: var(--tw-surface-raised); z-index: 1050;
        box-shadow: 0 0 0 100vmax rgba(15, 23, 42, .38), 0 20px 50px rgba(15, 23, 42, .3);
        transform-origin: var(--tw-pop-x, 50%) 0; animation: tw-pop-in .28s cubic-bezier(.2, .9, .3, 1.2) both;
    }
    .tw-acc-new-col { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; min-width: 0; }
    .tw-acc-new-col + .tw-acc-new-col { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--tw-border); }
    .tw-acc-new .dropdown-header { grid-column: 1 / -1; padding: 8px 6px 2px; font-size: 11.5px; font-weight: 700; letter-spacing: .05em;
        text-transform: uppercase; color: var(--tw-muted); }
    .tw-acc-new .dropdown-item {
        display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 2px; border-radius: 14px;
        text-align: center; white-space: normal; font-size: 12px; font-weight: 500; line-height: 1.2; color: var(--tw-text);
    }
    .tw-acc-new .dropdown-item > i {
        margin: 0 !important; width: 46px; height: 46px; display: flex; align-items: center; justify-content: center; border-radius: 15px;
        font-size: 21px; color: var(--brand-primary, #1e2a78) !important; background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent);
    }
    .tw-acc-new .dropdown-item:active { background: var(--tw-surface); transform: scale(.95); }
}
@media (max-width: 575.98px) {
    .tw-acc-new.show { overflow-x: hidden; min-width: 0; }
    .tw-acc-new .dropdown-item { width: auto; min-width: 0; overflow-wrap: anywhere; }
    /* A sheet from the bottom over the tab bar, as tall as it needs (product owner, 2026-10-30: the New card showed
       under half its options, the rest hidden below with no sign of them); four to a row, so all fit on most phones. */
    .tw-acc-new.show {
        inset: auto 0 0 0 !important; max-height: 88dvh; border-radius: 24px 24px 0 0; z-index: 1060;
        padding: 6px 10px calc(14px + env(safe-area-inset-bottom, 0px)); transform-origin: 50% 100%;
    }
    .tw-acc-new.show::before { content: ""; display: block; width: 40px; height: 5px; margin: 4px auto 6px; border-radius: 3px;
                               background: color-mix(in srgb, var(--tw-text) 18%, transparent); }
    .tw-acc-new-col { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .tw-acc-new .dropdown-item { padding: 5px 2px; gap: 4px; font-size: 11.5px; }
    .tw-acc-new .dropdown-item > i { width: 38px; height: 38px; font-size: 18px; border-radius: 12px; }
    .tw-acc-new .dropdown-header { padding: 6px 6px 0; }
    .tw-acc-new-col + .tw-acc-new-col { margin-top: 4px; padding-top: 4px; }
}

/* Phones (2026-10-30: "step progress bars, e.g. at the fee concession, have a scroll bar"): steps as an app's
   progress bar: one rounded segment per step, filled up to the current one, the current step's name above its
   segment; it always fits, so no scroll bar. */
@media (max-width: 575.98px) {
    .steps { display: flex !important; flex-wrap: nowrap; gap: 6px; overflow: hidden !important; scrollbar-width: none; margin-left: 0; margin-right: 0; padding: 0; }
    .steps::-webkit-scrollbar { display: none; }
    .steps .step-item {
        flex: 1 1 0 !important; min-width: 0; margin: 0 !important; padding: 0 !important; font-size: 0 !important;
        display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; min-height: 28px; text-align: left; white-space: nowrap;
    }
    .steps .step-item.active { flex: 2.4 1 0 !important; font-size: 12.5px !important; font-weight: 700; color: var(--brand-primary, #1e2a78); overflow: hidden; text-overflow: ellipsis; }
    .steps .step-item::after { display: none !important; }
    .steps .step-item::before {
        content: "" !important; position: static !important; display: block; width: 100% !important; height: 6px !important; margin: 0 !important;
        border: 0 !important; border-radius: 3px; background: var(--tw-border) !important; box-shadow: none !important; transform: none !important;
        order: 2;
    }
    .steps .step-item.active::before, .steps .step-item:has(~ .step-item.active)::before { background: var(--brand-primary, #1e2a78) !important; }
}
/* Phones: the profile's attendance calendar shows only dots for present and absent, no circles (2026-10-30). */
@media (max-width: 575.98px) {
    .pd-cal-day.is-present, .pd-cal-day.is-absent { background: transparent; color: var(--tw-text); font-weight: 500; }
    .pd-cal-day.is-present::after, .pd-cal-day.is-absent::after { width: 6px; height: 6px; margin-left: -3px; bottom: 2px; }
    .pd-cal-day.is-present::after { background: #2f9e44; }
    .pd-cal-day.is-absent::after { background: #e03131; }
}

/* Phones (2026-10-30): a student profile's tabs share the width, icon above a short label, none cut off; "More"
   opens its menu freely. And the attendance calendar marks present and absent days with small faded circles. */
@media (max-width: 575.98px) {
    .tw-content .card-header .nav-tabs.pd-tabs, .tw-content .pd-tabs {
        display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 4px; overflow: visible; flex-wrap: nowrap;
    }
    .tw-content .pd-tabs .nav-item { min-width: 0; }
    .tw-content .pd-tabs .nav-link {
        display: flex; flex-direction: column; align-items: center; gap: 3px; width: 100%; padding: 7px 2px !important;
        border-radius: 12px !important; font-size: 11px !important; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .tw-content .pd-tabs .nav-link > i { margin: 0 !important; font-size: 17px; }
    .tw-content .pd-tabs .dropdown-toggle::after { display: none; }

    .pd-cal-day.is-present, .pd-cal-day.is-absent { width: 32px; height: 32px; line-height: 32px; font-size: 14px; }
    .pd-cal-day.is-present { background: rgba(47, 158, 68, .14); color: #2b8a3e; font-weight: 600; }
    .pd-cal-day.is-absent { background: rgba(224, 49, 49, .13); color: #c92a2a; font-weight: 600; }
    .pd-cal-day.is-present::after, .pd-cal-day.is-absent::after { content: none; }
}

/* Phones: a compact list (the student list, 2026-10-30: "without details so that more students are viewed"):
   one short row per pupil, photo, name and one grey line, in one card with thin dividers. */
@media (max-width: 575.98px) {
    table.tw-cards.tw-compact-list { background: var(--tw-surface-raised); border-radius: 16px; overflow: hidden;
        box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 2px 10px rgba(15, 23, 42, .05); }
    table.tw-cards.tw-compact-list tr { display: flex; align-items: center; gap: 8px; margin: 0; padding: 9px 14px; border-radius: 0;
        box-shadow: none; background: transparent; border-bottom: 1px solid var(--tw-border) !important; }
    table.tw-cards.tw-compact-list tr:last-child { border-bottom: 0 !important; }
    table.tw-cards.tw-compact-list td { display: none; }
    table.tw-cards.tw-compact-list td.tw-card-title { display: block; flex: 1 1 auto; min-width: 0; font-size: 15px; }
    table.tw-cards.tw-compact-list td:last-child { display: block; flex: 0 0 auto; }
    table.tw-cards.tw-compact-list td:last-child::before { content: none; }
}

/* Phones: a student profile's More opens a card of icon tiles under it (as New on the Accounting page), not a list
   hanging off the tab (2026-10-30). */
@media (max-width: 575.98px) {
    .pd-tabs .nav-item.dropdown { position: static; }
    .pd-tabs .dropdown-menu.show {
        position: absolute !important; inset: calc(100% + 8px) 0 auto 0 !important; transform: none !important; margin: 0 !important;
        display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 10px; border: 0; border-radius: 20px;
        background: var(--tw-surface-raised); z-index: 30; box-shadow: 0 0 0 100vmax rgba(15, 23, 42, .3), 0 18px 44px rgba(15, 23, 42, .28);
        transform-origin: 90% 0; animation: tw-pop-in .26s cubic-bezier(.2, .9, .3, 1.2) both;
    }
    .pd-tabs .card-header, .card-header:has(> .pd-tabs) { position: relative; }
    .pd-tabs .dropdown-menu .dropdown-item {
        display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 2px; border-radius: 14px;
        text-align: center; white-space: normal; font-size: 12px; font-weight: 500; line-height: 1.2; position: relative;
    }
    .pd-tabs .dropdown-menu .dropdown-item > i {
        margin: 0 !important; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 14px;
        font-size: 20px; color: var(--brand-primary, #1e2a78); background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent);
    }
    .pd-tabs .dropdown-menu .dropdown-item .badge { position: absolute; top: 4px; right: 10px; margin: 0 !important; }
    .pd-tabs .dropdown-menu .dropdown-item.active { background: var(--tw-surface); color: var(--tw-text); }
}

/* The staff sign-up sheet's QR (accounts/signup/code_created.html). */
.tw-signup-qr { width: 200px; max-width: 70%; }
.tw-signup-qr svg { width: 100%; height: auto; display: block; }
/* Phones: the student profile's active tab is a soft tint, the same size as the others (2026-10-30: it looked big). */
@media (max-width: 575.98px) {
    .tw-content .pd-tabs .nav-link, .tw-content .card-header .pd-tabs .nav-link { background: transparent !important; color: var(--tw-muted) !important; box-shadow: none !important; border: 0 !important; }
    .tw-content .pd-tabs .nav-link.active, .tw-content .card-header .pd-tabs .nav-link.active {
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent) !important; color: var(--brand-primary, #1e2a78) !important; font-weight: 600;
    }
    .tw-content .pd-tabs .nav-link[aria-expanded="true"] { background: var(--tw-surface) !important; color: var(--tw-text) !important; }
}
/* Phones: the profile's tabs get the card's full width and a little more air (2026-10-30: they looked squeezed). */
@media (max-width: 575.98px) {
    .tw-content .card-header:has(> .pd-tabs) { padding: 8px 6px !important; }
    .tw-content .card-header .nav-tabs.pd-tabs, .tw-content .pd-tabs { gap: 2px; margin: 0 !important; width: 100%; }
    .tw-content .pd-tabs .nav-link { padding: 9px 0 8px !important; gap: 5px; font-size: 11.5px !important; letter-spacing: -.01em; }
    .tw-content .pd-tabs .nav-link > i { font-size: 19px; }
    .tw-content .pd-tabs .nav-link .badge { display: none; }
}
@media (max-width: 575.98px) {
    /* Not so tall (2026-10-30): smaller icon, tighter padding; the width stays. */
    .tw-content .card-header:has(> .pd-tabs) { padding: 6px !important; }
    .tw-content .pd-tabs .nav-link { padding: 5px 0 !important; gap: 2px; font-size: 11px !important; border-radius: 10px !important; }
    .tw-content .pd-tabs .nav-link > i { font-size: 15px; line-height: 1; }
}

/* Phones (2026-10-30): the money cycles' tiles show only their name; what waits is the coloured dot on the icon,
   without the amounts and statuses under it, which crowded the tiles. */
@media (max-width: 575.98px) {
    .tw-acc-steps .tw-acc-queue, .tw-acc-steps .tw-acc-step-hint { display: none !important; }
}
/* Phones: Cancel as a soft red button (static/js/app.js marks plain Cancel buttons). */
@media (max-width: 575.98px) {
    .btn.tw-cancel, .tw-content .btn.tw-cancel, .modal .btn.tw-cancel {
        /* A button in a warning colour (2026-10-30): soft red, red text, round corners. */
        background: rgba(224, 49, 49, .1) !important; border-color: transparent !important; box-shadow: none !important;
        color: #c92a2a !important; font-weight: 600; min-height: 46px; border-radius: 14px !important; padding-left: 18px; padding-right: 18px;
    }
    [data-bs-theme="dark"] .btn.tw-cancel { color: #ff8787 !important; background: rgba(255, 107, 107, .14) !important; }
    .btn.tw-cancel:active { background: rgba(224, 49, 49, .18) !important; transform: scale(.96); }
}
/* A stepped form's own buttons, in the step buttons' place on the last step (static/js/app.js makeStepped). */
.tw-step-nav > .tw-step-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin: 0 !important; padding: 0 !important;
    border: 0 !important; background: transparent !important; }
.tw-step-nav > .tw-step-actions > * { margin: 0 !important; }

/* Phones: a stepped form's buttons keep one row on every step (2026-10-30): Back as an arrow, the step count left to the
   progress bar above, Next or the form's own buttons at the right, at the same height throughout. */
@media (max-width: 575.98px) {
    .tw-step-nav { flex-wrap: nowrap !important; }
    .tw-step-nav [data-step-count] { display: none; }
    .tw-step-nav [data-step-back] { flex: 0 0 auto; width: 46px; min-width: 46px; padding: 0 !important; font-size: 0; border-radius: 50% !important; }
    .tw-step-nav [data-step-back] i { font-size: 19px; margin: 0 !important; }
    .tw-step-nav [data-step-next], .tw-step-nav > .tw-step-actions { margin-left: auto !important; }
    .tw-step-nav > .tw-step-actions { flex-wrap: nowrap; flex: 0 1 auto; min-width: 0; }
    .tw-step-nav > .tw-step-actions > .btn { white-space: nowrap; padding-left: 14px; padding-right: 14px; }
}

/* Phones (2026-10-30, review of fields): a card row's field takes the card's full width with its button inside the line
   (Record fee payment's "Paying now" and Full spilled past the card), and fields and file pickers look alike everywhere:
   44px, round corners, a soft border, the file picker as a dashed box with its button. */
@media (max-width: 575.98px) {
    table.tw-cards td:has(input:not([type=checkbox]):not([type=radio]):not([type=hidden])),
    table.tw-cards td:has(select), table.tw-cards td:has(textarea) { grid-column: 1 / -1; }
    table.tw-cards td .input-group { flex-wrap: nowrap; width: 100%; }
    table.tw-cards td .input-group > .form-control { min-width: 0; flex: 1 1 auto; }
    table.tw-cards td .input-group > .btn { flex: 0 0 auto; min-height: 44px; }
    .tw-content .form-control, .tw-content .form-select { min-height: 44px; border-radius: 12px; border-color: var(--tw-border); font-size: 16px; }
    .tw-content .input-group > .form-control:not(:first-child), .tw-content .input-group > .btn:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
    .tw-content .input-group > .form-control:not(:last-child), .tw-content .input-group > .btn:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
    .tw-content .form-label { font-size: 13.5px; font-weight: 600; margin-bottom: 6px; }
    .tw-content .form-text, .tw-content .form-hint { font-size: 12.5px; }
    .tw-content input[type="file"].form-control {
        min-height: 64px; padding: 12px; border: 1.5px dashed var(--tw-border); background: var(--tw-surface); font-size: 14px; line-height: 1.3;
    }
    .tw-content input[type="file"].form-control::file-selector-button {
        margin: 0 12px 0 0; padding: 8px 14px; border: 0; border-radius: 10px; font-weight: 600;
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent); color: var(--brand-primary, #1e2a78);
    }
    .tw-content input[type="file"].form-control:focus { border-color: var(--brand-primary, #1e2a78); background: var(--tw-surface-raised); }
}
/* Phones: a field with a button in it (Paying now + Full) is one rounded box with the button inside (2026-10-30). */
@media (max-width: 575.98px) {
    .tw-content .input-group.input-group-flat {
        border: 1px solid var(--tw-border); border-radius: 12px; background: var(--tw-surface-raised); overflow: hidden; align-items: center;
    }
    .tw-content .input-group.input-group-flat:focus-within { border-color: var(--brand-primary, #1e2a78);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #1e2a78) 14%, transparent); }
    .tw-content .input-group.input-group-flat > .form-control,
    .tw-content .input-group.input-group-flat > .input-group-text { border: 0 !important; box-shadow: none !important; background: transparent !important; }
    .tw-content .input-group.input-group-flat > .btn, .tw-content .input-group.input-group-flat > .input-group-text > .btn {
        margin: 4px; min-height: 36px !important; border: 0 !important; border-radius: 9px !important; padding: 0 14px;
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent) !important; color: var(--brand-primary, #1e2a78) !important;
        font-weight: 600;
    }
}
/* Phones: line grids (expenses, bills, LPOs) as cards: each field under its label at full size (2026-10-30). */
@media (max-width: 575.98px) {
    table.tw-lines.tw-cards td { position: static !important; padding: 0 !important; height: auto !important; }
    table.tw-lines.tw-cards td::before { margin-bottom: 4px; }
    table.tw-lines.tw-cards td input:not([type=checkbox]):not([type=hidden]), table.tw-lines.tw-cards td select,
    table.tw-lines.tw-cards td textarea, table.tw-lines.tw-cards td .ts-wrapper, table.tw-lines.tw-cards td .ts-control {
        position: static !important; display: block; width: 100% !important; height: auto !important; min-height: 44px; margin: 0 !important;
        padding: 10px 12px; border: 1px solid var(--tw-border) !important; border-radius: 12px !important; background: var(--tw-surface-raised);
        font-size: 16px; box-shadow: none;
    }
    table.tw-lines.tw-cards td .ts-wrapper { padding: 0; border: 0 !important; }
    table.tw-lines.tw-cards .tw-card-title { font-size: 13px; color: var(--tw-muted); }
}
/* Phones: filter boxes in place of filter buttons (static/js/app.js). */
.tw-filter-row { display: none; }
@media (max-width: 575.98px) {
    .tw-filter-row { display: flex; gap: 8px; width: 100%; }
    .tw-filter-row .tw-filter-select { flex: 1 1 0; min-width: 0; min-height: 42px; border-radius: 12px; font-size: 15px; font-weight: 500; }
    .tw-filter-replaced { display: none !important; }
    .card-header-tabs:has(> li > .tw-filter-replaced), .card-header .nav-tabs:has(> li > .tw-filter-replaced) { display: none !important; }
}
/* Phones: card cells grow with what is in them (a table's fixed row height left Paying now hanging out of its card). */
@media (max-width: 575.98px) {
    table.tw-cards td, table.tw-cards th { height: auto !important; min-height: 0 !important; }
}
/* Phones (2026-10-30: "dropdowns should match their input boxes"): a drop-down is styled exactly as the text field
   beside it, and a list of suggestions opening under a field has the field's width, corners and border. */
@media (max-width: 575.98px) {
    .tw-content .form-select, .modal .form-select, .tw-content .ts-control, .modal .ts-control {
        min-height: 44px; border: 1px solid var(--tw-border) !important; border-radius: 12px !important;
        background-color: var(--tw-surface-raised) !important; font-size: 16px; color: var(--tw-text); box-shadow: none;
        padding-top: 10px; padding-bottom: 10px; padding-left: 12px;
    }
    .tw-content .form-select { padding-right: 36px; background-position: right 12px center; }
    .tw-content .form-select:focus, .tw-content .ts-wrapper.focus .ts-control, .modal .form-select:focus {
        border-color: var(--brand-primary, #1e2a78) !important; box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #1e2a78) 14%, transparent) !important;
    }
    .tw-content .ts-dropdown, .modal .ts-dropdown, .tw-pupil-results:not(:empty), .tw-content .list-group.tw-suggestions {
        margin-top: 4px; border: 1px solid var(--tw-border) !important; border-radius: 12px !important; overflow: hidden;
        background: var(--tw-surface-raised); box-shadow: 0 10px 28px rgba(15, 23, 42, .14);
    }
    .tw-content .ts-dropdown .option, .tw-pupil-results .list-group-item { min-height: 44px; padding: 10px 12px; font-size: 15px; }
}
/* Phones: a pupil search inside a form looks like the form's other fields (the pill is for a list's own search). */
@media (max-width: 575.98px) {
    .tw-pupil-search input[type="search"].form-control, .tw-content form .tw-pupil-search input {
        border-radius: 12px !important; border: 1px solid var(--tw-border) !important; background-color: var(--tw-surface-raised) !important;
    }
    .tw-pupil-search .tw-pupil-chosen { min-height: 44px; border-radius: 12px; }
}

/* The money cycles' step icons as app icons (2026-10-30), each step its own colour:
   computers: Windows 11 (Fluent) tiles, small rounded squares with a soft gradient and a white symbol;
   phones: iPhone app icons, rounder, larger, glossier. */
.tw-acc-steps li:nth-child(6n+1) { --icon: #2563eb; }
.tw-acc-steps li:nth-child(6n+2) { --icon: #16a34a; }
.tw-acc-steps li:nth-child(6n+3) { --icon: #ea580c; }
.tw-acc-steps li:nth-child(6n+4) { --icon: #9333ea; }
.tw-acc-steps li:nth-child(6n+5) { --icon: #0891b2; }
.tw-acc-steps li:nth-child(6n+6) { --icon: #db2777; }
.tw-acc-step .tw-acc-step-icon {
    border-radius: 8px; color: #fff !important;
    background: linear-gradient(145deg, color-mix(in srgb, var(--icon, var(--lane)) 75%, #fff) 0%, var(--icon, var(--lane)) 55%,
                color-mix(in srgb, var(--icon, var(--lane)) 80%, #000) 100%) !important;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .18), inset 0 1px 0 rgba(255, 255, 255, .28);
}
.tw-acc-more-tile .tw-acc-step-icon { background: linear-gradient(145deg, #9aa3af, #6b7280) !important; }
@media (max-width: 575.98px) {
    .tw-acc-step .tw-acc-step-icon {
        border-radius: 14px; width: 52px; height: 52px; font-size: 24px;
        background: linear-gradient(165deg, color-mix(in srgb, var(--icon, var(--lane)) 68%, #fff) 0%, var(--icon, var(--lane)) 58%,
                    color-mix(in srgb, var(--icon, var(--lane)) 84%, #000) 100%) !important;
        box-shadow: 0 3px 8px color-mix(in srgb, var(--icon, var(--lane)) 35%, transparent), inset 0 1px 0 rgba(255, 255, 255, .35);
    }
    .tw-acc-more-tile [aria-expanded="true"] .tw-acc-step-icon { background: linear-gradient(165deg, #6b7280, #374151) !important; }
}
.tw-acc-steps li.tw-acc-more-tile .tw-acc-step .tw-acc-step-icon { background: linear-gradient(160deg, #a3abb7, #6b7280) !important; box-shadow: 0 2px 6px rgba(15, 23, 42, .2); }
/* Phones: the money cycles' icons match the menu tiles (2026-10-30): a soft tint of the colour, the symbol in the colour,
   the menu's corners and size; computers keep the Windows-style tiles. */
@media (max-width: 575.98px) {
    .tw-acc-steps .tw-acc-step .tw-acc-step-icon, .tw-acc-steps li.tw-acc-more-tile .tw-acc-step .tw-acc-step-icon {
        width: 46px; height: 46px; border-radius: 15px; font-size: 21px; box-shadow: none !important;
        color: var(--icon, var(--lane)) !important; background: color-mix(in srgb, var(--icon, var(--lane)) 13%, transparent) !important;
    }
    .tw-acc-steps li.tw-acc-more-tile .tw-acc-step .tw-acc-step-icon { --icon: #6b7280; }
    .tw-acc-steps li.tw-acc-more-tile [aria-expanded="true"] .tw-acc-step-icon { color: #fff !important; background: #6b7280 !important; }
}

/* Computers: a money cycle step shows its Windows 11 (Fluent System) icon in the navigation bar's colour on a light
   tile (accounting_views.PICTURES; 2026-10-30). Phones keep the menu-style icon. */
.tw-acc-picture { display: none; }
@media (min-width: 576px) {
    .tw-acc-step .tw-acc-step-icon.has-picture {
        width: 2.5rem; height: 2.5rem; border-radius: 8px;
        background: linear-gradient(180deg, #ffffff 0%, #f1f3f6 100%) !important;
        box-shadow: 0 1px 2px rgba(0, 0, 0, .12), inset 0 0 0 1px rgba(0, 0, 0, .05) !important;
    }
    [data-bs-theme="dark"] .tw-acc-step .tw-acc-step-icon.has-picture { background: linear-gradient(180deg, #2b313d, #222833) !important; }
    .tw-acc-step .tw-acc-step-icon.has-picture > i { display: none; }
    .tw-acc-step .tw-acc-step-icon.has-picture > .tw-acc-picture {
        display: block; width: 24px; height: 24px;
        background: color-mix(in srgb, var(--brand-primary, #1e2a78) 18%, #1e2533);       /* the navigation bar's colour */
        -webkit-mask: var(--glyph) center / contain no-repeat; mask: var(--glyph) center / contain no-repeat;
    }
    [data-bs-theme="dark"] .tw-acc-step .tw-acc-step-icon.has-picture > .tw-acc-picture { background: #e6e9ef; }
}
/* Phones: buttons in a card row (Requirements check-in: quantity, Brought, Cash) are slim and long, sharing the row
   (2026-10-30: "smaller and longer, a phone app feel"). */
@media (max-width: 575.98px) {
    table.tw-cards td:has(> form.d-flex) { grid-column: 1 / -1; display: block; }
    table.tw-cards td > form.d-flex { width: 100%; gap: 8px !important; align-items: center; }
    table.tw-cards td > form.d-flex > .form-control { flex: 0 0 76px; width: 76px !important; min-height: 38px; text-align: center; }
    table.tw-cards td > form.d-flex > .btn { flex: 1 1 0; min-height: 38px !important; padding-top: 6px; padding-bottom: 6px; border-radius: 10px !important; font-size: 14px; }
}
@media (max-width: 575.98px) { table.tw-cards td.tw-card-empty { display: none !important; } }

/* Rounded fields stay rounded when focused, and drop-downs open rounded (2026-10-30: "rounded fields turn edged on focus
   and drop-down menus have no round borders"). */
.form-control, .form-select, .form-control:focus, .form-select:focus, textarea.form-control:focus { border-radius: var(--tw-field-radius, 8px); }
@media (max-width: 575.98px) { :root { --tw-field-radius: 12px; } }
.input-group > .form-control:focus, .input-group > .form-select:focus { z-index: 3; }
.dropdown-menu { border-radius: 12px; padding: 6px; overflow: hidden; box-shadow: 0 12px 32px rgba(15, 23, 42, .16); }
.dropdown-menu .dropdown-item { border-radius: 8px; }
.tw-pupil-results:not(:empty), .app-search-suggestions .card, .app-search-suggestions > * { border-radius: 12px !important; overflow: hidden; }
/* The list a drop-down opens: rounded where the browser lets a page style it (Chrome and Edge 135+, also on Android);
   iPhones keep their own wheel. Not on the sign-in and sign-up pages, where the styled list did not open inside the
   glass card (staff sign-up's designation, 2026-10-30): the browser's own list there. */
@supports (appearance: base-select) {
    body:not(.auth-page) select.form-select:not([multiple]):not([size]), body:not(.auth-page) select.form-select:not([multiple]):not([size])::picker(select) { appearance: base-select; }
    body:not(.auth-page) select.form-select:not([multiple]):not([size]) { background-image: none; display: flex; align-items: center; }
    body:not(.auth-page) select.form-select:not([multiple]):not([size])::picker-icon { margin-left: auto; color: var(--tw-muted); transition: transform .15s; }
    body:not(.auth-page) select.form-select:not([multiple]):not([size]):open::picker-icon { transform: rotate(180deg); }
    body:not(.auth-page) select.form-select::picker(select) {
        border: 1px solid var(--tw-border); border-radius: 12px; padding: 6px; margin-top: 4px;
        background: var(--tw-surface-raised); box-shadow: 0 12px 32px rgba(15, 23, 42, .16);
    }
    body:not(.auth-page) select.form-select option { padding: 9px 12px; border-radius: 8px; }
    body:not(.auth-page) select.form-select option:hover, body:not(.auth-page) select.form-select option:focus { background: var(--tw-surface); }
    body:not(.auth-page) select.form-select option:checked { background: color-mix(in srgb, var(--brand-primary, #1e2a78) 10%, transparent); font-weight: 600; }
    body:not(.auth-page) select.form-select option::checkmark { color: var(--brand-primary, #1e2a78); }
}
@supports (appearance: base-select) {
    body:not(.auth-page) select.form-select:not([multiple]):not([size])::picker-icon {
        content: ""; width: 12px; height: 12px; background: currentColor;
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
                mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    }
}

/* A view-only role (custom role, 2026-10-30) changes nothing: the page's main add/record button is not offered;
   the server refuses any save anyway (apps/accounts/custom_roles.py). */
.tw-view-only .tw-page-actions > .btn-primary, .tw-view-only .tw-page-actions > a.btn-primary { display: none !important; }

/* ---- The sign-out countdown (static/js/idle.js; as in Twincare, 2026-11-11): a card with a ring that empties,
   a short line of text and one button. On phones it is a sheet across the bottom, above the tab bar, with the
   button full width. ---- */
.tw-idle-banner { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 2000;
    display: flex; align-items: center; gap: 14px; width: max-content; max-width: calc(100vw - 32px); padding: 14px 16px;
    background: var(--tw-surface-raised, #fff); color: var(--tw-text, #1f2937); border: 1px solid var(--tw-border, #e5e7eb);
    border-radius: 18px; box-shadow: 0 18px 44px rgba(15, 23, 42, .22), 0 2px 6px rgba(15, 23, 42, .08); font-size: 14px;
    animation: tw-idle-in .28s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes tw-idle-in { from { opacity: 0; translate: 0 14px; } }
.tw-idle-ring { position: relative; flex: 0 0 auto; width: 44px; height: 44px; }
.tw-idle-ring svg { width: 44px; height: 44px; transform: rotate(-90deg); }
.tw-idle-ring circle { fill: none; stroke-width: 4; }
.tw-idle-track { stroke: color-mix(in srgb, currentColor 12%, transparent); }
.tw-idle-arc { stroke: var(--brand-accent, #f5b400); stroke-linecap: round; stroke-dasharray: 119.4; stroke-dashoffset: 0;
    transition: stroke-dashoffset 1s linear; }
.tw-idle-ring span { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 700; font-size: 15px;
    font-variant-numeric: tabular-nums; }
.tw-idle-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; line-height: 1.3; }
.tw-idle-text strong { font-size: 15px; }
.tw-idle-text span { color: var(--tw-muted, #667382); font-size: 13px; }
.tw-idle-banner .btn { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 767.98px) {
    .tw-idle-banner { left: 12px; right: 12px; width: auto; max-width: none; transform: none; flex-wrap: wrap; padding: 16px;
        border-radius: 22px; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
    .tw-idle-text { flex: 1 1 0; }
    .tw-idle-banner .btn { flex: 1 1 100%; min-height: 46px; font-size: 16px; }
}
/* Phones show the tab bar below 576px: the sheet sits above it. */
@media (max-width: 575.98px) { .tw-idle-banner { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); } }
@media (prefers-reduced-motion: reduce) { .tw-idle-banner { animation: none; } .tw-idle-arc { transition: none; } }

/* ---- Lists as grids (static/js/listgrid.js; as in Twincare, 2026-11-11: "use the grid view for lists like the
   students list, especially on the phone") ----
   A list table is drawn as a spreadsheet: lines between all cells, a sticky header and first column, its own scroll
   box on computers; on phones the page scrolls and the grid scrolls sideways. Click a column's name to sort; a filter
   box sits under each column. */
table.tw-lgrid {
    --lg-line: var(--tw-border); --lg-head: color-mix(in srgb, var(--brand-primary, #1e2a78) 7%, var(--tw-surface-raised, #fff));
    --lg-zebra: color-mix(in srgb, var(--tw-text, #1f2937) 2.5%, var(--tw-surface-raised, #fff));
    --lg-hover: color-mix(in srgb, var(--brand-primary, #1e2a78) 8%, var(--tw-surface-raised, #fff));
    margin-bottom: 0; font-size: 13px; border-collapse: separate; border-spacing: 0; width: 100%;
}
table.tw-lgrid > :not(caption) > * > * { box-shadow: none; }
table.tw-lgrid thead th, table.tw-lgrid.card-table > thead > tr > th {
    position: sticky; top: 0; z-index: 2; background: var(--lg-head) !important; color: var(--tw-text);
    border-bottom: 1px solid color-mix(in srgb, var(--tw-text, #1f2937) 18%, transparent); border-right: 1px solid var(--lg-line);
    font-size: 12px; font-weight: 650; text-transform: none; letter-spacing: 0; padding: 7px 10px; white-space: nowrap; vertical-align: bottom;
}
table.tw-lgrid tbody td, table.tw-lgrid tbody th, table.tw-lgrid tfoot td, table.tw-lgrid tfoot th {
    padding: 6px 10px; vertical-align: middle; white-space: nowrap;
    border-bottom: 1px solid var(--lg-line); border-right: 1px solid var(--lg-line); background: var(--tw-surface-raised, #fff);
}
table.tw-lgrid tbody tr:nth-child(even) > * { background: var(--lg-zebra); }
table.tw-lgrid tbody tr:hover > * { background: var(--lg-hover); --tblr-table-accent-bg: transparent; }
table.tw-lgrid tr > :last-child { border-right: 0; }
table.tw-lgrid tfoot td, table.tw-lgrid tfoot th { font-weight: 650; }
table.tw-lgrid thead tr > :first-child, table.tw-lgrid tbody tr > :first-child { position: sticky; left: 0; z-index: 1; }
table.tw-lgrid thead tr > :first-child { z-index: 3; }
table.tw-lgrid tbody tr > :first-child { box-shadow: inset -1px 0 0 var(--lg-line); max-width: 46vw; overflow: hidden; text-overflow: ellipsis; }
table.tw-lgrid tbody tr > td[colspan]:first-child { position: static; max-width: none; white-space: normal; }
table.tw-lgrid .text-truncate { max-width: 260px; }
.tw-lgrid-scroll { overflow: auto; max-height: calc(100vh - 230px); -webkit-overflow-scrolling: touch; }
.tw-lgrid-sortable { cursor: pointer; user-select: none; -webkit-user-select: none; }
.tw-lgrid-sortable::after { content: "\2195"; margin-left: 6px; font-size: 10px; opacity: .35; }
.tw-lgrid-sortable[aria-sort="ascending"]::after { content: "\25B2"; opacity: .9; color: var(--brand-primary, #1e2a78); }
.tw-lgrid-sortable[aria-sort="descending"]::after { content: "\25BC"; opacity: .9; color: var(--brand-primary, #1e2a78); }
.tw-lgrid-sortable:focus-visible { outline: 2px solid var(--brand-primary, #1e2a78); outline-offset: -2px; }
table.tw-lgrid thead tr.tw-lgrid-filter th { top: var(--tw-lgrid-head-h, 31px); padding: 3px 4px; }
.tw-lgrid-filter-input { width: 100%; min-width: 64px; padding: 2px 6px; font-size: 12px; border: 1px solid var(--tw-border);
    border-radius: 4px; background: var(--tw-surface-raised, #fff); color: var(--tw-text); }
.tw-lgrid-filter-input:focus { outline: none; border-color: var(--brand-primary, #1e2a78); }
.tw-lgrid-note { font-size: 12px; color: var(--tw-muted); padding: 6px 12px; }
@media (max-width: 767.98px) {
    /* Phones: the page scrolls up and down, the grid sideways. */
    .tw-lgrid-scroll { max-height: none; overflow-y: visible; overflow-x: auto; }
    table.tw-lgrid thead th { position: static; }
    table.tw-lgrid thead tr > :first-child { position: sticky; }
}
@media print { .tw-lgrid-scroll { max-height: none; overflow: visible; } .tw-lgrid-filter { display: none; } }

/* ---- Pupil's profile on a phone (2026-11-11: "the profile creates unnecessary tiles that occupy the screen such as
   fee balance; a better phone display that is user friendly and easy to navigate") ----
   In order: the pupil in one compact card (photo, name, class, the contact with call and text), the key figures as
   one slim strip that slides sideways, the buttons in one row, then the tabs; the other cards fold behind one-line
   headings (script at the end of templates/students/student_detail.html). Computers are unchanged. */
.pd-fold-head { display: none; }
@media (max-width: 575.98px) {
    [data-page-body]:has(> .pd-main) { display: flex; flex-direction: column; }
    .pd-main { display: contents; }
    .pd-main > [class*="col-"] { order: 5; width: 100%; max-width: none; padding: 0; margin: 0 0 12px; }
    .pd-main > [class*="col-"]:first-child { order: 1; }
    .pd-main > [class*="col-"]:first-child > .card { height: auto !important; }
    .pd-stats { order: 2; }
    .pd-actions { order: 3; }
    .pd-tabs-card { order: 4; margin-bottom: 12px; }

    /* The pupil: photo beside the name, not above it. */
    .pd-profile .card-body { display: grid; grid-template-columns: 64px minmax(0, 1fr); column-gap: 12px; align-items: center;
        text-align: left !important; padding: 14px; }
    .pd-profile .pd-ring { width: 64px; height: 64px; margin: 0 !important; grid-row: 1 / span 3; align-self: start; }
    .pd-profile .tw-photo-ring { width: 60px; height: 60px; border-width: 2px; }
    .pd-profile .pd-name { font-size: 18px; margin: 0 !important; }
    .pd-profile .card-body > .text-secondary { margin-bottom: 4px !important; font-size: 13px; }
    .pd-profile .card-body > .d-flex.flex-wrap { justify-content: flex-start !important; margin-bottom: 0 !important; }
    .pd-profile .pd-facts { display: none; }                      /* age, sex and dates are on the Overview tab */
    .pd-profile .pd-contact { grid-column: 1 / -1; margin: 12px 0 0 !important; }
    .pd-profile .card-body > .d-flex.justify-content-center { grid-column: 1 / -1; justify-content: flex-start !important; margin-top: 10px; }

    /* Key figures: one strip of small chips. */
    .pd-stats { flex-wrap: nowrap; overflow-x: auto; gap: 8px; margin: 0 -14px 12px !important; padding: 0 14px 2px;
        scrollbar-width: none; -webkit-overflow-scrolling: touch; }
    .pd-stats::-webkit-scrollbar { display: none; }
    .pd-stats > [class*="col-"] { flex: 0 0 auto; width: max-content; min-width: 104px; max-width: none; padding: 0; margin: 0; }
    .pd-stats .pd-stat { border-radius: 14px; }
    .pd-stats .pd-stat .card-body { padding: 8px 12px; }
    .pd-stats .pd-stat-label { font-size: 11px; margin: 0; padding: 0; white-space: nowrap; }
    .pd-stats .pd-stat-label .badge { display: none; }
    .pd-stats .pd-stat-value { font-size: 15px; padding: 0; white-space: nowrap; overflow-wrap: normal; }
    .pd-stats .pd-stat-note { display: none; }

    /* Buttons: one row that slides sideways. */
    .pd-actions { margin: 0 0 12px !important; }
    .pd-actions .breadcrumb { display: none; }
    .pd-actions .btn-list { display: flex; flex-wrap: nowrap; overflow-x: auto; width: 100%; gap: 8px; margin: 0; scrollbar-width: none; }
    .pd-actions .btn-list::-webkit-scrollbar { display: none; }
    .pd-actions .btn-list .btn { flex: 0 0 auto; margin: 0; }

    /* The other cards, each behind its heading. */
    .pd-main > [class*="col-"]:not(:first-child) { gap: 8px !important; }
    .pd-fold-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 48px;
        padding: 10px 14px; border: 1px solid var(--tw-border); border-radius: 14px; background: var(--tw-surface-raised, #fff);
        color: var(--tw-text); font-weight: 600; font-size: 15px; text-align: left; }
    .pd-fold-head i { color: var(--tw-muted); transition: transform .2s ease; }
    .pd-folded > .card-header > .card-title, .pd-folded > .card-body > .d-flex:first-child > .card-title { display: none; }
    .pd-folded > .card-header:not(:has(> :not(.card-title))) { display: none; }
    .pd-fold-head[aria-expanded="true"] i { transform: rotate(180deg); }
    .pd-fold-head[aria-expanded="true"] { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
    .pd-fold-head[aria-expanded="true"] + .card { margin-top: -8px; border-top-left-radius: 0; border-top-right-radius: 0; }
}
@media print { .pd-fold-head { display: none !important; } .pd-folded[hidden] { display: block !important; } }

/* ---- Phones: a profile's figures and tabs as strips (2026-11-11, with the pupil's profile above) ----
   .tw-figure-strip: a row of figure cards becomes one line of small chips that slides sideways.
   .tw-tab-strip: a long set of tabs stays on one line and slides sideways, in place of wrapping over several rows.
   Used on the child's page in the parents' portal and a staff member's Performance page. */
@media (max-width: 575.98px) {
    .tw-figure-strip { flex-wrap: nowrap; overflow-x: auto; gap: 8px; margin: 0 -14px 12px !important; padding: 0 14px 2px;
        scrollbar-width: none; -webkit-overflow-scrolling: touch; }
    .tw-figure-strip::-webkit-scrollbar { display: none; }
    .tw-figure-strip > [class*="col-"] { flex: 0 0 auto; width: max-content; min-width: 112px; max-width: 72vw; padding: 0; margin: 0; }
    .tw-figure-strip .card { height: 100%; border-radius: 14px; margin: 0; }
    .tw-figure-strip .card-body { padding: 8px 12px; }
    .tw-figure-strip .stat-card .avatar { display: none; }
    .tw-figure-strip .stat-card .h2 { font-size: 16px; }
    .tw-figure-strip > [class*="col-"]:has(.stat-card) { width: 140px; min-width: 140px; }
    .tw-figure-strip .stat-card .text-truncate { white-space: normal; overflow: visible; line-height: 1.25; font-size: 11px; }
    .tw-tab-strip { flex-wrap: nowrap !important; overflow-x: auto; margin: 0 -14px 12px !important; padding: 0 14px 4px !important;
        scrollbar-width: none; -webkit-overflow-scrolling: touch; }
    .tw-tab-strip::-webkit-scrollbar { display: none; }
    .tw-tab-strip .nav-item { flex: 0 0 auto; }
    .tw-tab-strip .nav-link { white-space: nowrap; }
}
