/* Shared component styles. Uses tokens only: no colour literals in this file. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); font-size: var(--fs-body); line-height: 1.5;
  color: var(--ink-900); background: var(--canvas); -webkit-font-smoothing: antialiased;
}
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
img { max-width: 100%; display: block; }
h1, h2, h3, h4, p { margin: 0; }
button { font-family: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: var(--s-4); top: -60px; z-index: 100; background: var(--primary); color: var(--on-primary); padding: var(--s-2) var(--s-4); border-radius: var(--r-btn); }
.skip-link:focus { top: var(--s-4); }

/* ---------- type ---------- */
.t-page { font-size: var(--fs-page); font-weight: var(--fw-page); line-height: 28px; }
.t-card { font-size: var(--fs-card); font-weight: var(--fw-card); line-height: 26px; }
.t-sub { font-size: 15px; font-weight: 600; line-height: 22px; }
.t-meta { font-size: var(--fs-meta); font-weight: 500; color: var(--ink-400); }
.t-stat { font-size: var(--fs-stat); font-weight: 700; line-height: 34px; }
.t-label, .th { font-size: var(--fs-th); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-400); }
.t-group { font-size: var(--fs-group); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-400); }
.muted { color: var(--ink-600); }
.faint { color: var(--ink-400); }

/* ---------- layout helpers ---------- */
.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.row { display: flex; align-items: center; gap: var(--s-3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6); }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-6); }
.grid-main { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--s-6); align-items: start; }
@media (max-width: 1180px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-main { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 767px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); } .grid-main { gap: var(--s-4); } }

/* ---------- icons ---------- */
.ic {
  display: inline-block; flex-shrink: 0; width: 20px; height: 20px; background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.ic-14 { width: 14px; height: 14px; } .ic-16 { width: 16px; height: 16px; } .ic-18 { width: 18px; height: 18px; }
.ic-24 { width: 24px; height: 24px; } .ic-32 { width: 32px; height: 32px; } .ic-40 { width: 40px; height: 40px; }
/* sizes passed to icon() that are off the icon scale snap to it (they used to fall back to 20px) */
.ic-12, .ic-13 { width: 14px; height: 14px; } .ic-15 { width: 16px; height: 16px; } .ic-20 { width: 20px; height: 20px; }
.ic-22 { width: 24px; height: 24px; } .ic-26, .ic-28 { width: 28px; height: 28px; }

/* ---------- card ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow); }
.card-pad { padding: var(--s-6); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-5) var(--s-6); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.card-body { padding: var(--s-6); }
.card-foot { padding: var(--s-4) var(--s-6); border-top: 1px solid var(--line); }
@media (min-width: 1280px) { .card-pad, .card-body { padding: var(--s-8); } .card-head { padding: var(--s-6) var(--s-8); } .card-foot { padding: var(--s-4) var(--s-8); } }
.divider { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  height: var(--h-btn); padding: 0 var(--s-4); border-radius: var(--r-btn); border: 1px solid transparent;
  font: inherit; font-size: 14px; font-weight: 600; line-height: 1; cursor: pointer; white-space: nowrap;
  text-decoration: none !important; transition: background-color .15s ease;
}
.btn .ic { width: 18px; height: 18px; }
.btn-sm { height: var(--h-btn-sm); padding: 0 var(--s-3); font-size: 13px; }
.btn-sm .ic { width: 16px; height: 16px; }
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-soft { background: var(--soft); color: var(--on-soft); }
.btn-soft:hover { border-color: var(--line-strong); }
.btn-danger { background: var(--danger); color: var(--on-danger); }
.btn-success { background: var(--success); color: var(--on-success); }
.btn-ghost { background: transparent; color: var(--ink-900); }
.btn-ghost:hover { background: var(--field); }
.btn-outline { background: var(--surface); color: var(--ink-900); border-color: var(--line-strong); }
.btn-outline:hover { background: var(--field); }
.btn-icon { width: var(--h-btn); padding: 0; background: transparent; color: var(--ink-600); }
.btn-icon:hover { background: var(--field); color: var(--ink-900); }
.btn-icon.btn-sm { width: var(--h-btn-sm); }
.btn-block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
@media (max-width: 767px) { .btn { height: 44px; } .btn-sm { height: 44px; } .btn-icon, .btn-icon.btn-sm { width: 44px; } }

/* ---------- pills ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px; height: var(--h-pill); padding: 0 var(--s-2);
  border-radius: var(--r-pill); font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap;
}
.pill .ic { width: 14px; height: 14px; }
.pill-navy, .pill-info, .pill-ended, .pill-submitted, .pill-me, .pill-completed { background: var(--me-bg); color: var(--me-fg); }
.pill-green, .pill-active, .pill-digital, .pill-approved, .pill-published, .pill-accepted, .pill-ee { background: var(--ee-bg); color: var(--ee-fg); }
.pill-amber, .pill-inactive, .pill-nondigital, .pill-progress, .pill-pending, .pill-ae { background: var(--ae-bg); color: var(--ae-fg); }
.pill-crimson, .pill-changes, .pill-declined, .pill-be, .pill-error { background: var(--be-bg); color: var(--be-fg); }
.pill-neutral, .pill-draft, .pill-revoked, .pill-expired { background: var(--field); color: var(--ink-600); }
.pill-ai { background: var(--mustard-50); color: var(--amber-700); }
.chip { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid var(--line-strong); border-radius: var(--r-pill); font-size: 13px; font-weight: 500; color: var(--ink-600); background: var(--surface); }

/* rubric level badges and swatches */
.lvl { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; height: var(--h-pill); padding: 0 6px; border-radius: var(--r-pill); font-size: 12px; font-weight: 700; }
.lvl-ee { background: var(--ee-bg); color: var(--ee-fg); } .lvl-me { background: var(--me-bg); color: var(--me-fg); }
.lvl-ae { background: var(--ae-bg); color: var(--ae-fg); } .lvl-be { background: var(--be-bg); color: var(--be-fg); }
.sw-ee { background: var(--ee); } .sw-me { background: var(--me); } .sw-ae { background: var(--ae); } .sw-be { background: var(--be); }
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

/* rubric segmented selector (radio group) */
.rubric-seg { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-btn); background: var(--field); }
.rubric-seg label { position: relative; }
.rubric-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.rubric-seg span {
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px; height: 36px; padding: 0 10px;
  border-radius: var(--r-pill); font-size: 13px; font-weight: 700; color: var(--ink-600); cursor: pointer; border: 1px solid transparent;
}
.rubric-seg input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 1px; }
.rubric-seg input[value="EE"]:checked + span { background: var(--ee-bg); color: var(--ee-fg); border-color: var(--ee); }
.rubric-seg input[value="ME"]:checked + span { background: var(--me-bg); color: var(--me-fg); border-color: var(--me); }
.rubric-seg input[value="AE"]:checked + span { background: var(--ae-bg); color: var(--ae-fg); border-color: var(--ae); }
.rubric-seg input[value="BE"]:checked + span { background: var(--be-bg); color: var(--be-fg); border-color: var(--be); }
@media (max-width: 767px) { .rubric-seg span { height: 44px; } }

/* ---------- forms ---------- */
.field { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
fieldset.field { margin: 0; padding: 0; border: 0; }
.field > label, .field-label { font-size: 13px; font-weight: 600; color: var(--ink-900); }
.req { color: var(--crimson-700); margin-left: 2px; }
.input, .select, .textarea {
  width: 100%; height: var(--h-input); padding: 0 14px; border-radius: var(--r-input); border: 1px solid transparent;
  background: var(--canvas); color: var(--ink-900); font: inherit; font-size: 14px;
}
.rb-dark-fix, [data-theme="dark"] .input, [data-theme="dark"] .select, [data-theme="dark"] .textarea { background: var(--field); }
.textarea { height: auto; min-height: 96px; padding: 12px 14px; resize: vertical; line-height: 1.5; }
.select { appearance: none; -webkit-appearance: none; padding-right: 40px; cursor: pointer; }
.select-wrap { position: relative; }
.select-wrap .ic { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--ink-600); width: 16px; height: 16px; }
.input::placeholder, .textarea::placeholder { color: var(--ink-400); }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--focus); background: var(--surface); }
.field.has-error .input, .field.has-error .select, .field.has-error .textarea { border-color: var(--danger); background: var(--crimson-50); }
.help { font-size: 12px; color: var(--ink-400); }
.error-text { font-size: 12px; font-weight: 500; color: var(--crimson-700); display: flex; align-items: center; gap: 6px; }
.input-icon { position: relative; }
.input-icon > .ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-400); width: 18px; height: 18px; }
.input-icon .input { padding-left: 42px; }
.check { display: inline-flex; align-items: center; gap: var(--s-2); cursor: pointer; font-weight: 500; }
.check input { width: 18px; height: 18px; accent-color: var(--primary); margin: 0; }
.switch { position: relative; display: inline-flex; align-items: center; gap: var(--s-3); cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch .track { width: 40px; height: 24px; border-radius: var(--r-full); background: var(--line-strong); position: relative; transition: background .15s; flex-shrink: 0; }
.switch .track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--white); box-shadow: var(--shadow); transition: transform .15s; }
.switch input:checked + .track { background: var(--primary); }
.switch input:checked + .track::after { transform: translateX(16px); }
.switch input:focus-visible + .track { outline: 2px solid var(--focus); outline-offset: 2px; }

/* dropzone */
.dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2); text-align: center;
  padding: var(--s-8) var(--s-6); border: 1px dashed var(--navy-700); border-radius: var(--r-card); background: var(--soft); color: var(--on-soft); cursor: pointer;
}
.dropzone.is-over { border-style: solid; }
/* keyboard focus: the file input is visually hidden, so the label shows the ring */
.dropzone:focus-within { outline: 2px solid var(--focus); outline-offset: 2px; }
.dropzone .ic { color: var(--on-soft); }
.file-row { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) var(--s-3); border: 1px solid var(--line); border-radius: var(--r-btn); }

/* ---------- tables ---------- */
.table-wrap { width: 100%; overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; padding: var(--s-4) var(--s-3); border-bottom: 1px solid var(--line); white-space: nowrap; font-size: var(--fs-th); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-400); }
.table td { padding: var(--s-4) var(--s-3); border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tr:last-child td { border-bottom: 0; }
.table th:first-child, .table td:first-child { padding-left: 0; }
.table th:last-child, .table td:last-child { padding-right: 0; }
.table .col-actions { text-align: right; white-space: nowrap; }
.sort-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 0; padding: 0; font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.sort-btn .ic { width: 16px; height: 16px; }
.tile-ic { width: 44px; height: 44px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.tile-green { background: var(--green-50); color: var(--green-700); } .tile-amber { background: var(--amber-50); color: var(--amber-700); }
.tile-navy { background: var(--navy-50); color: var(--on-soft); } .tile-crimson { background: var(--crimson-50); color: var(--crimson-700); }
.pager { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; padding-top: var(--s-5); }
.pager-pages { display: flex; align-items: center; gap: 4px; }
.page-btn { min-width: 32px; height: 32px; border-radius: var(--r-btn); border: 0; background: transparent; color: var(--ink-600); font: inherit; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.page-btn[aria-current="page"] { background: var(--primary); color: var(--on-primary); }
.page-btn:disabled { opacity: .4; cursor: not-allowed; }
.skel { display: block; height: 12px; border-radius: var(--r-pill); background: var(--skeleton); animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }
/* tables become stacked cards on mobile */
@media (max-width: 767px) {
  .table-cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .table-cards, .table-cards tbody, .table-cards tr, .table-cards td { display: block; width: 100%; }
  .table-cards tr { border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-3); background: var(--surface); }
  .table-cards td { border: 0; padding: 6px 0 !important; display: flex; justify-content: space-between; align-items: center; gap: var(--s-3); text-align: right; }
  .table-cards td::before { content: attr(data-label); font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-400); text-align: left; }
  .table-cards td.cell-primary { display: block; text-align: left; padding-bottom: var(--s-2) !important; }
  .table-cards td.cell-primary::before, .table-cards td.col-check::before { content: none; }
  .table-cards td.col-check { position: absolute; width: auto; right: var(--s-4); }
  .table-cards tr { position: relative; }
  .table-cards .col-actions { justify-content: flex-end; }
}

/* ---------- toolbar (DataTable) ---------- */
.toolbar { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-4); }
.toolbar .input-icon { flex: 1 1 240px; max-width: 320px; }
.toolbar .select-wrap { flex: 0 0 180px; }
.toolbar .spacer { flex: 1 1 auto; }
.bulk-bar { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) var(--s-3); background: var(--soft); color: var(--on-soft); border-radius: var(--r-btn); margin-bottom: var(--s-3); font-weight: 600; }
@media (max-width: 767px) { .toolbar .input-icon, .toolbar .select-wrap { flex: 1 1 100%; max-width: none; } }

/* ---------- stat card ---------- */
.stat { display: flex; align-items: flex-start; gap: var(--s-4); }
.stat .tile-ic { width: 48px; height: 48px; border-radius: var(--r-card); }

