* { box-sizing: border-box; }
body { font-family: "Segoe UI", Arial, sans-serif; margin: 0; color: #1f2937; background: #eef1f5; }
/* ===== App shell: navy sidebar + white top bar (desktop); app-bar + bottom tabs (mobile) ===== */
.app { display: flex; min-height: 100vh; align-items: stretch; }
.sidebar { width: 212px; flex-shrink: 0; background: #1b2a4a; color: #cdddef; position: sticky; top: 0; align-self: flex-start; height: 100vh; overflow-y: auto; }
.side-brand { display: flex; align-items: center; gap: 10px; padding: 14px 16px; color: #fff; font-weight: 700; font-size: 17px; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.10); }
.brand-logo { height: 34px; width: 34px; border-radius: 7px; background: #fff; padding: 2px; flex-shrink: 0; }
.side-nav { padding: 8px 0; display: flex; flex-direction: column; }
.side-nav a, .side-nav button { display: flex; align-items: center; gap: 12px; padding: 11px 16px; color: #cdddef; text-decoration: none; font-size: 14.5px; font-weight: 400; background: none; border: 0; width: 100%; text-align: left; cursor: pointer; font-family: inherit; border-radius: 0; }
.side-nav a:hover, .side-nav button:hover { background: rgba(255,255,255,.08); color: #fff; }
.side-nav a.active { background: #2f6db0; color: #fff; font-weight: 600; }
.side-nav svg { width: 18px; height: 18px; flex-shrink: 0; }
.side-nav form { margin: 0; }
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar { background: #fff; border-bottom: 1px solid #e5e7eb; padding: 11px 20px; display: flex; align-items: center; gap: 12px; position: sticky; top: 0; z-index: 20; }
.topbar-title { font-weight: 600; color: #1b2a4a; font-size: 16px; }
.topbar-sub { color: #5f6b7a; font-weight: 400; font-size: 14px; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 10px; font-size: 13px; }
.topbar-right .who { background: #eef2f8; color: #1b2a4a; padding: 5px 11px; border-radius: 20px; font-weight: 600; }
/* Repeatable staff-posting rows (create-login form) */
.posting-row { display: flex; gap: 8px; margin-bottom: 8px; align-items: center; flex-wrap: wrap; }
.posting-row select { flex: 1 1 150px; min-width: 0; }
.posting-row .rm-posting { flex: 0 0 auto; padding: 6px 12px; line-height: 1; }
.topbar-cta { display: inline-flex; align-items: center; gap: 6px; background: #2f6db0; color: #fff; border: 0; border-radius: 8px; padding: 7px 13px; font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.topbar-cta svg { width: 16px; height: 16px; }
.topbar-cta:hover { background: #255a94; color: #fff; }
@media print { .topbar-cta { display: none !important; } }
/* On phones the New Inquiry action takes priority in the bar: drop the name badge
   and let the title truncate so nothing overflows. */
@media (max-width: 640px) {
  .topbar-right .who { display: none; }
  .topbar-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* THE WHOLE APP SCROLLED SIDEWAYS ON A PHONE because of this bar (found
     2026-09-20 while measuring the teacher screen at 375px). The search box and
     the New Inquiry button add up to 260px of content that cannot shrink — the
     button's label is nowrap — and a flex item defaults to min-width:auto, so it
     refuses to go below its content and pushes the page out. Every screen was
     411px wide on a 375px phone, and the fixed bottom nav stretched with it.

     The owner asked for exactly the opposite: "automatically reformatted into a
     clean, well-arranged, scroll-free (vertically scrollable, not horizontally)
     layout on mobile devices."

     So the bar may shrink, the search box gives up its fixed width, and the
     button keeps its icon and drops its words. Nothing is removed — search and
     New Inquiry are both still there, and the words come back past 640px. */
  .topbar-right { min-width: 0; }
  .quick-search { min-width: 0; flex: 1 1 auto; }
  .quick-search input { min-width: 0; }
  .topbar-cta { padding: 7px 10px; flex: 0 0 auto; }
  .topbar-cta span { display: none; }
}
.nav-toggle { display: none; background: none; border: 0; color: #1b2a4a; font-size: 24px; line-height: 1; cursor: pointer; padding: 0 4px; }
.back-btn { display: inline-flex; align-items: center; gap: 4px; background: #fff; border: 1px solid #cbd5e1; color: #1b2a4a; border-radius: 8px; padding: 6px 11px; font-size: 13px; font-weight: 600; font-family: inherit; cursor: pointer; }
.back-btn svg { width: 16px; height: 16px; }
.back-btn:hover { background: #f4f7fb; border-color: #2f6db0; }
@media print { .back-btn, .nav-toggle { display: none !important; } }
/* Reusable actions dropdown (native <details>) */
.dropdown { position: relative; display: inline-block; }
.dropdown > summary { list-style: none; cursor: pointer; }
.dropdown > summary::-webkit-details-marker { display: none; }
.dropdown .menu { position: absolute; right: 0; top: calc(100% + 4px); background: #fff; border: 1px solid #d8e0ec; border-radius: 10px; box-shadow: 0 6px 18px rgba(20,30,60,.12); min-width: 210px; padding: 6px; z-index: 30; display: flex; flex-direction: column; gap: 2px; }
.dropdown .menu a, .dropdown .menu button { display: block; width: 100%; text-align: left; background: none; border: 0; color: #1b2a4a; padding: 8px 10px; border-radius: 7px; font-size: 14px; text-decoration: none; cursor: pointer; font-family: inherit; }
.dropdown .menu a:hover, .dropdown .menu button:hover { background: #eef2f8; }
.dropdown .menu form { margin: 0; }
.dropdown .menu .menu-danger { color: #b91c1c; }
/* Generic in-app print: hide chrome, show only the content */
@media print {
  .sidebar, .topbar, .noprint { display: none !important; }
  .app, .main, .container { display: block !important; margin: 0 !important; padding: 0 !important; }
  body { background: #fff !important; }
}
.bottomnav, .scrim { display: none; }
/* The white content area on EVERY page (owner, 2026-09-19): "across the entire
   software … made wider, reducing the grey empty space on the left/right sides
   … minimize/eliminate the need for horizontal scrolling".

   Item 15 built this as an opt-in and exactly one route opted in, so every other
   screen stayed a 1080px column with its tables scrolling sideways inside it.
   Widening `.container` itself means a screen gets it by existing.

   THE CAP IS A PLAIN PIXEL NUMBER ON PURPOSE. Written as calc(100vw - 36px) it
   would fight the 18px padding below and cost a 375px phone another 36px. At
   1800px it simply never binds on a phone: the container is width:100%, keeps
   its side padding, and the page reflows down the screen instead of sideways. */
.container { max-width: 1800px; margin: 22px auto; padding: 0 18px; width: 100%; }
/* Kept so the `wide` flag item 15 added still resolves to something. It is the
   same width now; the flag is harmless rather than necessary. */
.container.container-wide { max-width: 1800px; }
/* KPI metric tiles */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(155px, 1fr)); gap: 12px; margin-bottom: 18px; }
.kpi { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 14px 16px; display: flex; align-items: center; gap: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.05); }
.kpi-ic { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.kpi-ic svg { width: 20px; height: 20px; }
.kpi .lbl { font-size: 12.5px; color: #5f6b7a; }
.kpi .num { font-size: 22px; font-weight: 700; color: #1b2a4a; line-height: 1.15; }
.kpi.b-blue .kpi-ic { background: #E6F1FB; color: #185FA5; }
.kpi.b-teal .kpi-ic { background: #E1F5EE; color: #0F6E56; }
.kpi.b-amber .kpi-ic { background: #FAEEDA; color: #854F0B; }
.kpi.b-coral .kpi-ic { background: #FAECE7; color: #993C1D; }
.kpi.b-purple .kpi-ic { background: #EEEDFE; color: #534AB7; }
.kpi.b-red .kpi-ic { background: #FCEBEB; color: #A32D2D; }
/* Charts */
.chart-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; margin-bottom: 18px; }
.chart-card { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,.05); }
.chart-card h3 { margin: 0 0 12px; font-size: 14px; color: #1b2a4a; font-weight: 600; }
.chart-flex { display: flex; align-items: center; gap: 16px; }
.chart-flex svg { flex-shrink: 0; }
.legend { list-style: none; padding: 0; margin: 0; font-size: 13px; flex: 1; min-width: 0; }
.legend li { display: flex; align-items: center; gap: 8px; margin: 6px 0; color: #374151; }
.legend .dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.legend strong { margin-left: auto; color: #1b2a4a; }
.hbars { display: flex; flex-direction: column; gap: 10px; max-height: 220px; overflow-y: auto; }
.hbar .hbar-top { display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 12.5px; color: #374151; }
.hbar .track { height: 8px; background: #eef1f5; border-radius: 4px; overflow: hidden; }
.hbar .fill { height: 100%; background: #2f6db0; border-radius: 4px; }
/* Class chips (selectors) */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border: 1px solid #d8e0ec; border-radius: 22px; background: #fff; color: #1b2a4a; text-decoration: none; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit; line-height: 1.2; }
.chip:hover { border-color: #2f6db0; }
.chip.active { background: #1b2a4a; color: #fff; border-color: #1b2a4a; }
.chip .badge { background: #eef2f8; color: #1b2a4a; border-radius: 12px; padding: 1px 8px; font-size: 12px; font-weight: 700; }
.chip.active .badge { background: rgba(255,255,255,.22); color: #fff; }

/* The stepped filter's colours (2026-09-14, the owner's Part 4). One colour per
   level, so that after a week the office reads the row by its colour before it
   reads the words: Class blue, Board teal, Section purple, Group amber, Gender
   pink. Outlined when not chosen, filled when chosen.

   Defined HERE and only here. Any screen that adopts the stepped filter gets the
   same colours by using the same class names — which is the whole point of them
   being classes rather than styles written on the page. */
.step-level { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; }
.step-level > .step-label { font-size: 13px; color: #5f6b7a; font-weight: 600; min-width: 62px; }
.step-crumbs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 10px; font-size: 13px; color: #5f6b7a; }
.step-crumbs .sep { color: #aab4c2; }

.chip.lvl-class   { border-color: #c3d6f2; color: #14427e; background: #f3f7fd; }
.chip.lvl-class.active   { background: #1b4f9c; border-color: #1b4f9c; color: #fff; }
.chip.lvl-board   { border-color: #b9e0d8; color: #0f5b4f; background: #f2fbf9; }
.chip.lvl-board.active   { background: #12705f; border-color: #12705f; color: #fff; }
.chip.lvl-section { border-color: #d6c9ee; color: #4a2f80; background: #f8f5fd; }
.chip.lvl-section.active { background: #5b3aa6; border-color: #5b3aa6; color: #fff; }
.chip.lvl-group   { border-color: #f0d9a8; color: #7a5210; background: #fdf8ee; }
.chip.lvl-group.active   { background: #a8720f; border-color: #a8720f; color: #fff; }
.chip.lvl-gender  { border-color: #f2c9da; color: #7d2b4d; background: #fdf4f8; }
.chip.lvl-gender.active  { background: #a63a63; border-color: #a63a63; color: #fff; }
/* The two levels that belong to Exams and Results alone. Deliberately the app's
   own navy rather than a sixth colour: five is already as many as a person can
   hold, and these two are never in the same row as each other. */
.chip.lvl-test    { border-color: #cfd8e6; color: #1b2a4a; background: #f7f9fc; }
.chip.lvl-test.active    { background: #1b2a4a; border-color: #1b2a4a; color: #fff; }
.chip.lvl-subject { border-color: #cfd8e6; color: #1b2a4a; background: #f7f9fc; }
.chip.lvl-subject.active { background: #1b2a4a; border-color: #1b2a4a; color: #fff; }

/* On a phone only the row still being asked is worth the width; the ones already
   answered collapse to the breadcrumb above it. */
@media (max-width: 640px) {
  .step-level > .step-label { min-width: 0; }
}

.att-tally { display: flex; gap: 14px; align-items: center; margin: 4px 0 12px; font-size: 14px; }
.att-tally b { font-size: 18px; }
/* Parent/student portal tabs */
.portal-tabs { display: flex; gap: 4px; flex-wrap: wrap; background: #fff; border-bottom: 1px solid #e5e7eb; padding: 8px 16px; overflow-x: auto; }
.portal-tabs a { padding: 8px 14px; border-radius: 8px; color: #1b2a4a; text-decoration: none; font-size: 14px; white-space: nowrap; font-weight: 500; }
.portal-tabs a.active { background: #1b2a4a; color: #fff; }
.portal-tabs a:hover { background: #eef2f8; }
.portal-tabs a.active:hover { background: #24386a; }
.hero { text-align: center; margin: 24px 0; }
.hero-logo { width: 120px; height: 120px; }
.hero h2 { color: #1b2a4a; margin: 8px 0 0; }
h1 { font-size: 23px; color: #1b2a4a; }
.group-title { color: #2f6db0; border-bottom: 2px solid #e2e8f0; padding-bottom: 4px; margin: 22px 0 6px; }
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 10px; padding: 20px; margin-bottom: 18px; box-shadow: 0 1px 3px rgba(0,0,0,.05); }
label { display: block; margin: 12px 0 4px; font-weight: 600; }
label.inline { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; margin: 0; }
input, select, textarea { width: 100%; padding: 11px; font-size: 16px; border: 1px solid #cbd5e1; border-radius: 8px; font-family: inherit; }
/* A tick-box is not a text box. `input { width: 100% }` above is right for the
   things you type in and ruinous for the ones you tick: a checkbox stretched to
   fill its row shoves its own label to the far side, which is exactly what the
   owner saw on the teacher assignment screen (2026-09-20, "its like messy").
   Checkbox was missing from this list, so EVERY tick-box in the app had it. */
input[type="radio"], input[type="checkbox"], input[type="file"] { width: auto; }

/* A block of tick-boxes — sections, subjects — as an even grid of cards rather
   than a flex row that wraps into ragged columns. Each label holds its own box,
   so the tick and its words can never be pulled apart, and a long name wraps
   inside its own card instead of pushing the next one out of line. */
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.pick-grid label {
  display: flex; align-items: flex-start; gap: 9px; margin: 0;
  padding: 10px 12px; border: 1px solid #dbe2ea; border-radius: 9px;
  background: #fff; font-weight: 500; font-size: 14.5px; line-height: 1.35; cursor: pointer;
}
.pick-grid label:hover { border-color: #9db4d0; background: #f7fafd; }
.pick-grid input { margin-top: 2px; flex: 0 0 auto; }
/* A ticked one is obvious at a glance, so the office can see what it is about
   to assign without reading every box. */
.pick-grid label:has(input:checked) { border-color: #1b2a4a; background: #eef3fa; }
.pick-grid .empty-note { grid-column: 1 / -1; color: #5f6b7a; font-size: 14px; }
button, .btn { display: inline-block; padding: 11px 18px; font-size: 16px; border: 0; border-radius: 8px; background: #1b2a4a; color: #fff; cursor: pointer; text-decoration: none; }
button:hover, .btn:hover { background: #24386a; }
button.secondary, .btn.secondary { background: #2f6db0; }
table { width: 100%; border-collapse: collapse; background: #fff; }
th, td { text-align: left; padding: 9px 12px; border-bottom: 1px solid #eef1f5; }
th { background: #f4f7fb; color: #1b2a4a; }
.notice { background: #fef3c7; border: 1px solid #fde68a; padding: 12px; border-radius: 8px; margin-bottom: 14px; }
.present { color: #166534; font-weight: 600; }
.absent { color: #b91c1c; font-weight: 600; }
.toggle { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.thumb { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid #cbd5e1; vertical-align: middle; }
.thumb-empty { display: inline-block; background: #dbe4f3; }
/* Student roster: compact rows, names on one line, muted subtitles, row hover. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 10px; }
/* The Save row under a table a person acts on (table.sheet). On a desktop it is
   the plain row of buttons it always was; under 720px it sticks above the
   shell's bottom bar (see the phone block below). */
.sheet-save { margin: 12px 0 0; }
/* A figure in a sheet: right-aligned in the desktop table (its header says so
   inline); on a phone the cell is a labelled line and reads from the left. */
.sheet td.num { text-align: right; }
#stuTable td, #stuTable th { white-space: nowrap; vertical-align: middle; }
#stuTable .name { font-weight: 600; font-size: 14.5px; }
/* A second line under the main one in a table cell — the board under a test's
   name, a phone under a father's. Same treatment as the student list's. */
#phaseTable .sub { display: block; color: #6b7684; font-size: 12px; font-weight: 400; margin-top: 2px; }
#stuTable .sub { display: block; color: #6b7684; font-size: 12px; font-weight: 400; margin-top: 2px; }
#stuTable tr:hover td { background: #f7f9fc; }
#stuTable .thumb { width: 40px; height: 40px; }
#stuTable .actions { font-size: 13px; }
.section { display: flex; align-items: center; gap: 8px; color: #2f6db0; font-weight: 600; border-bottom: 2px solid #e2e8f0; padding-bottom: 6px; margin: 22px 0 12px; }
.section svg { width: 18px; height: 18px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px 16px; }
.field { min-width: 0; }
.field > label { margin-top: 0; }
.field.full { grid-column: 1 / -1; }
.sibling-note { margin-top: 6px; font-size: 12.5px; color: #166534; }
.photo-preview { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; border: 1px solid #cbd5e1; }
.dob-row { display: flex; gap: 8px; }
.dob-row select { flex: 1; min-width: 0; }
.metrics { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.metric { background: #f4f7fb; border-radius: 8px; padding: 12px 16px; min-width: 110px; }
.metric .num { font-size: 22px; font-weight: 700; color: #1b2a4a; }
.metric .lbl { font-size: 12.5px; color: #475569; }

/* ===== Phones / small screens ===== */
@media (max-width: 720px) {
  /* Sidebar becomes a slide-in drawer opened by ☰ / "More" */
  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; height: auto; width: 240px; transform: translateX(-100%); transition: transform .22s ease; z-index: 60; box-shadow: 2px 0 14px rgba(0,0,0,.25); }
  body.nav-open .sidebar { transform: translateX(0); }
  .scrim { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 50; }
  body.nav-open .scrim { display: block; }
  .nav-toggle { display: inline-flex; align-items: center; }
  .topbar { padding: 10px 14px; }
  .container { margin: 14px auto; padding: 0 12px 80px; }
  h1 { font-size: 20px; }
  .card { padding: 16px; }
  /* Bottom tab bar */
  .bottomnav { display: flex; position: fixed; left: 0; right: 0; bottom: 0; background: #1b2a4a; z-index: 40; padding: 6px 0; padding-bottom: max(6px, env(safe-area-inset-bottom)); box-shadow: 0 -2px 10px rgba(0,0,0,.18); }
  .bottomnav a, .bottomnav button { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 5px 0; color: #9db8de; font-size: 10.5px; text-decoration: none; background: none; border: 0; cursor: pointer; font-family: inherit; }
  .bottomnav a.active { color: #fff; }
  .bottomnav svg { width: 21px; height: 21px; }
  /* Wide data tables scroll sideways instead of squashing/breaking the page */
  table { display: block; width: auto; min-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
  th, td { padding: 8px 10px; font-size: 14px; }
  /* ---- A table a person ACTS on: a list of cards on a phone (2026-10-10) ----
     The rule above is right for a report the office reads on a desktop and
     wrong for a teacher entering marks on a phone: the owner's screenshots
     showed the marks box off the right edge, the name scrolling out of view
     when the next box was tapped, and "Enter marks" cut to "Enter". So a table
     carrying class="sheet" is NOT a scroller here. Its header row hides (it
     must sit in a <thead>), each row becomes a white rounded card, and each
     cell a line of it, printing its data-label first. Three kinds of cell:
       data-roll  the roll number, a small pill before the name
       data-main  the name — large, beside the roll
       data-sub   the father, muted, on its own line
       data-act   the control: select, box, button — its own line, 44px tall;
                  data-act="att" and data-act="mark" share one line (the
                  attendance select about 55%, the marks box the rest).
     Above 720px none of this applies and a .sheet is the table it always was,
     so the office's desktop screens (the marks grid is the office's view too)
     do not change. tests/teacher_phone_fit.test.js walks every teacher page
     for a bare <table>, and reads these rules. */
  table.sheet { display: block; width: 100%; min-width: 0; overflow: visible; white-space: normal; background: none; border-radius: 0; }
  table.sheet thead { display: none; }
  table.sheet tbody { display: block; }
  table.sheet tr { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; background: #fff; border: 1px solid #e3e8f0; border-radius: 12px; padding: 10px 12px; margin: 0 0 10px; }
  table.sheet td { display: block; flex: 1 1 100%; min-width: 0; padding: 1px 0; border: 0; font-size: 14px; line-height: 1.45; overflow-wrap: anywhere; }
  table.sheet td:empty { display: none; }
  table.sheet td[data-label]::before { content: attr(data-label) ": "; color: #6b7684; font-size: 12.5px; font-weight: 600; }
  table.sheet td[data-label] { flex: 1 1 45%; text-align: left; }
  /* The roll and the name lead the card whatever column they sit in on the
     desktop (the time table's Period | Time | Subject keeps its column order). */
  table.sheet td[data-roll] { order: -2; flex: 0 0 auto; background: #eef2f8; color: #1b2a4a; border-radius: 7px; padding: 1px 8px; font-size: 12.5px; font-weight: 700; }
  table.sheet td[data-main] { order: -1; flex: 1 1 0; font-size: 16px; font-weight: 700; color: #1b2a4a; }
  table.sheet td[data-sub] { flex: 1 1 100%; color: #6b7684; font-size: 13px; }
  table.sheet td[data-act] { flex: 1 1 100%; margin-top: 6px; }
  table.sheet td[data-act="att"] { flex: 0 0 55%; }
  table.sheet td[data-act="mark"] { flex: 1 1 0; }
  table.sheet td[data-act] select, table.sheet td[data-act] input, table.sheet td[data-act] button, table.sheet td[data-act] .btn { min-height: 44px; }
  table.sheet td[data-act] select, table.sheet td[data-act] input { width: 100%; padding: 9px 10px; font-size: 16px; }
  table.sheet td[data-act] > .btn:only-child { display: block; text-align: center; box-sizing: border-box; }
  table.sheet td[data-act] form { display: inline; }
  /* The Save row of a sheet stays within a thumb's reach while the rows scroll
     by, sitting on the shell's bottom bar: each shell says how tall its bar is
     through --bar-h on the body (the teacher's in teacher.css). */
  body { --bar-h: calc(60px + env(safe-area-inset-bottom, 0px)); }
  .sheet-save { position: sticky; bottom: var(--bar-h, 0px); z-index: 5; background: #fff; margin: 0 -16px; padding: 10px 16px; box-shadow: 0 -6px 12px -8px rgba(0,0,0,.18); display: flex; gap: 8px; flex-wrap: wrap; }
  .sheet-save > button, .sheet-save > .btn { flex: 1 1 auto; text-align: center; min-height: 44px; }
  .form-grid { gap: 10px 12px; }
  button, .btn { padding: 12px 18px; }
  .kpi-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .kpi { padding: 12px 13px; gap: 10px; }
  .kpi-ic { width: 34px; height: 34px; }
  .kpi .num { font-size: 19px; }
}
@media (max-width: 380px) {
  .bottomnav span { font-size: 10px; }
  .topbar-title { font-size: 15px; }
}

/* ===== Sidebar expandable group (Attendance) ===== */
.nav-group { border: 0; }
.nav-group > summary { display: flex; align-items: center; gap: 12px; padding: 11px 16px; color: #cdddef; font-size: 14.5px; cursor: pointer; list-style: none; user-select: none; }
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover { background: rgba(255,255,255,.08); color: #fff; }
.nav-group > summary svg { width: 18px; height: 18px; flex-shrink: 0; }
.nav-group > summary .chev { margin-left: auto; display: inline-flex; transition: transform .18s ease; }
.nav-group[open] > summary .chev { transform: rotate(180deg); }
.nav-sub { display: flex; flex-direction: column; background: rgba(0,0,0,.16); }
.nav-sub a { padding: 9px 16px 9px 46px !important; font-size: 13.5px !important; }

/* ===== Attendance register grid ===== */
.att-register .reg-head { text-align: center; margin-bottom: 12px; }
table.reg-grid { border-collapse: collapse; font-size: 12px; width: auto; min-width: 100%; }
table.reg-grid th, table.reg-grid td { border: 1px solid #cbd3df; padding: 4px 6px; text-align: center; white-space: nowrap; }
table.reg-grid thead th { background: #1b2a4a; color: #fff; font-weight: 600; }
table.reg-grid tfoot td { background: #eef2f8; font-weight: 700; }
table.reg-grid td.stick, table.reg-grid th.stick { position: sticky; left: 0; background: #fff; text-align: left; z-index: 2; }
table.reg-grid th.stick { background: #1b2a4a; }
table.reg-grid td.stick2, table.reg-grid th.stick2 { left: 52px; min-width: 150px; }
table.reg-grid thead th.stick { z-index: 3; }
table.reg-grid .daycol { min-width: 22px; }
table.reg-grid .sumcol { background: #f7f9fc; font-weight: 600; }
table.reg-grid td.s-present, table.reg-grid td.s-late_present { color: #12684d; font-weight: 700; }
table.reg-grid td.s-absent { color: #a3241c; font-weight: 700; }
table.reg-grid td.s-leave { color: #8a5a00; }
table.reg-grid td.s-short_leave { color: #7a6100; }
table.reg-grid td.s-notset { color: #c2c8d2; }
.reg-legend { margin-top: 10px; font-size: 12px; color: #444; }

@media print {
  @page { size: A4 landscape; margin: 10mm; }
  .att-register { border: none !important; box-shadow: none !important; padding: 0 !important; }
  table.reg-grid { font-size: 9px; }
  table.reg-grid th, table.reg-grid td { padding: 2px 3px; }
  table.reg-grid td.stick, table.reg-grid th.stick, table.reg-grid td.stick2, table.reg-grid th.stick2 { position: static; }
  table.reg-grid thead th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ── Per-setup identity ───────────────────────────────────────────────────────
   The group runs 8 campuses across 3 setups and campus names REPEAT across them
   ("Jorry Pul" is both a Babar Academy and a Kandaan School campus), so text alone
   is easy to misread. Each institution carries its own colour (--setup-accent):
   teal = Kandaan School, blue = Babar Academy, green = Lahore College. Pages with
   no active campus keep the original navy (body.setup-default). */
body:not(.setup-default) .sidebar { background: var(--setup-accent); }
body:not(.setup-default) .side-nav a.active { background: rgba(0,0,0,.30); color: #fff; }
body:not(.setup-default) .topbar { border-top: 4px solid var(--setup-accent); }
.topbar-title .setup-name { color: var(--setup-accent, #1b2a4a); font-weight: 800; }

/* Campus picker, grouped by institution */
.setup-block { padding-top: 14px; }
.setup-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.setup-dot { width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; }
.setup-meta { color: #5f6b7a; font-size: 13px; }
.open-btn { color: #fff; border: 0; border-radius: 8px; padding: 8px 14px; font-weight: 600; cursor: pointer; font-family: inherit; font-size: 13px; white-space: nowrap; }
.open-btn:hover { filter: brightness(.92); }

/* "You are adding to …" banner on data-entry screens */
.scope-banner { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  border-left: 5px solid var(--setup-accent, #1b2a4a); background: #f6f8fb;
  border-radius: 6px; padding: 9px 13px; margin: 0 0 14px; font-size: 14px; }
.scope-banner .sb-dot { width: 11px; height: 11px; border-radius: 50%; background: var(--setup-accent, #1b2a4a); flex: 0 0 auto; }
.scope-banner strong { color: var(--setup-accent, #1b2a4a); }
.scope-banner .sb-switch { margin-left: auto; font-size: 13px; }
.scope-banner .sb-switch button { background: none; border: 0; color: #2f6db0; text-decoration: underline; cursor: pointer; font: inherit; padding: 0; }
@media print { .scope-banner { display: none !important; } }

/* A dashboard number is the start of a question, so tiles that lead somewhere are
   clickable and say so on hover. */
.kpi-link { text-decoration: none; color: inherit; cursor: pointer; transition: transform .08s ease, box-shadow .08s ease; }
.kpi-link:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(27,42,74,.14); }
.kpi-link:focus-visible { outline: 2px solid var(--setup-accent, #2f6db0); outline-offset: 2px; }

/* Student status at a glance in the register — Inactive means "stopped coming but
   has not formally left", so it must stand out without looking like an error. */
.pill { display: inline-block; padding: 2px 9px; border-radius: 11px; font-size: 12px; font-weight: 700; white-space: nowrap; background: #eef2f8; color: #41506a; }
.pill-enrolled { background: #e7f6ee; color: #14724c; }
.pill-inactive { background: #fdf1dd; color: #96601a; }
.pill-left, .pill-struck-off { background: #f4f5f6; color: #78838f; }
.pill-suspended { background: #fdecea; color: #a3241c; }
.pill-passed-out { background: #eef3fb; color: #2f5b9c; }

/* Fee Setup: a class with students but no fee silently bills Rs 0 — make it obvious. */
tr.fee-gap td { background: #fdf1dd; }
.gap-tag { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 10px; background: #f5c06b; color: #6b4410; font-size: 11px; font-weight: 700; }

/* ===== Class teacher's call list =====
   A card per child instead of a table row. This screen exists to be used on a
   phone in a corridor: the number to tap and the remark to pick must both be on
   screen, which a wide table cannot manage without sideways scrolling. */
.callrow { border: 1px solid #e2e8f0; border-radius: 10px; padding: 12px 14px; margin: 10px 0; background: #fff; }
.callrow-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.callrow-who { display: flex; flex-direction: column; gap: 2px; }
.callrow-sub { color: #5f6b7a; font-size: 12.5px; }
.callrow-tel { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.callrow-tel .btn { padding: 9px 14px; }
.callrow-say { display: flex; flex-wrap: wrap; gap: 10px 14px; }
.callrow-say label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: #41506a; flex: 1 1 220px; }
.callrow-say select, .callrow-say input { width: 100%; }


/* ===== Top-bar student search =====
   Sits beside New Inquiry. The results panel floats over the page rather than
   pushing it about, because it opens and closes on every keystroke. */
.quick-search { position: relative; display: inline-flex; }
.quick-search input[type="search"] { width: 190px; padding: 7px 11px; border: 1px solid #d7dee8; border-radius: 8px; font: inherit; font-size: 13.5px; background: #fff; }
.quick-search input[type="search"]:focus { outline: 2px solid var(--setup-accent, #1b4f9c); outline-offset: 1px; }
.quick-search-results { position: absolute; top: calc(100% + 6px); right: 0; min-width: 290px; max-height: 340px; overflow-y: auto; background: #fff; border: 1px solid #dbe2ec; border-radius: 10px; box-shadow: 0 8px 24px rgba(16,26,48,.16); z-index: 70; }
.quick-search-hit { display: flex; flex-direction: column; gap: 1px; padding: 8px 12px; text-decoration: none; color: #1b2a4a; border-bottom: 1px solid #f0f3f8; }
.quick-search-hit:last-child { border-bottom: 0; }
.quick-search-hit:hover, .quick-search-hit.active { background: #eef4ff; }
.quick-search-hit .qs-name { font-weight: 600; font-size: 13.5px; }
.quick-search-hit .qs-where { color: #5f6b7a; font-size: 12px; }
.quick-search-none { padding: 10px 12px; color: #5f6b7a; font-size: 13px; }
@media (max-width: 720px) {
  .quick-search input[type="search"] { width: 130px; }
  /* The results panel is pinned to the RIGHT EDGE OF THE INPUT and is at least
     290px wide. On a phone the input is 130px and sits mid-bar, so the panel hung
     59px off the left of the screen and every name and "Section B · Roll 4" was
     cut in half. The office reported exactly that.
     Dropping position:relative here hands the panel to .topbar (which is sticky,
     so it is a containing block), and it then spans the screen and drops below
     the whole bar instead of below the little input. */
  .quick-search { position: static; }
  .quick-search-results { left: 10px; right: 10px; min-width: 0; max-height: 60vh; }
}

/* The inquiry form's "this number already has an inquiry" panel. Neutral by
   default — a sibling's inquiry is information, not a mistake — and amber only
   when the same child is already on file, which is what Save will refuse.
   It sits inside the form grid, so it spans the whole row rather than
   squeezing itself into one column beside a field. */
.dupe-panel { grid-column: 1 / -1; margin: -4px 0 10px; padding: 10px 12px; border-radius: 10px;
  background: #eef5ff; border: 1px solid #cfe0f7; font-size: 13px; }
.dupe-panel.is-dupe { background: #fdf3e6; border-color: #f0d9a8; }
/* The box while the answer is still on its way. Same size as a painted one, so
   the reply lands INSIDE a box that is already the right shape. */
.dupe-panel.is-checking { color: #5f6b7a; }
/* ONE height, whatever is in it — checking, one name, or ten.
   The panel opens between the phone field and the next one, about 200ms after
   the last digit, which is often exactly as the office reaches for that next
   field. Any change of height moves their target under their finger. A box
   reserved for one row and then filled with ten shoved the form 431px, which
   was worse than the jump the reservation was added to stop, so the box is now
   a fixed size and long lists scroll inside it. A little whitespace under a
   short answer is a fair price for the form never moving. */
.dupe-panel { height: 132px; overflow-y: auto; }
.dupe-checking { color: #5f6b7a; }
.dupe-head { font-weight: 600; margin-bottom: 6px; }
.dupe-hit { display: block; padding: 3px 0; color: inherit; text-decoration: none; }
.dupe-where { color: #5f6b7a; font-size: 12.5px; }
.dupe-many { margin-top: 6px; color: #5f6b7a; font-size: 12.5px; }

/* A wide table scrolls inside its own box on screen so the whole PAGE does not
   slide sideways. On paper there is nothing to scroll, and leaving it on clips
   the columns that ran past the edge — so the printed sheet gets all of them. */
@media print { .table-scroll { overflow: visible !important; } }

/* Attendance: one row per class; the class that is open is tinted. */
.att-rows tr.active td { background: #eef1f5; }
.att-rows td { vertical-align: middle; }

/* The password reminder: a notice, not a gate (2026-09-11). The selectors carry
   the body so they outrank the shells' own button rules. */
body .pw-nudge { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: #fff8e1; border: 1px solid #f0e0a0; color: #7a5b00; border-radius: 12px; padding: 9px 12px; margin: 0 0 12px; font-size: 13.5px; line-height: 1.4; }
body .pw-nudge .pw-nudge-icon { font-size: 18px; }
body .pw-nudge .pw-nudge-text { flex: 1 1 220px; min-width: 200px; }
body .pw-nudge .pw-nudge-actions { display: flex; gap: 8px; align-items: center; margin-left: auto; }
body .pw-nudge a.pw-nudge-go { display: inline-block; background: #7a5b00; color: #fff; border-radius: 8px; padding: 6px 12px; font-weight: 700; text-decoration: none; font-size: 13px; line-height: 1.3; }
body .pw-nudge button.pw-nudge-later, body.portal .pw-nudge button.pw-nudge-later { background: transparent; border: 1px solid #d9c98a; color: #7a5b00; border-radius: 8px; padding: 5px 11px; font-size: 13px; font-weight: 600; line-height: 1.3; cursor: pointer; box-shadow: none; width: auto; min-height: 0; }

/* ── Messaging (2026-10-11): the conversation list and the chat. The same block
   sits in styles.css for the office shell, which does not load this sheet;
   change both. tests/messaging_portal + messaging_inbox render the markup. ── */
.conv { display: flex; gap: 10px; align-items: center; padding: 10px 2px; border-top: 1px solid #eef0f6; text-decoration: none; color: inherit; }
.conv:first-of-type { border-top: 0; }
.conv-avatar { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; background: #e8e7f6; color: #4a43a8; font-weight: 800; font-size: 15px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.conv-avatar img { width: 100%; height: 100%; object-fit: cover; }
.conv-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.conv-name { font-weight: 700; font-size: 15px; }
.conv-name small { font-weight: 600; color: #6b6f8c; font-size: 12px; margin-left: 4px; }
.conv-last { color: #6b6f8c; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-side { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.conv-when { font-size: 11.5px; color: #8a8fb0; }
.conv-unread { min-width: 20px; height: 20px; border-radius: 10px; background: var(--accent, #534AB7); color: #fff; font-size: 12px; font-weight: 800; display: flex; align-items: center; justify-content: center; padding: 0 6px; }
.chat-head { display: flex; align-items: center; gap: 10px; padding: 6px 2px 10px; }
.chat-who { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.chat-who small { color: #6b6f8c; font-size: 12px; }
.chat-scroll { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 8px; }
.chat-day { text-align: center; margin: 8px 0 4px; }
.chat-day span { font-size: 11.5px; font-weight: 700; color: #6b6f8c; background: #eef0f6; border-radius: 10px; padding: 3px 10px; }
.chat-row { display: flex; }
.chat-row.own { justify-content: flex-end; }
.chat-bubble { max-width: 84%; padding: 8px 11px; border-radius: 16px; background: #fff; border: 1px solid #e6e6f0; border-bottom-left-radius: 5px; }
.chat-row.own .chat-bubble { background: var(--accent, #534AB7); color: #fff; border-color: transparent; border-bottom-left-radius: 16px; border-bottom-right-radius: 5px; }
.chat-text { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; line-height: 1.4; }
.chat-meta { font-size: 11px; opacity: .72; margin-top: 4px; }
.chat-img img { display: block; max-width: 100%; max-height: 260px; border-radius: 10px; margin-bottom: 6px; }
.chat-file { display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; background: rgba(0,0,0,.06); border-radius: 10px; padding: 8px 10px; margin-bottom: 6px; }
.chat-row.own .chat-file { background: rgba(255,255,255,.18); }
.chat-file-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: 14px; }
.chat-file-size { font-size: 12px; opacity: .8; }
.chat-compose { position: sticky; bottom: var(--bar-h, 60px); display: flex; align-items: flex-end; gap: 8px; background: #fff; border: 1px solid #e6e6f0; border-radius: 22px; padding: 6px 6px 6px 10px; margin-top: 6px; }
.chat-compose textarea { flex: 1 1 auto; border: 0; outline: 0; resize: none; font: inherit; font-size: 16px; line-height: 1.35; padding: 8px 4px; min-height: 36px; max-height: 120px; background: transparent; box-shadow: none; }
.chat-attach { flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #6b6f8c; cursor: pointer; }
.chat-attach input { display: none; }
.chat-attach svg { width: 22px; height: 22px; }
.chat-send { flex: 0 0 40px; width: 40px; height: 40px; border-radius: 50%; border: 0; background: var(--accent, #534AB7); color: #fff; display: flex; align-items: center; justify-content: center; padding: 0; margin: 0; }
.chat-send svg { width: 20px; height: 20px; }
.chat-pending { font-size: 12.5px; color: #6b6f8c; padding: 4px 12px; }
/* The office shell has no .icon-btn of its own (portal.css and teacher.css do): the
   chat head's back arrow would draw at the browser's default SVG size. */
.chat-head .icon-btn { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #1b2a4a; background: #eef2f8; text-decoration: none; flex: 0 0 36px; }
.chat-head .icon-btn svg { width: 22px; height: 22px; }
.chat-card { padding: 12px; }

/* ── Campus feed (2026-10-11): posts, the composer, comments. The same block
   sits in portal.css for the student's and the teacher's shells;
   change both. tests/campus_feed_portal + campus_feed_staff render the markup. ── */
.post { background: #fff; border: 1px solid #e6e6f0; border-radius: 16px; padding: 12px 12px 8px; margin: 0 0 12px; }
.post.pending { border-color: #f0e0a0; }
.post-head { display: flex; align-items: center; gap: 10px; }
.post-avatar { flex: 0 0 40px; width: 40px; height: 40px; font-size: 14px; }
.post-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.post-who b { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.post-who small { color: #6b6f8c; font-size: 12px; }
.post-kind { display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .3px; text-transform: uppercase; border-radius: 8px; padding: 1px 7px; background: #e8e7f6; color: #4a43a8; margin-left: 4px; vertical-align: 1px; }
.post-when { flex: 0 0 auto; font-size: 11.5px; color: #8a8fb0; text-align: right; line-height: 1.3; text-decoration: none; }
.post-wait { margin: 10px 0 0; font-size: 12.5px; font-weight: 700; color: #7a5b00; background: #fff8e1; border-radius: 10px; padding: 7px 10px; }
.post-text { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 15px; line-height: 1.45; margin: 10px 0 0; }
.post-pics { display: grid; gap: 4px; margin: 10px 0 0; border-radius: 12px; overflow: hidden; }
.post-pics.n1 { grid-template-columns: 1fr; }
.post-pics.n2, .post-pics.n3, .post-pics.n4 { grid-template-columns: 1fr 1fr; }
.post-pics.n3 a:first-child { grid-column: 1 / -1; }
.post-pics a { display: block; background: #f1f2f7; min-width: 0; }
.post-pics img { display: block; width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.post-pics.n1 img { aspect-ratio: auto; max-height: 420px; object-fit: contain; }
.post-doc { display: flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; background: #f4f5fa; border-radius: 10px; padding: 9px 10px; margin: 10px 0 0; }
.post-acts { display: flex; align-items: center; gap: 2px; margin: 8px 0 0; border-top: 1px solid #eef0f6; padding-top: 6px; }
.post-acts form, .cmt-meta form { margin: 0; }
.act { display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; color: #6b6f8c; font: inherit; font-size: 13px; font-weight: 700; padding: 6px 9px; border-radius: 10px; text-decoration: none; cursor: pointer; line-height: 1; }
.act svg { width: 20px; height: 20px; flex: 0 0 20px; }
.act.like.on { color: #d6336c; } .act.like.on svg { fill: #d6336c; }
.act.ok { color: #0f6e56; }
.act.danger { color: #b4231f; margin-left: auto; }
.post-compose { background: #fff; border: 1px solid #e6e6f0; border-radius: 16px; padding: 10px 12px; margin: 0 0 12px; }
.post-compose textarea { width: 100%; border: 0; outline: 0; resize: none; font: inherit; font-size: 15px; line-height: 1.4; padding: 6px 2px; min-height: 44px; background: transparent; box-shadow: none; box-sizing: border-box; }
.pc-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; border-top: 1px solid #eef0f6; padding-top: 8px; }
.pc-attach { display: inline-flex; align-items: center; gap: 6px; color: #6b6f8c; font-size: 13px; font-weight: 700; cursor: pointer; }
.pc-attach input { display: none; }
.pc-attach svg { width: 22px; height: 22px; }
.pc-opt { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600; color: #4a4f6a; }
.pc-opt input { margin: 0; }
.pc-post { margin-left: auto; border: 0; border-radius: 12px; background: var(--setup-accent, var(--accent, #534AB7)); color: #fff; font: inherit; font-weight: 800; font-size: 14px; padding: 9px 18px; }
.pc-post:disabled { opacity: .55; }
.cmt { display: flex; gap: 10px; padding: 10px 0; border-top: 1px solid #eef0f6; }
.cmt:first-of-type { border-top: 0; }
.cmt-avatar { flex: 0 0 34px; width: 34px; height: 34px; font-size: 12.5px; }
.cmt-body { flex: 1 1 auto; min-width: 0; background: #f4f5fa; border-radius: 14px; padding: 8px 12px; }
.cmt-body b { font-size: 14px; }
.cmt-text { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14.5px; line-height: 1.4; margin-top: 2px; }
.cmt-meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #8a8fb0; margin-top: 4px; }
.cmt-meta .act { padding: 2px 4px; font-size: 12px; }
.cmt.best .cmt-body { background: #e1f5ee; border: 1px solid #b6ecdb; }
.best-tag { color: #0f6e56; font-weight: 800; font-size: 12px; }
.cmt-compose { margin-top: 10px; }
/* The action buttons are NOT the portal's big navy submit buttons (body.portal button[type=submit], and styles.css's button): flat text with an icon. */
body.portal .post-acts button.act, body.portal .cmt-meta button.act, .post-acts button.act, .cmt-meta button.act { background: transparent !important; box-shadow: none !important; color: #6b6f8c; border: 0; border-radius: 10px; padding: 6px 9px; min-height: 0; width: auto; font-size: 13px; font-weight: 700; line-height: 1; transform: none; }
body.portal .post-acts button.act.like.on, .post-acts button.act.like.on { color: #d6336c; }
body.portal .post-acts button.act.ok, body.portal .cmt-meta button.act.ok, .post-acts button.act.ok, .cmt-meta button.act.ok { color: #0f6e56; }
body.portal .post-acts button.act.danger, body.portal .cmt-meta button.act.danger, .post-acts button.act.danger, .cmt-meta button.act.danger { color: #b4231f; }
body.portal .cmt-meta button.act, .cmt-meta button.act { padding: 2px 4px; font-size: 12px; }

/* Campus rights (2026-10-11): the who-may-post list. In both sheets, like the feed block. */
.rt-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding: 10px 0; border-top: 1px solid #eef0f6; }
.rt-row:first-of-type { border-top: 0; }
.rt-main { flex: 1 1 150px; min-width: 0; }
.rt-main small { display: block; color: #6b6f8c; font-size: 12px; }
.rt-opt { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: #4a4f6a; }
.rt-opt input[type=checkbox], .rt-opt input[type=radio] { margin: 0; width: auto; min-height: 0; }
.rt-opt input[type=date], .rt-opt select { font: inherit; font-size: 13px; padding: 5px 7px; border: 1px solid #d9dbe8; border-radius: 8px; width: auto; min-height: 0; background: #fff; }