/* ---------- empty state ---------- */
.empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--s-3); padding: var(--s-12) var(--s-6); }
.empty .tile-ic { width: 64px; height: 64px; }
.empty p { max-width: 420px; color: var(--ink-600); }

/* ---------- modal / dialog ---------- */
.modal-backdrop { position: fixed; inset: 0; background: var(--scrim); display: flex; align-items: center; justify-content: center; padding: var(--s-4); z-index: 60; }
.modal { width: 100%; max-width: var(--modal-w); max-height: calc(100vh - 32px); display: flex; flex-direction: column; background: var(--surface); border-radius: var(--r-modal); box-shadow: var(--shadow-pop); }
.modal-lg { max-width: 800px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-5) var(--s-6); border-bottom: 1px solid var(--line); }
.modal-body { padding: var(--s-6); overflow-y: auto; display: flex; flex-direction: column; gap: var(--s-4); }
.modal-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--s-6); border-top: 1px solid var(--line); }
.confirm { max-width: 420px; text-align: center; }
.confirm .modal-body { align-items: center; padding: var(--s-10) var(--s-8) var(--s-6); gap: var(--s-5); }
.confirm-mark { width: 72px; height: 72px; border-radius: 50%; border: 3px solid var(--danger); color: var(--danger); display: flex; align-items: center; justify-content: center; font-size: 40px; font-weight: 500; line-height: 1; }
.confirm-actions { display: flex; gap: var(--s-3); justify-content: center; flex-wrap: wrap; }
.confirm-note { display: flex; align-items: center; justify-content: center; gap: var(--s-2); color: var(--crimson-700); font-size: 13px; padding: var(--s-4) var(--s-6); border-top: 1px solid var(--line); margin: 0 var(--s-6); }
.drawer-panel { position: fixed; top: 0; right: 0; bottom: 0; width: min(480px, 100%); background: var(--surface); box-shadow: var(--shadow-pop); z-index: 61; display: flex; flex-direction: column; }
@media (max-width: 767px) { .modal-backdrop { align-items: flex-end; padding: 0; } .modal { max-width: none; border-radius: var(--r-modal) var(--r-modal) 0 0; } }

/* ---------- toasts ---------- */
.toasts { position: fixed; right: var(--s-6); bottom: var(--s-6); z-index: 80; display: flex; flex-direction: column; gap: var(--s-2); }
.toast { display: flex; align-items: center; gap: var(--s-3); min-width: 280px; max-width: 420px; padding: var(--s-3) var(--s-4); border-radius: var(--r-card); background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-pop); font-weight: 500; }
.toast-success .ic { color: var(--green-700); } .toast-error .ic { color: var(--crimson-700); } .toast-info .ic { color: var(--on-soft); }
@media (max-width: 767px) { .toasts { left: var(--s-4); right: var(--s-4); bottom: var(--s-4); } .toast { min-width: 0; max-width: none; } }

/* ---------- popovers / menus ---------- */
.pop { position: absolute; z-index: 40; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-pop); padding: var(--s-2); min-width: 220px; }
.pop[hidden] { display: none; }
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; height: 40px; padding: 0 var(--s-3); border: 0; border-radius: var(--r-btn); background: transparent; color: var(--ink-900); font: inherit; font-weight: 500; text-align: left; cursor: pointer; text-decoration: none !important; }
.menu-item:hover, .menu-item[aria-checked="true"] { background: var(--field); }
.menu-item .ic { width: 18px; height: 18px; color: var(--ink-600); }

/* ---------- avatars, crests, placeholders ---------- */
.avatar { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--soft); color: var(--on-soft); font-weight: 600; flex-shrink: 0; overflow: hidden; }
.avatar-32 { width: 32px; height: 32px; font-size: 12px; } .avatar-40 { width: 40px; height: 40px; font-size: 14px; }
.avatar-48 { width: 48px; height: 48px; font-size: 16px; } .avatar-96 { width: 96px; height: 96px; font-size: 28px; }
.crest { display: inline-flex; align-items: center; justify-content: center; border-radius: var(--r-card); font-weight: 700; flex-shrink: 0; border: 1px solid var(--line); }
.crest-40 { width: 40px; height: 40px; font-size: 14px; } .crest-56 { width: 56px; height: 56px; font-size: 18px; } .crest-96 { width: 96px; height: 96px; font-size: 28px; }
.crest-32 { width: 32px; height: 32px; font-size: 12px; } .crest-48 { width: 48px; height: 48px; font-size: 16px; } .crest-72 { width: 72px; height: 72px; font-size: 24px; }
/* no-access state (AppShell): the page renders behind it, hidden */
.page-main > .page-head[hidden], .page-main > .page-body[hidden] { display: none !important; }
.no-access { max-width: 720px; width: 100%; margin: var(--s-6) auto 0; }
/* SchoolCrest: an uploaded school logo sits on a neutral tile, fitted inside the crest box */
.crest-logo { background: var(--surface); padding: 4px; overflow: hidden; }
.crest-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.crest-72.crest-logo, .crest-96.crest-logo { padding: 6px; }
.crest-navy { background: var(--crest-navy-bg); color: var(--crest-navy-fg); } .crest-crimson { background: var(--crest-crimson-bg); color: var(--crest-crimson-fg); }
.crest-green { background: var(--crest-green-bg); color: var(--crest-green-fg); } .crest-amber { background: var(--crest-amber-bg); color: var(--crest-amber-fg); }
.ph { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; background: var(--field); border: 1px dashed var(--line-strong); color: var(--ink-400); font-size: 12px; font-weight: 600; border-radius: var(--r-btn); }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: var(--s-6); border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.tab { height: 48px; display: inline-flex; align-items: center; background: none; border: 0; border-bottom: 2px solid transparent; padding: 0; color: var(--ink-600); font: inherit; font-size: 15px; font-weight: 500; white-space: nowrap; cursor: pointer; }
.tab[aria-selected="true"] { color: var(--ink-900); border-bottom-color: var(--primary); font-weight: 600; }

/* ---------- progress bars ---------- */
.bar { height: 8px; border-radius: var(--r-full); background: var(--field); overflow: hidden; display: flex; }
.bar > span { display: block; height: 100%; }
.bar-primary > span { background: var(--primary); }

/* ---------- banners ---------- */
.banner { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-4); border-radius: var(--r-btn); font-weight: 500; }
.banner-info { background: var(--soft); color: var(--on-soft); }
.banner-warn { background: var(--amber-50); color: var(--amber-700); }
.banner-danger { background: var(--crimson-50); color: var(--crimson-700); }
.banner-success { background: var(--green-50); color: var(--green-700); }

/* ---------- timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.timeline li { display: grid; grid-template-columns: 24px 1fr; gap: var(--s-3); padding-bottom: var(--s-4); position: relative; }
.timeline li::before { content: ""; position: absolute; left: 11px; top: 24px; bottom: 0; width: 2px; background: var(--line); }
.timeline li:last-child::before { content: none; }
.timeline .dot { width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--soft); color: var(--on-soft); }
.timeline .dot .ic { width: 14px; height: 14px; }

/* ---------- list rows ---------- */
.list { list-style: none; margin: 0; padding: 0; }
.list > li { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-4) 0; border-bottom: 1px solid var(--line); }
.list > li:last-child { border-bottom: 0; }

/* =====================================================================
   App shell (spec section 3). Recreated from Samples Image-020/030/040.
   ===================================================================== */
.shell { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }
.shell.is-collapsed { grid-template-columns: var(--rail-w) minmax(0, 1fr); }
.sidebar {
  position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column;
  background: var(--surface); border-right: 1px solid var(--line); z-index: 50;
}
.sb-head { height: var(--topbar-h); display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); padding: 0 var(--s-3) 0 var(--s-6); flex-shrink: 0; }
.sb-logo { display: flex; align-items: center; }
.sb-logo img { height: 45px; width: auto; }
.logo-mark { display: none; }
.logo-on-dark { display: none; }
[data-theme="dark"] .logo-on-light { display: none; }
[data-theme="dark"] .logo-full.logo-on-dark { display: block; }
.sb-collapse { border: 1px solid var(--line); width: 32px; height: 32px; }
.sb-close { display: none; }
.sb-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--s-2) var(--s-4) var(--s-4); scrollbar-width: thin; }
.sb-group + .sb-group { margin-top: var(--s-5); }
.sb-group-label { padding: 0 var(--s-2) var(--s-2); }
.sb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  display: flex; align-items: center; gap: var(--s-3); width: 100%; height: 44px; padding: 0 var(--s-3);
  border: 0; border-radius: var(--r-btn); background: transparent; color: var(--ink-900); font: inherit; font-size: 14px; font-weight: 500;
  text-align: left; cursor: pointer; text-decoration: none !important;
}
.nav-item > .ic:first-child { color: var(--ink-600); }
.nav-item:hover { background: var(--field); }
.nav-item.is-active { background: var(--soft); color: var(--on-soft); font-weight: 600; }
.nav-item.is-active > .ic:first-child { color: var(--on-soft); }
.nav-item.is-planned { color: var(--ink-400); cursor: default; }
.nav-item.is-planned:hover { background: transparent; }
.nav-soon { font-size: 11px; font-weight: 600; color: var(--ink-400); border: 1px solid var(--line-strong); border-radius: var(--r-pill); padding: 1px 6px; }
.nav-caret { color: var(--ink-600); transition: transform .15s; }
[aria-expanded="true"] > .nav-caret { transform: rotate(180deg); }
.nav-subs { list-style: none; margin: 2px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.nav-sub { height: 40px; padding-left: 44px; font-size: 13px; color: var(--ink-600); }
.sb-rule { border: 0; height: 1px; background: var(--line); margin: 0 var(--s-2) var(--s-3); }
.sb-foot { padding: var(--s-4) var(--s-5) var(--s-5); flex-shrink: 0; }

/* collapsed rail */
.is-collapsed .sb-head { padding: 0; flex-direction: column; justify-content: center; gap: var(--s-2); height: auto; padding: var(--s-4) 0; }
.is-collapsed .logo-full { display: none !important; }
.is-collapsed .logo-mark.logo-on-light { display: block; height: 38px; }
[data-theme="dark"] .is-collapsed .logo-mark.logo-on-light { display: none; }
[data-theme="dark"] .is-collapsed .logo-mark.logo-on-dark { display: block; height: 38px; }
.is-collapsed .sb-nav { padding: var(--s-2) var(--s-3); }
.is-collapsed .nav-item { justify-content: center; padding: 0; }
.is-collapsed .nav-subs { display: none; }
.is-collapsed .sb-foot { padding: var(--s-3); }
.is-collapsed .sb-foot .btn { padding: 0; }
.is-collapsed .sb-foot-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* main column */
.shell-main { min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
.topbar {
  position: sticky; top: 0; z-index: 30; height: var(--topbar-h); display: flex; align-items: center; gap: var(--s-4);
  padding: 0 var(--s-8); background: var(--surface); border-bottom: 1px solid var(--line);
}
.tb-drawer { display: none; }
.tb-context { display: flex; align-items: center; gap: var(--s-3); min-width: 0; flex: 1 1 auto; }
.tb-context-text { min-width: 0; }
.tb-school { font-size: 18px; font-weight: 700; line-height: 24px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb-meta { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; line-height: 18px; }
.tb-role { color: var(--ink-600); }
.tb-dot { color: var(--ink-300); }
.tb-switch { color: var(--link); font-weight: 600; }
.tb-actions { display: flex; align-items: center; gap: var(--s-1); flex-shrink: 0; }
.tb-pop-wrap { position: relative; }
.tb-pop { right: 0; top: calc(100% + 8px); }
.tb-search { width: 340px; padding: var(--s-3); }
.tb-notes { width: 360px; }
.tb-note-list { max-height: 360px; overflow-y: auto; }
.tb-note-list > li { padding: 0; border: 0; }
.tb-note { display: flex; align-items: flex-start; gap: var(--s-3); width: 100%; padding: var(--s-2); border-radius: var(--r-btn); color: var(--ink-900); text-decoration: none !important; min-height: 44px; }
.tb-note:hover { background: var(--field); }
.tb-note:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.tb-note .tile-ic { flex-shrink: 0; }
.tb-note.is-unread .tile-ic { background: var(--primary); color: var(--white); }
.tb-note-body { display: block; font-size: 13px; line-height: 18px; color: var(--ink-600); margin: 2px 0; }
.tb-account { width: 280px; }
.tb-bell { position: relative; }
.tb-count { position: absolute; top: 4px; right: 4px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-full); background: var(--danger); color: var(--on-danger); font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
.tb-avatar { border: 0; padding: 0; background: none; border-radius: 50%; cursor: pointer; margin-left: var(--s-2); }

.shell-scroll { flex: 1 1 auto; display: flex; flex-direction: column; }
.page { width: 100%; max-width: calc(var(--content-max) + 2 * var(--s-8)); margin: 0 auto; padding: var(--s-6) var(--s-8) var(--s-10); flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--s-6); }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; }
.ph-left { display: flex; align-items: center; gap: var(--s-3); min-width: 0; flex-wrap: wrap; }
.ph-rule { width: 1px; height: 20px; background: var(--line-strong); }
.crumbs { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; font-size: var(--fs-meta); font-weight: 500; color: var(--ink-400); }
.crumbs li { display: flex; gap: 6px; }
.crumbs a { color: var(--ink-400); }
.ph-right { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin-left: auto; justify-content: flex-end; }
.session-chip { display: inline-flex; align-items: center; gap: var(--s-2); height: 32px; padding: 0 var(--s-2) 0 4px; border: 0; background: transparent; border-radius: var(--r-btn); font: inherit; cursor: pointer; color: var(--ink-600); }
.session-chip:hover { background: var(--field); }
.session-label { background: var(--soft); color: var(--on-soft); font-size: 12px; font-weight: 600; padding: 3px 8px; border-radius: var(--r-pill); }
.session-value { font-size: 14px; font-weight: 500; }
.session-pop { width: 260px; }
.page-main { display: flex; flex-direction: column; gap: var(--s-6); outline: none; flex: 1 1 auto; }
.page-body { display: flex; flex-direction: column; gap: var(--s-6); }
.parent-banner { margin-bottom: calc(-1 * var(--s-2)); }
/* The banner's link sits in running text, so it is underlined everywhere (axe link-in-text-block). */
.parent-banner a { text-decoration: underline; text-underline-offset: 2px; }
.footer { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; padding: var(--s-5) var(--s-8); font-size: 13px; color: var(--ink-600); }
.footer nav { display: flex; gap: var(--s-4); }
.footer a { color: var(--ink-600); font-weight: 500; }

/* below 1024px: sidebar becomes an off-canvas drawer */
@media (max-width: 1023px) {
  .shell, .shell.is-collapsed { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; width: min(var(--sidebar-w), 86vw); transform: translateX(-100%); transition: transform .2s ease; box-shadow: var(--shadow-pop); visibility: hidden; }
  .drawer-open .sidebar { transform: none; visibility: visible; }
  .drawer-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 45; }
  .sb-collapse { display: none; }
  .sb-close { display: inline-flex; }
  .is-collapsed .sb-head { flex-direction: row; padding: 0 var(--s-3) 0 var(--s-6); height: var(--topbar-h); }
  .is-collapsed .logo-full.logo-on-light { display: block !important; }
  .is-collapsed .logo-mark { display: none !important; }
  .is-collapsed .nav-item { justify-content: flex-start; padding: 0 var(--s-3); }
  .tb-drawer { display: inline-flex; margin-left: calc(-1 * var(--s-2)); }
  .topbar { padding: 0 var(--s-6); }
  .page { padding: var(--s-5) var(--s-6) var(--s-8); }
  .footer { padding: var(--s-4) var(--s-6); }
}
@media (max-width: 767px) {
  .topbar { padding: 0 var(--s-4); gap: var(--s-2); }
  .tb-hide-sm { display: none; }
  .tb-context .crest { display: none; }
  .tb-school { font-size: 15px; line-height: 20px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .tb-notes, .tb-account { position: fixed; left: var(--s-4); right: var(--s-4); top: calc(var(--topbar-h) + 4px); width: auto; }
  .tb-avatar { margin-left: 0; }
  .page { padding: var(--s-4) var(--s-4) var(--s-8); gap: var(--s-4); }
  .ph-rule { display: none; }
  .ph-left { flex-direction: column; align-items: flex-start; gap: 2px; }
  .page-head { align-items: flex-start; }
  .session-chip { height: 44px; }
  .footer { flex-direction: column; align-items: flex-start; padding: var(--s-4); }
  .footer a { display: inline-flex; min-height: 44px; align-items: center; }
}

/* =====================================================================
   Component library additions (tokens only). See app/pages/system/components.*
   ===================================================================== */

/* DataTable bulk-select checkboxes: sized to match .check input without needing the label wrapper */
.dt-check { width: 18px; height: 18px; accent-color: var(--primary); margin: 0; }

/* AuthBackdrop: full-viewport classroom photo + centred white card (sign in / OTP / invitation) */
.auth-backdrop {
  min-height: 100vh; width: 100%; display: flex; align-items: center; justify-content: center;
  padding: var(--s-6); background-size: cover; background-position: center;
}
.auth-card {
  width: 100%; background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-pop);
  padding: var(--s-8); display: flex; flex-direction: column; gap: var(--s-5);
}
.auth-logo { display: flex; justify-content: center; }
.auth-logo img { height: 40px; width: auto; }
@media (max-width: 480px) {
  .auth-backdrop { padding: var(--s-4); }
  .auth-card { max-width: none !important; padding: var(--s-6); }
}

/* ---------- rubric legend (inline) ---------- */
.rubric-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); font-size: 13px; }
.rubric-legend li { display: inline-flex; align-items: center; gap: 6px; }

.auth-backdrop { position: relative; isolation: isolate; }
.auth-backdrop::before { content: ""; position: absolute; inset: 0; background: var(--backdrop-dim); z-index: -1; }

/* ---------- touch targets and hit areas ---------- */
.dt-hit { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; min-height: 32px; cursor: pointer; }
@media (max-width: 767px) {
  .page-main { gap: var(--s-4); }
  .page-body { gap: var(--s-4); }
  .tb-drawer, .topbar .btn-icon { width: 44px; height: 44px; }
  .tb-avatar .avatar { width: 44px; height: 44px; }
  .dt-hit { min-width: 44px; min-height: 44px; }
  .dt-check { width: 22px; height: 22px; }
  .page-btn { min-width: 44px; height: 44px; }
  .pager .select, .pager select { height: 44px; }
  .sort-btn { min-height: 44px; }
  .crumbs a { display: inline-flex; min-height: 44px; align-items: center; }
  .nav-item, .menu-item { min-height: 44px; }
}

/* =====================================================================
   Custom dropdown (components/CustomSelect.js). Native <select> stays as the value source.
   ===================================================================== */
.cs-native { position: absolute !important; width: 1px !important; height: 1px !important; opacity: 0; pointer-events: none; overflow: hidden; clip: rect(0 0 0 0); }
.cs-wrap > .ic { display: none; }
.cs-trigger {
  display: flex; align-items: center; gap: var(--s-2); width: 100%; height: var(--h-input); padding: 0 12px 0 14px;
  border-radius: var(--r-input); border: 1px solid transparent; background: var(--canvas); color: var(--ink-900);
  font: inherit; font-size: 14px; text-align: left; cursor: pointer;
}
[data-theme="dark"] .cs-trigger { background: var(--field); }
.cs-trigger:hover { border-color: var(--line-strong); }
.cs-trigger:focus-visible, .cs-trigger[aria-expanded="true"] { outline: none; border-color: var(--focus); background: var(--surface); box-shadow: 0 0 0 3px var(--soft); }
.cs-trigger.is-empty .cs-value { color: var(--ink-400); }
.cs-trigger[aria-invalid="true"], .field.has-error .cs-trigger { border-color: var(--danger); background: var(--crimson-50); }
.cs-trigger:disabled { opacity: .5; cursor: not-allowed; }
.cs-value { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-caret { color: var(--ink-600); transition: transform .15s ease; }
.cs-trigger[aria-expanded="true"] .cs-caret { transform: rotate(180deg); }
.toolbar .cs-trigger, .pager .cs-trigger { height: var(--h-btn); }

.cs-panel {
  position: fixed; z-index: 90; max-width: min(420px, calc(100vw - 32px)); max-height: 320px; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-pop); overflow: hidden;
}
.cs-search { padding: var(--s-2); border-bottom: 1px solid var(--line); }
.cs-search .input { height: 36px; }
.cs-list { list-style: none; margin: 0; padding: var(--s-1); overflow-y: auto; }
.cs-list ul { list-style: none; margin: 0; padding: 0; }
.cs-group { display: block; padding: var(--s-2) var(--s-3) var(--s-1); font-size: var(--fs-group); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-400); }
.cs-option { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 8px var(--s-3); border-radius: var(--r-btn); cursor: pointer; color: var(--ink-900); }
.cs-option.is-active { background: var(--field); }
.cs-option[aria-selected="true"] { color: var(--on-soft); font-weight: 600; }
.cs-option[aria-selected="true"]:not(.is-active) { background: var(--soft); }
.cs-option[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.cs-text { flex: 1 1 auto; }
.cs-tick { visibility: hidden; color: var(--on-soft); }
.cs-option[aria-selected="true"] .cs-tick { visibility: visible; }
.cs-box { width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--border-input-hover); flex-shrink: 0; position: relative; background: var(--surface); }
.cs-option[aria-selected="true"] .cs-box { background: var(--primary); border-color: var(--primary); }
.cs-option[aria-selected="true"] .cs-box::after { content: ""; position: absolute; left: 5px; top: 1.5px; width: 5px; height: 10px; border: solid var(--on-primary); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.cs-none { padding: var(--s-3); color: var(--ink-400); }
.cs-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 89; }
.cs-panel.is-sheet { left: 0; right: 0; bottom: 0; top: auto; max-width: none; max-height: 70vh; border-radius: var(--r-modal) var(--r-modal) 0 0; }
.cs-panel.is-sheet .cs-option { min-height: 48px; }

/* =====================================================================
   Custom checkboxes and radios (native inputs, restyled; hidden inputs in
   .rubric-seg, .switch and .cs-native keep their own treatment).
   ===================================================================== */
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]),
input[type="radio"]:not(.rubric-seg input):not(.switch input):not(.sr-only):not([data-native]) {
  appearance: none; -webkit-appearance: none; margin: 0; flex-shrink: 0; cursor: pointer; position: relative;
  width: 18px; height: 18px; border: 1.5px solid var(--border-input-hover); background: var(--surface);
  display: inline-grid; place-content: center; transition: background-color .12s ease, border-color .12s ease;
}
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]) { border-radius: 5px; }
input[type="radio"]:not(.rubric-seg input):not(.switch input):not(.sr-only):not([data-native]) { border-radius: 50%; }
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):hover,
input[type="radio"]:not(.rubric-seg input):not(.switch input):not(.sr-only):not([data-native]):hover { border-color: var(--primary); }
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):checked,
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):indeterminate { background: var(--primary); border-color: var(--primary); }
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):checked::after {
  content: ""; width: 5px; height: 10px; margin-top: -2px; border: solid var(--on-primary); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):indeterminate::after { content: ""; width: 10px; height: 2px; background: var(--on-primary); border-radius: 1px; }
input[type="radio"]:not(.rubric-seg input):not(.switch input):not(.sr-only):not([data-native]):checked { border-color: var(--primary); border-width: 5px; }
input[type="checkbox"]:not(.switch input):not(.rubric-seg input):not(.sr-only):not([data-native]):focus-visible,
input[type="radio"]:not(.rubric-seg input):not(.switch input):not(.sr-only):not([data-native]):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
input[type="checkbox"]:disabled, input[type="radio"]:disabled { opacity: .45; cursor: not-allowed; }
.field.has-error input[type="checkbox"], .field.has-error input[type="radio"] { border-color: var(--danger); }
.check { min-height: 32px; }
@media (max-width: 767px) { .check { min-height: 44px; } }

/* =====================================================================
   UI standard v2 (user direction 28/09/2026): bordered inputs with clear
   hover and focus, stronger card edges, richer toasts, loaders.
   ===================================================================== */
.input, .select, .textarea, .cs-trigger {
  background: var(--surface); border: 1px solid var(--border-input); box-shadow: var(--shadow-input);
  transition: border-color .12s ease, box-shadow .12s ease, background-color .12s ease;
}
[data-theme="dark"] .input, [data-theme="dark"] .select, [data-theme="dark"] .textarea, [data-theme="dark"] .cs-trigger { background: var(--field); border-color: var(--border-input); }
.input:hover, .select:hover, .textarea:hover, .cs-trigger:hover { border-color: var(--border-input-hover); }
.input:focus, .select:focus, .textarea:focus, .cs-trigger:focus-visible, .cs-trigger[aria-expanded="true"] {
  outline: none; border-color: var(--focus); background: var(--surface); box-shadow: 0 0 0 3px var(--soft);
}
.input:disabled, .select:disabled, .textarea:disabled { background: var(--field); color: var(--ink-400); cursor: not-allowed; }
.input[readonly] { background: var(--field); }
.field.has-error .input, .field.has-error .select, .field.has-error .textarea, .field.has-error .cs-trigger,
.input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--danger); background: var(--surface); box-shadow: 0 0 0 3px var(--crimson-50); }
.field.is-valid .input { border-color: var(--success); }
.card { border-color: var(--line-strong); }
.btn-outline { border-color: var(--line-strong); }
.btn-danger-outline { background: var(--surface); color: var(--crimson-700); border-color: var(--danger); }
.btn-danger-outline:hover { background: var(--crimson-50); }

/* toasts v2 */
.toasts { top: calc(var(--topbar-h) + var(--s-3)); bottom: auto; right: var(--s-6); width: 380px; }
.toast { position: relative; overflow: hidden; align-items: flex-start; gap: var(--s-3); padding: var(--s-4); border-color: var(--line-strong); animation: toast-in .2s ease; }
.toast .toast-ic { width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.toast-success .toast-ic { background: var(--green-50); color: var(--green-700); }
.toast-error .toast-ic { background: var(--crimson-50); color: var(--crimson-700); }
.toast-info .toast-ic { background: var(--soft); color: var(--on-soft); }
.toast-warning .toast-ic { background: var(--amber-50); color: var(--amber-700); }
.toast .toast-ic .ic { width: 18px; height: 18px; color: inherit; }
.toast-title { font-weight: 600; line-height: 20px; }
.toast-msg { color: var(--ink-600); font-size: 13px; line-height: 18px; }
.toast-bar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; transform-origin: left; animation: toast-bar linear forwards; }
.toast-success .toast-bar { background: var(--green-500); } .toast-error .toast-bar { background: var(--danger); }
.toast-info .toast-bar { background: var(--primary); } .toast-warning .toast-bar { background: var(--amber-500); }
.toast:hover .toast-bar { animation-play-state: paused; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } }
@keyframes toast-bar { to { transform: scaleX(0); } }
@media (max-width: 767px) { .toasts { top: auto; bottom: var(--s-4); left: var(--s-4); right: var(--s-4); width: auto; } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

/* loaders */
.spinner { display: inline-block; width: 18px; height: 18px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: spin .7s linear infinite; flex-shrink: 0; opacity: .9; }
.spinner-lg { width: 32px; height: 32px; border-width: 3px; color: var(--primary); }
@keyframes spin { to { transform: rotate(360deg); } }
.btn.is-loading { pointer-events: none; }
.btn.is-loading > :not(.spinner) { opacity: .7; }
.loading-block { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-3); padding: var(--s-12) var(--s-6); color: var(--ink-600); }
.progress-top { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 100; background: var(--soft); overflow: hidden; }
.progress-top::after { content: ""; position: absolute; inset: 0; width: 40%; background: var(--primary); animation: indet 1.1s ease-in-out infinite; }
@keyframes indet { from { transform: translateX(-100%); } to { transform: translateX(260%); } }
@media (prefers-reduced-motion: reduce) { .spinner, .progress-top::after { animation-duration: 2.4s; } }
.card > .tabs, .card > div > .tabs:first-child { padding: 0 var(--s-6); }
@media (min-width: 1280px) { .card > .tabs, .card > div > .tabs:first-child { padding: 0 var(--s-8); } }
@media (max-width: 767px) { .card > .tabs, .card > div > .tabs:first-child { padding: 0 var(--s-4); } }

/* Safety net: toolbars, tables and pagers inside a card but outside a .card-body get the card's inner padding. */
.card .toolbar { padding: var(--s-6) var(--s-6) 0; }
.card .table-wrap, .card .bulk-bar { margin-left: var(--s-6); margin-right: var(--s-6); }
.card .table-wrap { width: auto; }
.card .pager { padding: var(--s-4) var(--s-6) var(--s-5); border-top: 1px solid var(--line); }
.card .card-body .toolbar, .card .card-pad .toolbar { padding: 0; }
.card .card-body .table-wrap, .card .card-pad .table-wrap, .card .card-body .bulk-bar, .card .card-pad .bulk-bar { margin-left: 0; margin-right: 0; }
.card .card-body .pager, .card .card-pad .pager { padding: var(--s-5) 0 0; border-top: 0; }
@media (min-width: 1280px) {
  .card .toolbar { padding: var(--s-8) var(--s-8) 0; }
  .card .table-wrap, .card .bulk-bar { margin-left: var(--s-8); margin-right: var(--s-8); }
  .card .pager { padding: var(--s-4) var(--s-8) var(--s-6); }
}
@media (max-width: 767px) {
  .card .toolbar { padding: var(--s-4) var(--s-4) 0; }
  .card .table-wrap, .card .bulk-bar { margin-left: var(--s-4); margin-right: var(--s-4); }
  .card .pager { padding: var(--s-3) var(--s-4) var(--s-4); }
}
/* Tables: comfortable row height and a hover state */
.table tbody tr { transition: background-color .12s ease; }
.table tbody tr:hover { background: var(--canvas); }
.table td { padding-top: var(--s-4); padding-bottom: var(--s-4); }

/* =====================================================================
   Design round r1 system fixes (design-director verdict 28/09/2026)
   ===================================================================== */
/* shell: hidden labels must not leak the sidebar's scroll height */
.sb-nav { position: relative; }
.sb-foot { border-top: 1px solid var(--line); }

/* page header: breadcrumb line above a prominent title, actions on the same row */
.page-head { align-items: flex-end; gap: var(--s-4) var(--s-6); }
.ph-left { flex-direction: column; align-items: flex-start; gap: 6px; flex: 1 1 320px; }
.ph-crumbs .crumbs { font-size: 13px; gap: 4px; }
.ph-crumbs .crumbs li { align-items: center; gap: 4px; }
.crumb-sep { display: inline-flex; color: var(--ink-300); }
.ph-title { font-size: 24px; line-height: 32px; font-weight: 700; letter-spacing: -.01em; }
.ph-lead { color: var(--ink-600); max-width: 720px; }
.ph-back { display: none; }
.ph-right { gap: var(--s-2); }

/* session chip in the top bar */
.tb-session { margin-right: var(--s-2); }
.tb-session .session-chip { height: 40px; padding: 0 var(--s-3) 0 6px; border: 1px solid var(--line-strong); border-radius: var(--r-full); }
.tb-session .session-label { border-radius: var(--r-full); }
.tb-session .session-pop { right: 0; }
@media (max-width: 1100px) { .tb-session .session-label { display: none; } .tb-session .session-chip { padding-left: var(--s-3); } }

@media (max-width: 767px) {
  .ph-crumbs { display: none; }
  .ph-back { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; font-size: 13px; font-weight: 600; color: var(--ink-600); }
  .ph-title { font-size: 22px; line-height: 28px; }
  .ph-left { flex-basis: 100%; }
  .ph-right { width: 100%; }
  .ph-right > .btn, .ph-right > a.btn { flex: 1 1 auto; }
  .tb-session { margin-right: 0; }
  .tb-session .session-chip { height: 40px; padding: 0 10px; }
  .tb-session .session-value { font-size: 13px; }
}
@media (max-width: 420px) { .tb-session .session-value { max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } }

/* DataTable v2: tabs, nowrap, clickable rows, compact pager, composed mobile cards */
.dt-tabs { display: flex; gap: var(--s-1); padding: 4px; margin-bottom: var(--s-4); background: var(--field); border-radius: var(--r-btn); width: max-content; max-width: 100%; overflow-x: auto; }
.dt-tab { display: inline-flex; align-items: center; gap: var(--s-2); height: 34px; padding: 0 var(--s-3); border: 0; border-radius: 6px; background: transparent; color: var(--ink-600); font: inherit; font-weight: 600; font-size: 13px; cursor: pointer; white-space: nowrap; }
.dt-tab[aria-selected="true"] { background: var(--surface); color: var(--ink-900); box-shadow: var(--shadow); }
.dt-tab-count { min-width: 22px; height: 20px; padding: 0 6px; border-radius: var(--r-full); background: var(--line); color: var(--ink-600); font-size: 11px; display: inline-flex; align-items: center; justify-content: center; }
.dt-tab[aria-selected="true"] .dt-tab-count { background: var(--soft); color: var(--on-soft); }
.table .nowrap { white-space: nowrap; }
.table tr.is-clickable { cursor: pointer; }
.row-link { color: inherit !important; font-weight: 600; text-decoration: none !important; }
.row-link:hover { text-decoration: underline !important; }
.pager-compact { justify-content: flex-start; }
@media (max-width: 767px) {
  .dt-tabs { width: 100%; }
  .table-cards tbody tr { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-3) var(--s-3); padding: var(--s-4); }
  .table-cards tbody td, .table-cards tbody td.cell-primary { display: block; width: auto; padding: 0 !important; text-align: left; border: 0; }
  .table-cards tbody td::before { display: block; margin-bottom: 2px; font-size: 11px; letter-spacing: .04em; }
  .table-cards tbody td.col-check { position: static; order: 0; flex: 0 0 auto; }
  .table-cards tbody td.cell-primary { order: 1; flex: 1 1 0; min-width: 0; font-weight: 600; }
  .table-cards tbody td.m-badge { order: 2; flex: 0 0 auto; }
  .table-cards tbody td.m-badge::before { content: none; }
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions) { order: 3; flex: 1 1 calc(50% - var(--s-3)); min-width: 0; font-size: 13px; }
  .table-cards tbody td.m-hide { display: none; }
  .table-cards tbody td.col-actions { order: 4; flex: 1 1 100%; display: flex; justify-content: flex-end; gap: var(--s-1); padding-top: var(--s-3) !important; border-top: 1px solid var(--line); }
  .table-cards tbody td.col-actions::before { content: none; }
}
@media (max-width: 767px) {
  .table-cards tbody td.cell-primary { flex: 1 1 calc(100% - 150px); }
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions) { flex-basis: calc(50% - var(--s-3)); }
  .table-cards tbody tr::after { content: ""; order: 2; flex-basis: 100%; height: 0; }
  .toolbar .select-wrap, .toolbar .cs-wrap { flex: 1 1 calc(50% - var(--s-3)); max-width: none; }
  .toolbar .input-icon { flex-basis: 100%; }
}

/* building blocks (components/Blocks.js) */
.tiles { display: grid; grid-template-columns: repeat(var(--tile-count, 4), minmax(0, 1fr)); gap: var(--s-4); }
.tile { display: flex; align-items: flex-start; gap: var(--s-4); padding: var(--s-5); background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-card); box-shadow: var(--shadow); min-width: 0; }
.tile .tile-ic { width: 44px; height: 44px; border-radius: var(--r-card); }
.tile-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tile-label { font-size: 13px; font-weight: 500; color: var(--ink-600); }
.tile-value { font-size: 26px; line-height: 32px; font-weight: 700; letter-spacing: -.01em; }
.tile-hint { font-size: 12px; color: var(--ink-400); }
@media (max-width: 1100px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) { .tiles { gap: var(--s-3); } .tile { padding: var(--s-4); gap: var(--s-3); } .tile .tile-ic { display: none; } .tile-value { font-size: 22px; line-height: 28px; } }

.kv { display: grid; grid-template-columns: repeat(var(--kv-cols, 2), minmax(0, 1fr)); gap: var(--s-4) var(--s-6); margin: 0; }
.kv-item { min-width: 0; }
.kv dt { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-400); }
.kv dd { margin: 4px 0 0; font-weight: 500; overflow-wrap: anywhere; }
@media (max-width: 767px) { .kv { grid-template-columns: 1fr; gap: var(--s-3); } }

.form-section { margin: 0; padding: var(--s-6); border: 1px solid var(--line-strong); border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow); display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--s-6); min-width: 0; }
.form-section-head { float: left; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.form-section-title { font-size: 15px; font-weight: 600; color: var(--ink-900); }
.form-section-text { font-size: 13px; line-height: 18px; color: var(--ink-600); }
.form-section-body { min-width: 0; display: flex; flex-direction: column; gap: var(--s-5); }
@media (max-width: 1100px) { .form-section { grid-template-columns: 1fr; gap: var(--s-4); } }
@media (max-width: 767px) { .form-section { padding: var(--s-4); } }
/* top bar at phone widths */
.session-short { display: none; }
.tb-theme-item { display: none; }
@media (max-width: 767px) {
  .tb-school { -webkit-line-clamp: 1; font-size: 15px; }
  .tb-session .session-value { display: none; }
  .tb-session .session-short { display: inline; font-size: 13px; font-weight: 600; }
  .tb-session .session-chip { padding: 0 8px 0 10px; gap: 4px; }
}
@media (max-width: 480px) {
  .tb-role, .tb-dot { display: none; }
  .tb-theme { display: none; }
  .tb-theme-item { display: flex; }
}

/* segmented control (shared): <div class="segmented" role="radiogroup"><label><input type="radio" class="sr-only" name="x"><span>Day</span></label>...</div> */
.segmented { display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--r-btn); background: var(--field); border: 1px solid var(--line); }
.segmented label { position: relative; }
.segmented input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.segmented span, .segmented button { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 var(--s-3); border: 0; border-radius: 6px; background: transparent; color: var(--ink-600); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.segmented input:checked + span, .segmented button[aria-pressed="true"], .segmented button[aria-selected="true"] { background: var(--surface); color: var(--ink-900); box-shadow: var(--shadow); }
.segmented input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 1px; }
@media (max-width: 767px) { .segmented span, .segmented button { height: 40px; } }

/* =====================================================================
   List kit (components/ListKit.js): row menu, progress cell, row actions
   ===================================================================== */
/* ---------- list kit (row menu, progress cell, row actions) ---------- */
.row-actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-1); }
.row-menu { display: inline-flex; }
/* Every "more" menu uses vertical dots. */
.ic.i-more-dots { transform: rotate(90deg); }
.row-menu-btn[aria-expanded="true"] { background: var(--field); color: var(--ink-900); }
.row-menu-panel { z-index: 60; }
.menu-item-danger, .menu-item-danger .ic { color: var(--crimson-700) !important; }
.menu-item-danger:hover { background: var(--crimson-50) !important; }
.prog-cell { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.prog-bar { flex: 1 1 auto; min-width: 72px; max-width: 140px; height: 6px; }
.prog-bar > span { background: var(--primary); }
.prog-bar.is-done > span { background: var(--ee); }
.prog-text { font-size: 13px; color: var(--ink-600); white-space: nowrap; font-variant-numeric: tabular-nums; }
.prog-text b { color: var(--ink-900); font-weight: 600; }
.table td.col-actions { width: 1%; white-space: nowrap; }
@media (max-width: 767px) {
  .table-cards tbody td.col-actions { justify-content: stretch; }
  .row-actions { width: 100%; }
  .row-actions > .btn { flex: 1 1 auto; }
  .prog-bar { max-width: none; }
}

/* status tabs and search share one row above the table */
@media (min-width: 1024px) {
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)), .list-card .dt { display: flex; flex-wrap: wrap; align-items: flex-start; column-gap: var(--s-4); }
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)) > *, .list-card .dt > * { flex: 0 0 100%; min-width: 0; }
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)) > .dt-tabs, .list-card .dt > .dt-tabs { flex: 0 1 auto; }
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)) > .toolbar, .list-card .dt > .toolbar { flex: 1 1 280px; justify-content: flex-end; }
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)) > .toolbar .spacer, .list-card .dt > .toolbar .spacer { display: none; }
  .dt:has(> .dt-tabs):not(:has(> .toolbar .select-wrap)) > .toolbar .input-icon, .list-card .dt > .toolbar .input-icon { flex: 1 1 240px; max-width: 300px; }
}


/* pager page-size select reads as a dropdown */
.pager .cs-trigger { width: 76px; height: 36px; padding: 0 8px 0 12px; }
.pager .cs-wrap > .ic { display: none; }
/* mobile: a row whose only action is the menu does not need its own actions row */
@media (max-width: 767px) {
  .table-cards tbody tr:has(td.col-actions .row-actions > .row-menu:only-child) td.col-actions { order: 2; flex: 0 0 auto; border-top: 0; padding-top: 0 !important; }
}

/* sidebar column spans the full page height; its content stays pinned to the viewport */
.sidebar { height: auto; align-self: stretch; position: relative; }
.sb-inner { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; }
@media (max-width: 1023px) {
  .sidebar { position: fixed; height: auto; }
  .sb-inner { position: static; height: 100%; }
}

/* mobile table cards: rows without actions draw no empty action row */
@media (max-width: 767px) { .table-cards tbody td.col-actions:empty { display: none; } }
/* horizontally scrolling tab strips show a thin scrollbar and snap to tabs */
.tabs, .dt-tabs { scrollbar-width: thin; scroll-snap-type: x proximity; }
.tabs > *, .dt-tabs > * { scroll-snap-align: start; }

/* print: only the page content, never the app chrome */
@media print {
  .sidebar, .topbar, .footer, .drawer-scrim, .toasts, .skip-link, .ph-right, .tb-pop-wrap { display: none !important; }
  .shell, .shell.is-collapsed { display: block; }
  .page { max-width: none; padding: 0; }
  body { background: var(--white); }
}
.avatar-24 { width: 24px; height: 24px; font-size: 10px; }
.tile-value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 44px touch targets at phone widths for the session chip and table controls */
@media (max-width: 767px) {
  .tb-session .session-chip { height: 44px; }
  .toolbar .cs-trigger, .pager .cs-trigger, .toolbar .input, .toolbar .btn { height: 44px; }
  .dt-tab { height: 44px; min-height: 44px; }
  .dt-tabs { padding: 2px; }
}

/* date field (DD/MM/YYYY text input + calendar button driving a hidden native date input) */
.date-field { position: relative; }
.date-field .input { padding-right: 48px; }
.date-btn {
  position: absolute; right: 2px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border: 0; border-radius: var(--r-btn);
  background: transparent; color: var(--ink-600); display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.date-btn:hover { background: var(--field); color: var(--ink-900); }
.date-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.date-native { position: absolute; right: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; border: 0; padding: 0; }
/* password show/hide: 18px glyph centred in a 40px hit area inside the 44px input */
.pw-wrap { position: relative; }
.pw-wrap .input { padding-right: 48px; }
.pw-wrap .pw-toggle { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: var(--r-btn); }
.pw-wrap .pw-toggle .ic { width: 18px; height: 18px; }
/* colour helpers used instead of inline colour styles */
.text-danger { color: var(--crimson-700); }
.lvl-none { background: var(--field); color: var(--ink-600); }
.tok-chip { background: var(--swatch); }

/* =====================================================================
   Phone-width guarantees (accessibility round 2). Minimum sizes use
   !important so area stylesheets cannot shrink controls below 44px.
   ===================================================================== */
@media (max-width: 767px) {
  .tb-drawer { min-width: 44px !important; min-height: 44px !important; margin-left: 0; }
  .tb-switch { display: inline-flex; align-items: center; min-height: 44px; }
  .tb-meta { line-height: 1; }
  .tb-session .session-chip, .dt-tab, .cs-trigger, .segmented span, .segmented button,
  .pw-wrap .pw-toggle, .date-btn, .page-btn, .sort-btn, .ph-back, .row-menu-btn, .btn { min-height: 44px !important; }
  .pw-wrap .pw-toggle, .date-btn, .page-btn, .row-menu-btn, .btn-icon, .tb-drawer { min-width: 44px !important; }
  .sort-btn { min-width: 44px; }
  /* mobile card actions: always inside the card, wrapping, right-aligned */
  .table-cards tbody td.col-actions { flex: 1 1 100% !important; width: auto !important; min-width: 0; white-space: normal !important; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s-2); }
  .table-cards tbody td.col-actions > *, .table-cards tbody td.col-actions .row-actions { max-width: 100%; }
  .table-cards tbody td.col-actions .row-actions { width: auto; flex-wrap: wrap; justify-content: flex-end; }
  .table-cards tbody tr { overflow: hidden; }
}

/* compact mobile cards: denser meta, smaller padding */
@media (max-width: 767px) {
  .table-cards tbody tr { padding: var(--s-3) var(--s-4); gap: var(--s-2) var(--s-3); }
  .table-cards tbody td::before { font-size: 10px; margin-bottom: 0; }
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions) { font-size: 13px; line-height: 18px; }
  .table-cards tbody td.col-actions { padding-top: var(--s-2) !important; }
}

/* phones: a row whose only action is the overflow menu keeps the menu beside the title */
@media (max-width: 767px) {
  .table-cards tbody td.col-actions:has(> .row-actions > .row-menu:only-child),
  .table-cards tbody td.col-actions:has(> .row-menu:only-child) { flex: 0 0 auto !important; order: 2; border-top: 0; padding-top: 0 !important; }
}

/* phone cards: meta values read as one compact line ("value · value"), no label blocks */
@media (max-width: 767px) {
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions):not(.m-hide) { flex: 0 1 auto !important; color: var(--ink-600); }
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions)::before { content: none !important; }
  .table-cards tbody td.cell-primary + td:not(.m-badge):not(.col-actions):not(.m-hide),
  .table-cards tbody td.m-badge + td:not(.col-actions):not(.m-hide) { flex-basis: auto; }
}
@media (max-width: 767px) {
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions):not(.m-hide) { display: inline-flex !important; align-items: baseline; min-width: 0; max-width: 100%; }
  .table-cards tbody td:not(.cell-primary):not(.m-badge):not(.col-check):not(.col-actions):not(.m-hide) > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

@media (max-width: 767px) { .table-cards tbody tr { column-gap: var(--s-4); } }

/* phones: the row-menu trigger is a full 44px target */
@media (max-width: 767px) { .table-cards tbody td.col-actions .row-menu-btn { width: 44px; height: 44px; } }

/* Phone targets, general form (spec 7): every button, tab, radio and disclosure is at least
   44px tall, and links that open a row or record are 44px blocks. Inline links inside running
   text are exempt (WCAG 2.5.8). */
@media (max-width: 767px) {
  #app button:not(.sr-only):not([hidden]), #app [role="tab"], #app [role="radio"], #app summary,
  #app .chip, #app .merge-chip, #app .view-toggle button, #app .ann-title-btn { min-height: 44px; }
  #app .row-link, #app .doc-title, #app .ev-text, #app a.card-link, #app .ann-title-btn { display: inline-flex; flex-direction: column; justify-content: center; min-height: 44px; }
  #app .merge-chip, #app .chip { padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; }
}
@media (max-width: 767px) {
  /* standalone links (not inside running text) are 44px tall targets too */
  #app a[href]:not(.btn):not(.nav-item):not(.menu-item):not(p a):not(dd a):not(label a):not(.t-meta a):not(.crumbs a) { display: inline-flex; align-items: center; min-height: 44px; }
  #app .auth-logo, #app .sm-logo, #app .gw-logo-sm, #app .onb-logo-sm { display: inline-flex; align-items: center; min-height: 44px; }
}

/* shared rules consolidated from area stylesheets (code-quality iteration 4) */
.page-body > * { min-width: 0; }
.link-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.sa-school-cell { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.sa-school-cell .crest { flex-shrink: 0; }
@media (max-width: 767px) {
  .page-body .card-head:has(> .btn-ghost) { flex-wrap: nowrap; align-items: flex-start; }
  .page-body .card-head .btn-ghost { flex-shrink: 0; margin-right: -8px; }
  .table-cards tbody td.col-actions:has(> .row-actions > .row-menu:only-child) .row-actions { width: auto; }
}
/* phone targets: widths too (44px minimum for every button and standalone link) */
@media (max-width: 767px) {
  #app button:not(.sr-only):not([hidden]), #app [role="tab"], #app [role="radio"], #app summary { min-width: 44px; }
  #app a[href]:not(.btn):not(.nav-item):not(.menu-item):not(p a):not(dd a):not(label a):not(.t-meta a):not(.crumbs a) { min-width: 44px; justify-content: center; }
  #app .footer a { min-width: 44px; justify-content: center; }
}
/* phone targets: labels that wrap a checkbox or radio are the real tap target */
@media (max-width: 767px) {
  #app label:has(> input[type="checkbox"]), #app label:has(> input[type="radio"]), #app .check, #app .rb-tag { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; }
}
/* tab strips scroll; their tabs never shrink below their label (fixes phone overlap) */
.tab, .dt-tab, #app [role="tab"] { flex-shrink: 0; }

/* toolbar dropdowns match the 44px search field in the same row */
.toolbar .cs-trigger { height: var(--h-input); }

/* =====================================================================
   Design round 3 system fixes
   ===================================================================== */
/* 1. phone links: 44px tall but never centred or clipped; only icon-only links centre */
@media (max-width: 767px) {
  #app a[href]:not(.btn):not(.nav-item):not(.menu-item):not(p a):not(dd a):not(label a):not(.t-meta a):not(.crumbs a) { justify-content: flex-start; text-align: left; min-width: 0; max-width: 100%; }
  #app a[href]:has(> .ic:only-child) { justify-content: center; min-width: 44px; }
  #app a[href]:not(.btn):not(.nav-item):not(.menu-item):not(p a):not(dd a):not(label a):not(.t-meta a):not(.crumbs a):is(.row-link, .doc-title, .ev-text) { align-items: flex-start; justify-content: center; }
  #app .footer a { justify-content: center; }
}
/* 3. confirm dialogs follow their tone: crimson only for danger */
.confirm-success .confirm-mark, .confirm-primary .confirm-mark, .confirm-soft .confirm-mark { border-color: var(--primary); color: var(--on-soft); }
.confirm-success .confirm-mark { border-color: var(--success); color: var(--green-700); }
.confirm-success .confirm-note, .confirm-primary .confirm-note, .confirm-soft .confirm-note { color: var(--ink-600); }
/* 2. one shared sticky action bar: pinned to the bottom, full content width, solid surface */
.sticky-bar { position: sticky; bottom: 0; z-index: 25; display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin: 0 calc(-1 * var(--s-8)); padding: var(--s-3) var(--s-8); background: var(--surface); border-top: 1px solid var(--line-strong); box-shadow: 0 -4px 12px -8px var(--scrim); }
.sticky-bar .sticky-bar-text { margin-right: auto; }
/* Last thing on the page: sit on the footer instead of 40px above it (.page bottom padding). */
.sticky-bar:last-child { margin-bottom: calc(-1 * var(--s-10)); }
@media (max-width: 1023px) { .sticky-bar:last-child { margin-bottom: calc(-1 * var(--s-8)); } }
@media (max-width: 1023px) { .sticky-bar { margin: 0 calc(-1 * var(--s-6)); padding: var(--s-3) var(--s-6); } }
@media (max-width: 767px) { .sticky-bar { margin: 0 calc(-1 * var(--s-4)); padding: var(--s-3) var(--s-4); } .sticky-bar .btn { flex: 1 1 auto; } }
/* 4. scrolling tab strips hint that more tabs exist */
.tabs, .dt-tabs { overscroll-behavior-x: contain; }
.tabs.has-more, .dt-tabs.has-more { box-shadow: inset -16px 0 12px -12px var(--scrim); }
/* 5. meter cells keep their bar and value on phone cards */
@media (max-width: 767px) {
  .table-cards tbody td .bar, .table-cards tbody td .prog-bar { min-width: 96px; flex: 1 1 96px; }
  .table-cards tbody td:has(.bar), .table-cards tbody td:has(.prog-bar) { flex: 1 1 100% !important; display: flex !important; align-items: center; gap: var(--s-2); }
  .table-cards tbody td:has(.bar)::before, .table-cards tbody td:has(.prog-bar)::before { content: attr(data-label) !important; display: inline; font-size: 12px; text-transform: none; letter-spacing: 0; color: var(--ink-600); min-width: 96px; }
}
@media (max-width: 767px) { #app .footer a, #app .trip-sos, #app a.btn-icon { min-width: 44px !important; justify-content: center !important; } }

/* join confirmation (components/JoinConfirm.js), also used on the invitation page */
.join-modal .modal-body { display: flex; flex-direction: column; gap: var(--s-5); }
.join-hero { display: flex; align-items: center; gap: var(--s-4); }
.join-hero > div { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.join-school { font-size: 17px; font-weight: 700; line-height: 24px; }
.join-can { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-3) var(--s-4); border-radius: var(--r-btn); background: var(--soft); color: var(--on-soft); font-size: 14px; line-height: 20px; }
.join-can .ic { flex-shrink: 0; margin-top: 1px; }
.join-note { display: flex; align-items: center; gap: var(--s-2); font-size: 13px; color: var(--ink-600); }
.join-note .ic { color: var(--ink-400); flex-shrink: 0; }
.join-kids { display: flex; flex-direction: column; gap: var(--s-2); }
.join-kids ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.join-kids li { display: flex; align-items: center; gap: var(--s-2); }
.join-kids .ic { color: var(--on-soft); flex-shrink: 0; }

/* ---------- invitation links (components/InviteLink.js): wizard step 5, verification pending, Invitations ---------- */
.il { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.il-form-grid { display: grid; grid-template-columns: minmax(0, 1.2fr) auto minmax(0, .8fr); gap: var(--s-5); align-items: start; }
.il-days { align-self: flex-start; }
.il-create-row { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.il-live { display: grid; grid-template-columns: minmax(0, 1fr) 128px; gap: var(--s-5); align-items: start; }
.il-live-main { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.il-url-row { display: flex; gap: var(--s-2); min-width: 0; }
.il-url-wrap { position: relative; flex: 1 1 auto; min-width: 0; }
.il-url-wrap > .ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-400); pointer-events: none; }
.il-url { padding-left: 42px; font-weight: 600; font-variant-numeric: tabular-nums; text-overflow: ellipsis; background: var(--canvas); }
.il-facts { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-5); font-size: 13px; color: var(--ink-600); }
.il-facts li { display: inline-flex; align-items: center; gap: 6px; }
.il-facts .ic { color: var(--ink-400); }
.il-facts strong { color: var(--ink-900); font-weight: 600; }
.il-live-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.il-qr { width: 128px; height: 128px; gap: 2px; }
.il-qr .ic { color: var(--ink-400); margin-bottom: 4px; }
.il-qr-note { font-weight: 500; font-size: 11px; }
.il-modal-lead { margin-bottom: var(--s-5); }

.il-card .card-head { align-items: flex-start; flex-wrap: nowrap; }
.il-card-title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.il-card-actions { display: flex; align-items: center; gap: var(--s-3); flex-shrink: 0; }
.il-list { list-style: none; margin: calc(-1 * var(--s-3)) 0; padding: 0; }
.il-row { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: var(--s-4); align-items: center; padding: var(--s-4) 0; }
.il-row + .il-row { border-top: 1px solid var(--line); }
.il-row-ic { width: 40px; height: 40px; }
.il-row.is-revoked .il-row-ic, .il-row.is-expired .il-row-ic { background: var(--field); color: var(--ink-400); }
.il-row-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.il-row-url { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; font-weight: 600; }
.il-row-code { overflow-wrap: anywhere; }
.il-row.is-revoked .il-row-code, .il-row.is-expired .il-row-code { color: var(--ink-600); text-decoration: line-through; text-decoration-color: var(--ink-300); }
.il-row-actions { display: flex; gap: var(--s-2); }
.il-empty { display: flex; align-items: center; gap: var(--s-4); }

@media (max-width: 1100px) {
  .il-form-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .il-form-grid > .field:first-child { grid-column: 1 / -1; }
}
@media (max-width: 767px) {
  .il-form-grid { grid-template-columns: 1fr; }
  .il-days { display: flex; }
  .il-days label { flex: 1 1 0; }
  .il-days span { width: 100%; justify-content: center; }
  .il-create-row .btn { flex: 1 1 100%; }
  .il-live { grid-template-columns: 1fr; }
  .il-url-row { flex-direction: column; }
  .il-qr { width: 100%; height: 96px; flex-direction: row; gap: var(--s-2); }
  .il-qr .ic { margin: 0; }
  .il-live-actions .btn { flex: 1 1 0; }
  .il-card .card-head { flex-direction: column; align-items: stretch; }
  .il-card-actions { justify-content: space-between; }
  .il-row { grid-template-columns: 40px minmax(0, 1fr); }
  .il-row-actions { grid-column: 1 / -1; }
  .il-row-actions .btn { flex: 1 1 0; }
}

/* =====================================================================
   Document view: DocSheet, DocViewToggle, DocFrame (components/DocSheet.js)
   Printable professional documents in the format teachers already use. The sheet is .paper,
   so it stays white with dark ink in dark mode. One shared print block at the end.
   ===================================================================== */
.dv-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.dv-bar-actions { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.dv-toggle button { height: 38px; }
.dv-hint { display: flex; align-items: center; justify-content: center; gap: var(--s-2); margin: 0 0 var(--s-2); padding: var(--s-2) var(--s-3); border-radius: var(--r-btn); background: var(--soft); color: var(--on-soft); font-size: 13px; font-weight: 500; }
.dv-hint[hidden] { display: none; }
.dv-frame { overflow-x: auto; overscroll-behavior-x: contain; padding: 0 0 var(--s-3); scrollbar-width: thin; }
.dv-frame:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-card); }
.dv-doc { display: flex; flex-direction: column; min-width: 0; }
.dv-doc[hidden], [data-dv][hidden] { display: none !important; }
.dv-doc-tools { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-bottom: var(--s-4); }
@media (max-width: 767px) {
  .dv-bar { align-items: stretch; }
  .dv-toggle { width: 100%; }
  .dv-toggle button { flex: 1 1 0; justify-content: center; height: 40px; }
  .dv-bar-actions { width: 100%; }
  .dv-bar-actions .btn { flex: 1 1 auto; min-height: 44px; }
}

/* the paper sheet */
/* crests on any paper sheet resolve their tone against the paper colours, also in dark mode */
.paper { --crest-navy-bg: var(--soft); --crest-navy-fg: var(--on-soft); --crest-crimson-bg: var(--crimson-50); --crest-crimson-fg: var(--crimson-700); --crest-green-bg: var(--green-50); --crest-green-fg: var(--green-700); --crest-amber-bg: var(--amber-50); --crest-amber-fg: var(--amber-700); }
.doc-sheet {
  --crest-navy-bg: var(--soft); --crest-navy-fg: var(--on-soft); --crest-crimson-bg: var(--crimson-50); --crest-crimson-fg: var(--crimson-700);
  --crest-green-bg: var(--green-50); --crest-green-fg: var(--green-700); --crest-amber-bg: var(--amber-50); --crest-amber-fg: var(--amber-700);
  position: relative; box-sizing: border-box; margin: 0; display: flex; flex-direction: column; gap: var(--s-4);
  width: 100%; padding: var(--s-10); border: 1px solid var(--line-strong); border-radius: 4px; box-shadow: var(--shadow);
  font-family: var(--font); font-size: 12.5px; line-height: 1.45; font-variant-numeric: tabular-nums;
}
.doc-sheet[data-orient="landscape"] { min-width: 960px; }
.doc-sheet[data-orient="portrait"] { max-width: 794px; }
@media (max-width: 767px) { .doc-sheet { padding: var(--s-8); } .doc-sheet[data-orient="portrait"] { min-width: 720px; } }
/* Document widths (Design rules): landscape sheets fill the page content width like any card (a readable
   960px minimum only matters inside the scroll frame below 1024px); portrait sheets keep A4 proportion at
   794px, left aligned to the content edge, and the document bar becomes a sticky panel on their right. */
@media (min-width: 1180px) {
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) {
    display: grid; grid-template-columns: 794px minmax(0, 1fr); grid-auto-flow: row dense; gap: var(--gap-section, var(--s-6)); align-items: start;
  }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > * { grid-column: 1 / -1; }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > .dv-doc { grid-column: 1; }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > .dv-bar {
    grid-column: 2; position: sticky; top: calc(var(--topbar-h) + var(--s-6)); flex-direction: column; align-items: stretch; gap: var(--s-4);
    padding: var(--s-5); background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-card); box-shadow: var(--shadow);
  }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > .dv-bar :is(.dv-toggle, .dv-bar-actions) { width: 100%; }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > .dv-bar .dv-toggle > * { flex: 1 1 0; justify-content: center; }
  :is(.page-body, .page-body div):has(> .dv-bar):has(> .dv-doc:not([hidden]) .doc-sheet[data-orient="portrait"]) > .dv-bar .dv-bar-actions { flex-direction: column; align-items: stretch; }
}
.doc-sheet + .doc-sheet { margin-top: var(--s-6); }
.doc-sheet h2, .doc-sheet h3, .doc-sheet p { margin: 0; }

.doc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-6); padding-bottom: var(--s-4); border-bottom: 1px solid var(--ink-900); }
.doc-brand { display: flex; align-items: center; gap: var(--s-4); min-width: 0; }
.doc-crest { border-color: var(--line-strong); }
.doc-brand-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.doc-school { font-size: 17px; font-weight: 700; letter-spacing: .01em; text-transform: uppercase; color: var(--ink-900); }
.doc-motto { font-size: 12px; font-style: italic; color: var(--ink-600); }
.doc-address { font-size: 11.5px; color: var(--ink-600); }
.doc-sheet .doc-title { margin-top: var(--s-2) !important; font-size: 15px; font-weight: 700; color: var(--ink-900); text-transform: uppercase; letter-spacing: .03em; }
.doc-sheet .doc-subtitle { font-size: 12.5px; color: var(--ink-600); }
.doc-meta { display: grid; grid-template-columns: repeat(2, minmax(0, auto)); gap: var(--s-2) var(--s-6); margin: 0; align-content: start; }
.doc-meta div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.doc-meta dt { font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-400); }
.doc-meta dd { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--ink-900); }

/* centred header band (report cards) */
.doc-head-centered { display: grid; grid-template-columns: 88px minmax(0, 1fr) 88px; align-items: center; gap: var(--s-4); }
.doc-head-mid { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; min-width: 0; }
.doc-head-aside { display: flex; justify-content: flex-end; }
.doc-eyebrow { font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-600); }
.doc-school-lg { font-size: 21px; }
.doc-sheet .doc-titlebar { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; }
.doc-sheet .doc-titlebar .doc-title { margin: 0 !important; }
[data-variant="centered"] > .doc-meta { grid-template-columns: repeat(4, minmax(0, 1fr)); padding: var(--s-2) var(--s-3); border: 1px solid var(--line-strong); border-radius: 4px; }

.doc-body { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.doc-section-title { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-600); margin-bottom: var(--s-2) !important; }
.doc-empty { color: var(--ink-400); font-style: italic; }
.doc-list { margin: 0; padding-left: 16px; }
.doc-list li { margin-bottom: 3px; }
.doc-list li:last-child { margin-bottom: 0; }
.doc-steps { margin: 0; padding-left: 18px; }
.doc-steps li { margin-bottom: 4px; }
.doc-pre { white-space: pre-line; }
.doc-gap { margin-top: 6px !important; }

/* bordered grid tables (schemes, records, timetable, register, report card) */
.doc-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.doc-table th, .doc-table td { border: 1px solid var(--line-strong); padding: 6px 8px; vertical-align: top; text-align: left; }
.doc-table thead th { background: var(--field); font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-600); vertical-align: bottom; }
.doc-table .num { text-align: right; white-space: nowrap; }
.doc-table .ctr { text-align: center; }
.doc-table .nowrap { white-space: nowrap; }
.doc-table tfoot td, .doc-table tfoot th { background: var(--field); font-weight: 700; }
.doc-band td { background: var(--soft); color: var(--on-soft); font-size: 12px; }
.doc-band-strand { margin-right: var(--s-6); }
.doc-table .doc-shade { background: var(--field); }
.doc-sub { display: block; font-size: 11px; color: var(--ink-600); }

/* label and value form (lesson plan) */
.doc-form { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.doc-form th, .doc-form td { border: 1px solid var(--line-strong); padding: 8px 10px; vertical-align: top; text-align: left; }
.doc-form th { width: 26%; background: var(--field); font-weight: 600; color: var(--ink-900); }
.doc-form .doc-minutes { display: block; font-weight: 500; font-size: 11px; color: var(--ink-600); }
.doc-info th { width: auto; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-600); }
.doc-info td { font-weight: 600; }

/* signatures and footers */
.doc-signs { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--s-6); padding-top: var(--s-2); }
.doc-sign { display: flex; flex-direction: column; gap: 6px; }
.doc-sign-label { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-600); }
.doc-sign-name { font-weight: 600; min-height: 18px; }
.doc-sign-role { font-weight: 400; color: var(--ink-600); margin-left: 6px; }
.doc-sign-line { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: end; gap: var(--s-2); font-size: 11px; color: var(--ink-600); }
.doc-sign-line span:last-child { height: 18px; border-bottom: 1px dotted var(--ink-400); }
.doc-foot { display: flex; justify-content: space-between; gap: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line-strong); font-size: 11px; color: var(--ink-400); }
.doc-key { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); font-size: 11px; color: var(--ink-600); }
.doc-key b { color: var(--ink-900); margin-right: 4px; }

/* timetable sheet: days as rows, periods as columns, breaks as shaded bands */
.doc-tt th, .doc-tt td { text-align: center; vertical-align: middle; }
.doc-tt thead th { text-transform: none; letter-spacing: 0; font-size: 11px; }
.doc-tt .doc-tt-p { display: block; font-size: 11.5px; color: var(--ink-900); }
.doc-tt tbody th { width: 92px; text-align: left; background: var(--field); font-size: 12px; }
.doc-tt td { height: 58px; font-size: 11.5px; }
.doc-tt .doc-tt-area { display: block; font-weight: 700; color: var(--ink-900); }
.doc-tt .doc-tt-break { width: 40px; padding: 4px 2px; background: var(--field); color: var(--ink-600); font-weight: 700; font-size: 10.5px; }
.doc-tt thead .doc-tt-day { text-align: left; }
.doc-tt-vert { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; }

/* class register sheet */
.doc-reg td.ctr, .doc-reg th.ctr { text-align: center; width: 52px; }
.doc-reg .doc-reg-a { color: var(--crimson-700); font-weight: 700; }
.doc-reg .doc-reg-l { color: var(--amber-700); font-weight: 700; }

/* report card */
.doc-photo { width: 80px; height: 88px; border: 1px solid var(--line-strong); border-radius: 4px; padding: 3px; background: var(--surface); }
.doc-photo span { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; border-radius: 2px; background: var(--soft); color: var(--on-soft); font-size: 24px; font-weight: 700; }
.doc-learner { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.doc-learner-name { font-size: 18px; font-weight: 700; color: var(--ink-900); }
.doc-learner-name .doc-adm { font-weight: 600; color: var(--ink-600); margin-right: var(--s-2); }
.doc-rc tbody tr:nth-child(even) td, .doc-rc tbody tr:nth-child(even) th { background: var(--canvas); }
.doc-rc .doc-code { color: var(--ink-600); font-weight: 600; }
.doc-rc .lvl, .doc-hist .lvl { min-width: 28px; height: 18px; font-size: 10px; padding: 0 5px; }
.doc-lvl { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.doc-lvl-text { font-size: 11px; color: var(--ink-600); }
.doc-comments { display: grid; grid-template-columns: minmax(0, 1fr) 150px; gap: var(--s-4); }
.doc-remark { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 4px; }
.doc-remark + .doc-remark { margin-top: var(--s-2); }
.doc-stamp { display: flex; align-items: center; justify-content: center; border: 1px dashed var(--ink-400); border-radius: 4px; color: var(--ink-400); font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; min-height: 120px; }
.doc-chart { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-2); }
.doc-chart svg { width: 100%; height: auto; display: block; }
.doc-chart .doc-bar { fill: var(--me); }
.doc-chart .doc-avg { stroke: var(--crimson-700); fill: none; stroke-width: 2; }
.doc-chart .doc-avg-dot { fill: var(--crimson-700); }
.doc-chart .doc-axis { stroke: var(--line-strong); stroke-width: 1; }
.doc-chart .doc-grid { stroke: var(--line); stroke-width: 1; }
.doc-chart text { fill: var(--ink-600); font-size: 10px; font-family: var(--font); }
.doc-chart .doc-val { fill: var(--ink-900); font-weight: 700; }
.doc-legend { display: flex; justify-content: center; gap: var(--s-4); font-size: 11px; color: var(--ink-600); }
.doc-legend span { display: inline-flex; align-items: center; gap: 6px; }
.doc-legend i { display: inline-block; width: 12px; height: 10px; border-radius: 2px; background: var(--me); }
.doc-legend i.doc-legend-line { height: 2px; background: var(--crimson-700); }
.doc-two { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--s-4); }
.doc-tight th, .doc-tight td { padding: 4px 8px; }

.doc-meta-row { grid-template-columns: repeat(4, minmax(0, 1fr)); padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: 4px; }
.doc-stack { display: flex; flex-direction: column; gap: var(--s-3); min-width: 0; }
.doc-chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 12px; margin: 0; padding: 0; list-style: none; font-size: 11.5px; }
.doc-chips li { display: flex; align-items: center; gap: 6px; min-width: 0; }
.doc-chips .lvl { min-width: 28px; height: 18px; font-size: 10.5px; }
.doc-values { font-size: 11.5px; color: var(--ink-900); }
.doc-values .doc-section-title { display: inline; margin-right: 4px; }
.doc-comment-sign { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, .8fr); gap: var(--s-4); align-items: end; margin-top: 4px; }
.doc-comment-sign .doc-sign-line { grid-template-columns: auto minmax(0, 1fr); }
.doc-parent { grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr) minmax(0, .8fr); padding-top: 2px; }
.doc-report .doc-comments { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 116px; gap: 8px; }
.doc-report .doc-remark + .doc-remark { margin-top: 0; }
.doc-report .doc-remark .doc-comment-sign { grid-template-columns: auto minmax(0, 1fr) minmax(0, .8fr); gap: 8px; }
.doc-chips-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.doc-report .doc-body { gap: 10px; }
.doc-report .doc-rc tbody th, .doc-report .doc-rc tbody td { padding-top: 3px; padding-bottom: 3px; }
.doc-report .doc-remark > p:nth-child(2) { min-height: 24px; }
.doc-report { gap: 8px; }
.doc-report .doc-body { gap: 8px; }
.doc-report .doc-rc thead th { font-size: 9.5px; white-space: nowrap; }
.doc-report .doc-lvl { white-space: normal; align-items: flex-start; }
.doc-report .doc-lvl .lvl { flex-shrink: 0; }
.doc-report .doc-lvl-text { font-size: 10px; line-height: 1.3; }
.doc-report .doc-lvl { align-items: center; gap: 4px; }
.doc-report .doc-lvl-text { white-space: nowrap; }
.doc-report .doc-rc .lvl { min-width: 24px; padding: 0 4px; }
.doc-report .doc-stack .doc-table { table-layout: fixed; }
.doc-report .doc-stack .doc-table th, .doc-report .doc-stack .doc-table td { font-size: 10px; padding: 4px 6px; }
.doc-report .doc-stack .doc-table thead th { font-size: 9px; letter-spacing: .02em; }
.doc-report .doc-chart { align-content: start; }
.doc-report .doc-learner-name { font-size: 17px; }
.doc-meta-inline { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding: 6px 10px; }
.doc-meta-inline div { flex-direction: row; align-items: baseline; gap: 6px; }
.doc-meta-inline dd { white-space: nowrap; }
.doc-report .doc-two { gap: 12px; }
.doc-report .doc-chips { font-size: 10.5px; gap: 3px 10px; }
.doc-report .doc-chips li > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-report .doc-chips .lvl, .doc-report .doc-chips .doc-empty { flex: 0 0 30px; }
.doc-report .doc-remark { padding: 6px 10px; gap: 2px; }
.doc-report .doc-key { font-size: 10px; gap: 2px 10px; }
.doc-report .doc-section-title { margin-bottom: 4px !important; }
.doc-report .doc-rc { font-size: 10.5px; line-height: 1.35; table-layout: fixed; }
.doc-report .doc-rc td, .doc-report .doc-rc th { overflow-wrap: anywhere; }
.doc-report .doc-rc th, .doc-report .doc-rc td { padding: 4px 7px; }
.doc-report .doc-crest.crest-72 { width: 56px; height: 56px; font-size: 20px; }
.doc-report .doc-photo { width: 56px; height: 64px; }
.doc-report .doc-photo span { font-size: 20px; }
.doc-report .doc-head-centered { grid-template-columns: 64px minmax(0, 1fr) 64px; padding-bottom: 8px; }
.doc-report .doc-foot { padding-top: 8px; }
.doc-report .doc-remark p { font-size: 11.5px; }
.doc-report .doc-stamp { min-height: 0; }
.doc-report .doc-foot span:nth-child(2) { margin-left: auto; margin-right: var(--s-4); }

/* report card rhythm: 16px between sections, 12px inside a section, one set of edges */
.doc-report .doc-body { gap: 14px; }
.doc-sec { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.doc-row-muted th, .doc-row-muted td { color: var(--ink-600); }
.doc-report .doc-rc td, .doc-report .doc-rc th { vertical-align: top; }
.doc-report .doc-rc thead th { letter-spacing: .02em; }
.doc-hist { table-layout: fixed; }
.doc-report .doc-hist thead th { white-space: normal; text-transform: none; letter-spacing: 0; font-size: 10px; line-height: 1.2; }
.doc-hist td, .doc-hist th { overflow-wrap: anywhere; }
.doc-hist .doc-empty { font-size: 10px; }
.doc-minis { display: flex; flex-direction: column; gap: 8px; }
.doc-mini { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; }
.doc-minibar { position: relative; height: 10px; border-radius: 2px; background: var(--field); border: 1px solid var(--line-strong); }
.doc-minibar-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 1px; background: var(--me); }
.doc-minibar-avg { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; background: var(--crimson-700); }
.doc-minis .doc-legend { justify-content: flex-start; }

/* app view building blocks (a readable, non-paper view of the same document) */
.dv-app { display: flex; flex-direction: column; gap: var(--gap-section, var(--s-6)); min-width: 0; }
.dv-group-band { display: flex; flex-wrap: wrap; gap: 4px var(--s-4); font-size: 13px; color: var(--ink-600); }
.dv-group-band strong { color: var(--ink-900); }
.dv-items { display: flex; flex-direction: column; }
.dv-item { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-4) 0; border-top: 1px solid var(--line); }
.dv-item:first-child { border-top: 0; padding-top: 0; }
.dv-item-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.dv-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-3) var(--s-6); }
.dv-field { display: flex; flex-direction: column; gap: 4px; font-size: 14px; min-width: 0; }
.dv-field ul { margin: 0; padding-left: 18px; }

/* timetable: day agenda with a now marker (pages/teaching/timetable-views.js) and doc tints */
.tt-agenda { max-width: 760px; }
.tt-now { display: flex; align-items: center; gap: var(--s-2); color: var(--crimson-700); font-size: 12px; font-weight: 700; }
.tt-now::after { content: ""; flex: 1 1 auto; height: 2px; border-radius: 2px; background: var(--crimson-700); }
.tt-now-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--crimson-700); box-shadow: 0 0 0 3px var(--crimson-50); }
.tt-day-break.is-now, .tt-day-free.is-now { color: var(--crimson-700); }
.doc-kicker { font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-600); }
.doc-tint-navy { background: var(--navy-50); } .doc-tint-green { background: var(--green-50); } .doc-tint-mustard, .doc-tint-amber { background: var(--amber-50); } .doc-tint-crimson { background: var(--crimson-50); }
.doc-tt-legend { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); font-size: 11px; color: var(--ink-600); }
.doc-tt-legend span { display: inline-flex; align-items: center; gap: 6px; }
.doc-tt-legend i { width: 14px; height: 10px; border: 1px solid var(--line-strong); border-radius: 2px; }
.doc-tt-ini { font-weight: 600; color: var(--ink-600); }

/* timetable clashes (pages/teaching/timetable-clashes.js): chip, filter, drawer; tints and 1px borders only */
.tt-head-tools { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.tt-clash-chip { display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px; border-radius: var(--r-full); font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap; }
.tt-clash-chip.is-bad { background: var(--crimson-50); color: var(--crimson-700); border: 1px solid color-mix(in srgb, var(--crimson-600) 40%, transparent); cursor: pointer; }
.tt-clash-chip.is-bad:hover { border-color: var(--crimson-600); }
.tt-clash-chip.is-bad:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.tt-clash-chip.is-ok { background: var(--green-50); color: var(--green-700); border: 1px solid color-mix(in srgb, var(--green-600) 35%, transparent); }
.tt-clash-only-toggle { font-size: 13px; font-weight: 500; color: var(--ink-600); }
.tt-card.is-clash-only .tt-cell:not(.has-conflict), .tt-card.is-clash-only .tt-day-card:not(.has-conflict) { opacity: .3; }
.tt-clash-body { display: flex; flex-direction: column; gap: var(--s-4); overflow-y: auto; }
.tt-clash-card { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-4); border: 1px solid color-mix(in srgb, var(--crimson-600) 30%, var(--line)); border-radius: var(--r-card); background: var(--surface); }
.tt-clash-head { display: flex; align-items: flex-start; gap: var(--s-3); }
.tt-clash-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.tt-mini { display: flex; flex-direction: column; gap: 3px; padding: 10px 12px; border-radius: 8px; border: 1px solid color-mix(in srgb, var(--la-accent) 22%, transparent); min-width: 0; }
.tt-mini-meta { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-600); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-mini .btn { align-self: flex-start; margin-top: 4px; }
.tt-fixes { display: flex; flex-direction: column; gap: var(--s-2); }
.tt-fix { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; min-height: 44px; padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: var(--r-btn); background: var(--surface); color: var(--ink-900); font: inherit; text-align: left; cursor: pointer; }
.tt-fix:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.tt-fix:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.tt-fix-label { font-weight: 600; font-size: 14px; }
.tt-cell.tt-flash, .tt-day-card.tt-flash { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: var(--shadow); }
@media (max-width: 767px) {
  .tt-clash-back { align-items: flex-end; }
  .tt-clash-panel { top: auto; left: 0; width: 100%; max-height: 85vh; border-radius: var(--r-modal) var(--r-modal) 0 0; }
  .tt-clash-chip { height: 44px; }
  .tt-clash-only-toggle { min-height: 44px; }
  .tt-head-tools { width: 100%; }
  .tt-clash-pair { grid-template-columns: minmax(0, 1fr); }
  .tt-mini .btn { min-height: 44px; }
}

/* print: only the document, on clean A4 pages in the right orientation */
/* page size and margins: DocSheet.js keeps an @page rule for the sheet's orientation last in the document */
@media print {
  body:has(.dv-doc) * { visibility: visible; }
  body:has(.dv-doc) { background: var(--white) !important; }
  body:has(.dv-doc) :is(.shell, .shell-main, .shell-scroll, .page, .page-main, .page-body) {
    display: block !important; overflow: visible !important; height: auto !important; min-height: 0 !important; max-width: none !important;
    padding: 0 !important; margin: 0 !important; background: none !important; box-shadow: none !important; border: 0 !important;
  }
  body:has(.dv-doc) :is(.sidebar, .topbar, .footer, .page-head, .banner, .skip-link, .drawer-scrim, .toasts, .modal-backdrop, .sticky-bar) { display: none !important; }
  body:has(.dv-doc) .page-body > :not(.dv-doc), .dv-bar, .dv-hint, [data-dv="app"] { display: none !important; }
  .dv-doc, .dv-doc[hidden] { display: block !important; }
  .dv-frame { overflow: visible !important; padding: 0 !important; }
  .doc-sheet { width: auto !important; min-width: 0 !important; max-width: none !important; margin: 0 !important; padding: 0 !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; gap: 12px; }
  .dv-doc-tools { display: none !important; }
  .doc-sheet + .doc-sheet { break-before: page; margin-top: 0 !important; }
  .doc-sheet, .doc-sheet * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .doc-table thead { display: table-header-group; }
  .doc-table tr, .doc-form tr, .doc-sign, .doc-signs, .doc-comments, .doc-chart, .doc-keep { break-inside: avoid; }
  .doc-head, .doc-titlebar, .doc-section-title { break-after: avoid; }
  .doc-band { break-after: avoid; page-break-after: avoid; }
}

/* evidence preview (components/EvidencePreview.js) */
.ev-preview-img { display: block; width: 100%; max-height: 60vh; object-fit: contain; border: 1px solid var(--line); border-radius: var(--r-btn); background: var(--canvas); }
.ev-preview-ph { min-height: 220px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2); text-align: center; padding: var(--s-4); }

/* progress over time (components/TermTrend.js) */
.trend-bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.trend-bars li { display: grid; grid-template-columns: minmax(140px, 180px) minmax(0, 1fr) auto; align-items: center; gap: var(--s-3); }
.trend-bar-label { display: flex; flex-direction: column; font-weight: 600; font-size: 14px; }
.trend-bar-track { height: 12px; border-radius: 999px; background: var(--canvas); border: 1px solid var(--line); overflow: hidden; }
.trend-bar-fill { display: block; height: 100%; border-radius: inherit; }
.trend-bar-fill.is-mean { background: var(--primary); }
.trend-bar-val { display: inline-flex; align-items: center; gap: var(--s-2); }
.trend-up, .trend-down { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: 13px; }
.trend-up { color: var(--green-700); }
.trend-down { color: var(--crimson-700); }
@media (max-width: 767px) {
  .trend-bars li { grid-template-columns: 1fr auto; }
  .trend-bar-track { grid-column: 1 / -1; grid-row: 2; }
}

/* ---------- avatars with pictures (components/Avatar.js, AvatarPicker.js, AvatarCrop.js) ---------- */
.avatar-56 { width: 56px; height: 56px; font-size: 19px; } .avatar-72 { width: 72px; height: 72px; font-size: 22px; }
.avatar-128 { width: 128px; height: 128px; font-size: 36px; }
.av { border: 1px solid var(--line-strong); }
.av-pic { background: var(--field); }
.av > img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.avatar-btn { position: relative; display: inline-flex; flex-direction: column; align-items: center; gap: var(--s-2); padding: 0; border: 0; background: none; color: var(--link); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; border-radius: var(--r-btn); min-width: 44px; min-height: 44px; }
.avatar-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
.avatar-btn .avatar-btn-badge { position: absolute; top: 0; right: 0; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--primary); color: var(--on-primary); border: 2px solid var(--surface); }
.avatar-btn:hover .av { border-color: var(--border-input-hover); }
.field.avatar-field { flex-direction: row; align-items: center; gap: var(--s-4); }
/* Photo beside the name fields: <div class="photo-row">PhotoField({ compact: true }) <div>fields</div></div> */
.photo-row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s-4) var(--s-6); align-items: start; }
.photo-row > .stack { gap: var(--s-4); min-width: 0; }
.field.avatar-field-compact { flex-direction: column; align-items: center; gap: var(--s-1); width: 112px; text-align: center; padding-top: 22px; }
.avatar-field-compact .help { max-width: none; }
@media (max-width: 767px) {
  .photo-row { grid-template-columns: 1fr; }
  .field.avatar-field-compact { flex-direction: row; width: auto; text-align: left; padding-top: 0; gap: var(--s-3); }
}
.avatar-field .help { display: block; max-width: 36ch; }
.doc-photo > img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 2px; }
.idcard-photo-real { padding: 0; border-style: solid; overflow: hidden; }
.idcard-photo-real > img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* My account photo row (pages/auth/account-photo-parts.js) */
.acc-row-main.acc-photo-row { flex-direction: row; align-items: center; gap: var(--s-3); }

.avp { display: grid; grid-template-columns: 176px minmax(0, 1fr); gap: var(--s-6); align-items: start; }
.avp-side { display: flex; flex-direction: column; align-items: center; gap: var(--s-3); text-align: center; position: sticky; top: 0; }
.avp-status { max-width: 22ch; }
.avp-main { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }
.avp-tabs .tab { gap: var(--s-2); }
.avp-panel { display: flex; flex-direction: column; gap: var(--s-4); min-height: 260px; }
.avp-error { margin: 0; }
.avp-filters { flex-wrap: wrap; align-self: flex-start; }
.avp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: var(--s-3); max-height: 320px; overflow-y: auto; padding: 4px; }
.avp-tile { position: relative; display: block; width: 100%; min-height: 44px; padding: 0; border: 0; background: none; cursor: pointer; border-radius: 50%; }
.avp-tile:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.avp-art { display: block; aspect-ratio: 1; border-radius: 50%; overflow: hidden; border: 2px solid var(--line); background: var(--field); transition: border-color .15s; }
.avp-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.avp-tile:hover .avp-art { border-color: var(--border-input-hover); }
.avp-tile[aria-selected="true"] .avp-art { border-color: var(--primary); }
.avp-check { position: absolute; right: -2px; bottom: -2px; width: 24px; height: 24px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--primary); color: var(--on-primary); border: 2px solid var(--surface); }
.avp-stage { position: relative; width: min(280px, 100%); aspect-ratio: 1; overflow: hidden; border-radius: var(--r-card); background: var(--field); border: 1px solid var(--line-strong); cursor: grab; touch-action: none; align-self: center; }
.avp-stage.is-dragging { cursor: grabbing; }
.avp-stage:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.avp-stage-img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; user-select: none; pointer-events: none; }
.avp-ring { position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 0 999px var(--scrim); pointer-events: none; }
.avp-crop { display: flex; flex-direction: column; gap: var(--s-4); }
.avp-crop-tools { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.avp-zoom { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: 600; font-size: 13px; color: var(--ink-600); min-height: 44px; }
.avp-zoom input { width: 160px; accent-color: var(--primary); }
.avp-foot-extra .btn[hidden] { display: none; }
.avp-foot-extra { display: flex; gap: var(--s-2); margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 767px) {
  .avp { grid-template-columns: 1fr; gap: var(--s-4); }
  .avp-side { position: static; flex-direction: row; text-align: left; }
  .avp-side .avatar-128 { width: 72px; height: 72px; font-size: 22px; }
  .avp-status { max-width: none; }
  .avp-grid { grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); max-height: 260px; }
  .modal.avp-modal .modal-foot { flex-wrap: wrap; }
  .avp-foot-extra { order: 3; width: 100%; margin-left: 0; justify-content: space-between; }
  .avp-foot-extra .btn { min-height: 44px; }
}

/* =====================================================================
   Design rules (review/CONVENTIONS.md "Design rules"): one section rhythm.
   Page-level blocks (cards, tiles, tabs, banners, grids, and the plain host
   wrappers pages and lenses render into) sit one section gap apart:
   --s-6 (24px), --s-4 (16px) below 768px, stacked or side by side.
   ===================================================================== */
.page-body { --gap-section: var(--s-6); }
@media (max-width: 767px) { .page-body { --gap-section: var(--s-4); } }
/* the page body's gap is the only space between its blocks: no margins on top, no slots for empty hosts */
.page-body > :not(.sticky-bar) { margin-top: 0; margin-bottom: 0; }
.page-body > :is(div, section):not([class]):empty { display: none; }
/* plain host wrappers (lens bodies, #...-host divs) stack their blocks like the page body */
.page-body :is(div, section, form):not([class]):not(:is(.card, .tile, .modal, .form-section, table) *):has(> :is(.card, .tiles, .form-section, .banner, .dt-tabs, .tabs, .toolbar, .dv-bar, .dv-app, .grid-2, .grid-3, .grid-4, .grid-main)):has(> * + *) { display: flex; flex-direction: column; gap: var(--gap-section) !important; }
.page-body :is(div, section, form):not([class]):not(:is(.card, .tile, .modal, .form-section, table) *):has(> :is(.card, .tiles, .form-section, .banner, .dt-tabs, .tabs, .toolbar, .dv-bar, .dv-app, .grid-2, .grid-3, .grid-4, .grid-main)) > * { margin-top: 0; margin-bottom: 0; }
.page-body :is(div, section, form):not([class]):not(:is(.card, .tile, .modal, .form-section, table) *) > :is(div, section):not([class]):empty { display: none; }
/* any container of adjacent page blocks (card grids, card lists) and any layout whose columns hold cards
   uses the section gap; it wins over inline layout gaps so the rhythm holds on every page and width */
.page-body :not(:is(.card, .tile, .modal, .form-section, .pop, table) *):is(:has(> :is(.card, .form-section, .tiles, .dt-tabs, .tabs, .dv-bar, .dv-app, .grid-2, .grid-3, .grid-4, .grid-main) + :is(.card, .form-section, .tiles, .dt-tabs, .tabs, .dv-bar, .dv-app, .grid-2, .grid-3, .grid-4, .grid-main)), :has(> :not(.card, .tile, .form-section, .modal, .pop, .tiles, [class*="toolbar"], [class*="-bar"], [class*="actions"], .row, .row-between) > :is(.card, .form-section))) { gap: var(--gap-section) !important; }
/* icon sizes per context: icon chips (tiles, notes, list chips) 24px, 28px in hero chips of 56px and
   up (empty states), 20px in small chips under 40px; button icons 18px (16px in small buttons) */
.tile-ic { container-type: size; }
.tile-ic > .ic { width: 24px; height: 24px; }
@container (max-width: 39px) { .tile-ic > .ic { width: 20px; height: 20px; } }
@container (min-width: 56px) { .tile-ic > .ic { width: 28px; height: 28px; } }
