/* ---------------------------------------------------------------------------
   Hifzul Quran School — brand tokens

   Every colour below is sampled from the school crest. The three that carry
   the identity:

     navy    #1D1852   the shield
     crimson #89181B   the ribbon
     ink     #141240   the shield outline

   The palette is LIGHT ONLY, by request. There is deliberately no
   prefers-color-scheme block: a dark variant would have to re-derive every
   surface and would put the crest's navy against a dark ground, where it
   stops reading as navy at all.
--------------------------------------------------------------------------- */

:root {
  /* Brand, straight from the crest */
  --navy: #1d1852;
  --navy-ink: #141240;
  --navy-soft: #56527d;
  --crimson: #89181b;
  --crimson-deep: #77161e;
  --crimson-soft: #bd4647;

  /* Tinted neutrals — greys carrying a trace of the navy so the page reads
     as one family rather than brand colour dropped onto plain grey. */
  --paper: #f7f7fb;
  --surface: #ffffff;
  --surface-sunk: #f0f0f5;
  --border: #e0e0ea;
  --border-strong: #c7c6d4;

  --text: #1a1a2e;
  --text-muted: #5a5a72;
  --text-faint: #86869c;
  --on-dark: #ffffff;

  /* Status. Progressing and held-back are the two states in the domain;
     held-back is NOT an error — it is the rule working as intended, so it
     gets amber, never red. Red is reserved for genuine failures. */
  --ok: #1d6b4f;
  --ok-bg: #e7f3ee;
  --hold: #8a5a00;
  --hold-bg: #fdf3e0;
  --danger: var(--crimson);
  --danger-bg: #fbeaea;

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgb(20 18 64 / 6%), 0 4px 14px rgb(20 18 64 / 6%);
  --shadow-lift: 0 2px 4px rgb(20 18 64 / 8%), 0 10px 28px rgb(20 18 64 / 10%);

  --font: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --font-numeric: "SF Mono", "Cascadia Mono", "Consolas", monospace;

  --wrap: 68rem;
}

/* --- Reset ------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--text);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0 0 0.4em;
  line-height: 1.25;
  color: var(--navy-ink);
  font-weight: 650;
  letter-spacing: -0.01em;
}

h1 {
  font-size: 1.6rem;
}
h2 {
  font-size: 1.2rem;
}

p {
  margin: 0 0 1rem;
}

a {
  color: var(--navy);
  text-underline-offset: 2px;
}

a:hover {
  color: var(--crimson);
}

/* Focus is never removed — teachers and admins will use keyboards. */
:focus-visible {
  outline: 3px solid var(--crimson-soft);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* --- Layout ------------------------------------------------------------ */

.page {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.main {
  flex: 1;
  padding-block: 2rem 3rem;
}

/* --- Masthead ---------------------------------------------------------- */

.masthead {
  background: var(--navy);
  color: var(--on-dark);
  border-bottom: 4px solid var(--crimson);
}

.masthead__inner {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding-block: 0.7rem;
  flex-wrap: wrap;
}

.masthead__crest {
  height: 46px;
  width: auto;
  flex: none;
}

/* The crest is a link home for anyone signed in. */
.masthead__home {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-sm);
  padding: 2px 4px;
  margin-left: -4px;
}

.masthead__home:hover {
  color: inherit;
  background: rgb(255 255 255 / 8%);
}

.masthead__titles {
  min-width: 0;
}

.masthead__name {
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: 0.01em;
  line-height: 1.2;
}

.masthead__sub {
  font-size: 0.78rem;
  color: #b9b6d4;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/* --- Account menu ------------------------------------------------------- */

.usermenu {
  position: relative;
  flex: none;
  /* Pinned to the right edge. The section bar used to absorb the free space
     here with margin-left:auto; now that the sections live in the left rail,
     the account menu takes over that job. */
  margin-left: auto;
}

.usermenu__trigger {
  display: grid;
  place-items: center;
  padding: 3px;
  background: transparent;
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease;
}

.usermenu__trigger:hover,
.usermenu__trigger[aria-expanded="true"] {
  border-color: rgb(255 255 255 / 45%);
  background: rgb(255 255 255 / 10%);
}

.avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--crimson);
  color: var(--on-dark);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  user-select: none;
}

.avatar--sm {
  width: 26px;
  height: 26px;
  font-size: 0.66rem;
}

.avatar--lg {
  width: 46px;
  height: 46px;
  font-size: 1.05rem;
  flex: none;
}

.avatar--xl {
  width: 64px;
  height: 64px;
  font-size: 1.4rem;
  flex: none;
}

/* A photograph replaces the initials entirely, cropped to the circle. */
.avatar--photo {
  background: var(--surface-sunk);
  overflow: hidden;
  border: 1px solid var(--border);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.namecell {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
}

.namecell span {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.profilehead {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.profilehead strong {
  display: block;
  color: var(--navy-ink);
  font-weight: 650;
}

.usermenu__panel {
  position: absolute;
  top: calc(100% + 0.6rem);
  right: 0;
  z-index: 40;
  min-width: 16rem;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}

.usermenu__panel[hidden] {
  display: none;
}

.usermenu__head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface-sunk);
}

.usermenu__id {
  min-width: 0;
  line-height: 1.35;
}

.usermenu__id strong {
  display: block;
  color: var(--navy-ink);
  font-weight: 650;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.usermenu__role {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--crimson);
}

.usermenu__email {
  display: block;
  font-size: 0.8rem;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.usermenu__item {
  display: block;
  width: 100%;
  padding: 0.7rem 1rem;
  font: inherit;
  font-size: 0.92rem;
  text-align: left;
  text-decoration: none;
  color: var(--text);
  background: transparent;
  border: 0;
  cursor: pointer;
}

.usermenu__item:hover {
  background: var(--surface-sunk);
  color: var(--navy-ink);
}

.usermenu__item--button {
  border-top: 1px solid var(--border);
  color: var(--crimson);
  font-weight: 600;
}

.usermenu__item--button:hover {
  background: var(--danger-bg);
  color: var(--crimson-deep);
}

/* --- Buttons ----------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font: inherit;
  font-weight: 600;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease;
  /* Comfortable target on a phone held one-handed in a classroom. */
  min-height: 44px;
}

.btn--primary {
  background: var(--navy);
  color: var(--on-dark);
}

.btn--primary:hover {
  background: var(--navy-ink);
  color: var(--on-dark);
}

.btn--accent {
  background: var(--crimson);
  color: var(--on-dark);
}

.btn--accent:hover {
  background: var(--crimson-deep);
  color: var(--on-dark);
}

.btn--quiet {
  background: transparent;
  border-color: rgb(255 255 255 / 35%);
  color: var(--on-dark);
  padding: 0.4rem 0.8rem;
  min-height: 38px;
}

.btn--quiet:hover {
  background: rgb(255 255 255 / 12%);
  color: var(--on-dark);
}

.btn--block {
  width: 100%;
}

/* --- Cards ------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}

.card__lede {
  color: var(--text-muted);
  margin-bottom: 1.25rem;
}

/* --- Forms ------------------------------------------------------------- */

.field {
  margin-bottom: 1rem;
}

.field label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--navy-ink);
  margin-bottom: 0.3rem;
}

.field input {
  width: 100%;
  font: inherit;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  min-height: 44px;
}

.field input:focus {
  border-color: var(--navy);
  outline: 3px solid rgb(29 24 82 / 15%);
  outline-offset: 0;
}

.errors {
  background: var(--danger-bg);
  border-left: 3px solid var(--crimson);
  border-radius: var(--radius-sm);
  padding: 0.7rem 0.9rem;
  margin-bottom: 1.1rem;
  font-size: 0.9rem;
  color: var(--crimson-deep);
}

.errors p:last-child {
  margin-bottom: 0;
}

/* --- Login ------------------------------------------------------------- */

.login {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  /* A whisper of the crest's navy at the edges, white where the card sits. */
  background:
    radial-gradient(60rem 40rem at 50% -10%, #e8e7f2 0%, var(--paper) 60%);
}

.login__box {
  width: 100%;
  max-width: 25rem;
}

.login__card {
  padding-top: 2rem;
}

/* The full crest's white fields are transparent, so it must sit on the card's
   white surface — never on the tinted page background. */
.login__crest {
  display: block;
  width: 160px;
  height: auto;
  margin: 0 auto 1.25rem;
}

.login__title {
  text-align: center;
  font-size: 1.25rem;
  margin-bottom: 0.15rem;
}

.login__sub {
  text-align: center;
  color: var(--text-muted);
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 0;
}

.login__rule {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 1.5rem 0;
}

.login__help {
  text-align: center;
  font-size: 0.82rem;
  color: var(--text-faint);
  margin: 1rem 0 0;
}

.auth__heading {
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}

.auth__link {
  text-align: center;
  font-size: 0.88rem;
  margin: 1.1rem 0 0;
}

/* --- Placeholder pages ------------------------------------------------- */

.tag {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: var(--surface-sunk);
  color: var(--navy);
  border: 1px solid var(--border);
}

.upcoming {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}

.upcoming li {
  padding: 0.7rem 0 0.7rem 1.6rem;
  border-bottom: 1px solid var(--border);
  position: relative;
  color: var(--text-muted);
}

.upcoming li::before {
  content: "";
  position: absolute;
  left: 0.25rem;
  top: 1.15rem;
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--crimson);
  opacity: 0.55;
}

/* --- Appendix: the reference edition ------------------------------------ */

.edition {
  border-left: 4px solid var(--crimson);
  margin-bottom: 1.5rem;
}

/* --- Appendix: verification checklist ----------------------------------- */

.checks {
  list-style: none;
  counter-reset: check;
  margin: 1.25rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.check {
  counter-increment: check;
  position: relative;
  padding: 0.9rem 1rem 0.9rem 3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.check::before {
  content: counter(check);
  position: absolute;
  left: 0.9rem;
  top: 0.9rem;
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--navy);
  color: var(--on-dark);
  font-size: 0.78rem;
  font-weight: 700;
}

.check__do {
  font-weight: 650;
  color: var(--navy-ink);
}

.check__expect {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin-top: 0.15rem;
}

.check__system {
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--border);
  font-size: 0.86rem;
  font-variant-numeric: tabular-nums;
  color: var(--navy);
}

.check__system span {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-right: 0.4rem;
}

/* --- Quran reference: converters ---------------------------------------- */

.lookup {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  align-items: start;
}

.hint {
  font-size: 0.86rem;
  color: var(--text-muted);
}

.pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.result {
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1rem;
}

.result dt {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-top: 0.2rem;
}

.result dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.result__big {
  font-size: 1.1rem;
  font-weight: 650;
  color: var(--navy-ink);
}

.result__muted {
  color: var(--text-faint);
}

/* A para test falling due is information, not a problem — navy, not red. */
.flag {
  margin: 1rem 0 0;
  padding: 0.6rem 0.85rem;
  border-left: 3px solid var(--navy);
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: var(--navy-ink);
}

.seq {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}

.seq__item {
  display: grid;
  grid-template-columns: 1.6rem 1fr;
  grid-template-areas:
    "order para"
    "order pages";
  gap: 0 0.5rem;
  align-items: center;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.seq__item--rev {
  border-color: var(--crimson-soft);
  background: #fdf6f6;
}

.seq__order {
  grid-area: order;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.seq__para {
  grid-area: para;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--navy-ink);
}

.seq__pages {
  grid-area: pages;
  font-size: 0.76rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.swatch {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 3px;
  background: #fdf6f6;
  border: 1px solid var(--crimson-soft);
  vertical-align: -1px;
}

/* --- Console (M3) ------------------------------------------------------- */

.pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.pagehead h1,
.pagehead h2 {
  margin-bottom: 0.25rem;
}

.pagehead__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.banner {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  margin-bottom: 1.25rem;
  font-size: 0.92rem;
  border-left: 4px solid var(--navy);
  background: var(--surface-sunk);
  color: var(--navy-ink);
}

.banner--success {
  border-left-color: var(--ok);
  background: var(--ok-bg);
  color: #14503b;
}

.banner--error {
  border-left-color: var(--crimson);
  background: var(--danger-bg);
  color: var(--crimson-deep);
}

.tiles {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.tile {
  display: block;
  padding: 1.1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  text-decoration: none;
}

.tile:hover {
  box-shadow: var(--shadow-lift);
  border-color: var(--border-strong);
}

.tile__figure {
  display: block;
  font-size: 1.9rem;
  font-weight: 650;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.tile__label {
  display: block;
  font-size: 0.84rem;
  color: var(--text-muted);
  margin-top: 0.15rem;
}

.toolbar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.toolbar input[type="search"] {
  font: inherit;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  min-height: 40px;
  min-width: 14rem;
}

.toolbar__link {
  font-size: 0.88rem;
  margin-left: auto;
}

/* The quiet button is designed for the navy masthead; on a light page it needs
   dark text and a visible edge. */
.btn--dark {
  color: var(--navy);
  border-color: var(--border-strong);
}

.btn--dark:hover {
  background: var(--surface-sunk);
  color: var(--navy-ink);
}

.btn--ghost {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--navy);
}

.btn--ghost:hover {
  background: var(--surface-sunk);
  color: var(--navy-ink);
}

.tablewrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.table th,
.table td {
  padding: 0.65rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}

.table th {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--surface-sunk);
}

.table tr:last-child td {
  border-bottom: 0;
}

.table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.warn {
  color: var(--hold);
  font-weight: 600;
}

.pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background: var(--surface-sunk);
  color: var(--navy);
  border: 1px solid var(--border);
}

.pill--ok {
  background: var(--ok-bg);
  color: var(--ok);
  border-color: transparent;
}

.pill--wait {
  background: var(--hold-bg);
  color: var(--hold);
  border-color: transparent;
}

.pill--muted {
  background: var(--surface-sunk);
  color: var(--text-faint);
}

.cols {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  align-items: start;
}

.empty {
  text-align: center;
  padding-block: 2.5rem;
}

.formrule {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 1.5rem 0 1rem;
}

.formactions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 1.25rem;
}

.fielderror {
  color: var(--crimson-deep);
  font-size: 0.85rem;
  margin-top: 0.3rem;
}

.field select,
.field textarea {
  width: 100%;
  font: inherit;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}

.field select {
  min-height: 44px;
}

.link--danger {
  color: var(--crimson);
}

.consequences {
  margin: 0.5rem 0 1.25rem;
  padding-left: 1.25rem;
}

.consequences li {
  margin-bottom: 0.35rem;
}

.steps {
  margin: 0.75rem 0 0;
  padding-left: 1.25rem;
  color: var(--text-muted);
}

.steps li {
  margin-bottom: 0.5rem;
}

.plainlist {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.plainlist li {
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
}

.plainlist li:last-child {
  border-bottom: 0;
}

/* --- Teaching: roster and entry (M4) ------------------------------------ */

.roster {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.roster__row {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Recorded is a quiet, settled state — not a celebration, and not a warning. */
.roster__row--done {
  background: var(--surface-sunk);
  box-shadow: none;
}

.roster__link {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.8rem 1rem;
  text-decoration: none;
  color: inherit;
  /* Comfortable target for a thumb, standing in a classroom. */
  min-height: 62px;
}

.roster__who {
  min-width: 0;
  flex: 1;
}

.roster__who strong {
  display: block;
  color: var(--navy-ink);
  font-weight: 650;
}

.roster__meta {
  display: block;
  font-size: 0.82rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.roster__state {
  text-align: right;
  flex: none;
}

.roster__lines {
  display: block;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

.roster__done {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}

.roster__pending {
  display: inline-block;
  padding: 0.45rem 0.9rem;
  border-radius: var(--radius-sm);
  background: var(--navy);
  color: var(--on-dark);
  font-size: 0.82rem;
  font-weight: 600;
}

.roster__extra {
  position: absolute;
  right: 1rem;
  bottom: -0.6rem;
  font-size: 0.74rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
}

/* --- Rounds ------------------------------------------------------------- */

.rounddots {
  display: flex;
  gap: 3px;
  justify-content: flex-end;
  margin-bottom: 0.2rem;
}

.dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--border-strong);
  display: inline-block;
  flex: none;
}

.dot--passed { background: var(--ok); }
/* Failed is amber, not red: the student re-recites, which is the rule working. */
.dot--failed { background: var(--hold); }
.dot--skipped { background: var(--border-strong); border: 2px solid var(--hold); }
.dot--planned { background: transparent; border: 1.5px solid var(--border-strong); }
.dot--carried { background: var(--navy-soft); }

.rounds {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.round-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  flex-wrap: wrap;
}

.round-item--passed {
  background: var(--ok-bg);
  border-color: transparent;
}

.round-item--failed,
.round-item--skipped {
  background: var(--hold-bg);
  border-color: transparent;
}

.round-item__n {
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--navy);
  color: var(--on-dark);
  font-size: 0.78rem;
  font-weight: 700;
  flex: none;
}

.round-item__body {
  flex: 1;
  /* Wide enough that the sentence under the title has room to be read, rather
     than a short label stranded beside an acre of white and a button. */
  min-width: 16rem;
}

.round-item__body strong {
  display: block;
  color: var(--navy-ink);
}

.round-item__meta {
  display: block;
  font-size: 0.84rem;
  color: var(--text-muted);
}

/* Where he left off, in the round it belongs to: which Nisf comes next, the
   line his new lesson carries on from, what is holding him. */
.round-item__where {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.86rem;
  color: var(--text);
  line-height: 1.45;
}

.round-item__where strong {
  display: inline;
  font-variant-numeric: tabular-nums;
}

.holdnote {
  margin: 0 0 1rem;
  padding: 0.65rem 0.85rem;
  border-left: 3px solid var(--hold);
  background: var(--hold-bg);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}

.round-item__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  /* Pushed to the right edge so the buttons line up down the list however
     long each round's sentence runs. */
  margin-left: auto;
}

.inlineform {
  display: inline;
}

.linkbtn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 0.85rem;
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.linkbtn:hover { color: var(--navy); }
.linkbtn--danger { color: var(--crimson); }

.planslot {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 0.6rem;
  padding-bottom: 0.5rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px dashed var(--border);
}

.outcome {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.btn--big {
  min-height: 54px;
  font-size: 1rem;
}

.dayblock {
  display: flex;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.dayblock:last-child { border-bottom: 0; }

.dayblock__date {
  min-width: 6rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
}

.dayblock__rounds {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.88rem;
}

.dayblock__rounds li {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.dayblock__mark {
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
}

.entryhead {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.entryhead h1 {
  margin-bottom: 0.1rem;
}

.entryhead__pos {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}

/* Held back is the rule working as intended, not a failure: amber, never red. */
.banner--hold {
  border-left-color: var(--hold);
  background: var(--hold-bg);
  color: var(--hold);
}

.entry .round {
  border-top: 1px solid var(--border);
  padding-top: 1.1rem;
  margin-top: 1.1rem;
}

.round__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.round__n {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--navy);
  color: var(--on-dark);
  font-size: 0.76rem;
  font-weight: 700;
  flex: none;
}

.round__or {
  margin: 0.75rem 0 0.5rem;
  font-size: 0.8rem;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.triple {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 0.6rem;
}

.field--inline {
  max-width: 12rem;
}

@media (max-width: 30rem) {
  .triple {
    grid-template-columns: 1fr 1fr;
  }

  .triple .field:first-child {
    grid-column: 1 / -1;
  }
}

/* --- Manzil heat map (M5) ----------------------------------------------- */
/*
   Colour carries the meaning here, so the rule is deliberate:

   * Revision counts shade in NAVY. More revision is more ink — no red/green
     axis, because revising something four times is not "good" and once is not
     "bad"; it is a cursor moving at its own pace.
   * "Memorized but never revised" is the one cell worth acting on, so it gets
     an amber outline — visible without shouting.
   * "Not yet memorized" is neutral grey. No revision is due, so it must not
     read as a gap.
*/

.heatwrap {
  overflow-x: auto;
  margin-top: 1rem;
}

.heat {
  border-collapse: separate;
  border-spacing: 3px;
  font-variant-numeric: tabular-nums;
}

.heat th {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 0 0.4rem;
  text-align: right;
}

.heat thead th {
  text-align: center;
}

.cell {
  display: grid;
  place-items: center;
  width: 4.2rem;
  height: 2.1rem;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  border: 1px solid var(--border);
  gap: 0;
  line-height: 1;
  cursor: default;
}

.cell__n {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--navy-ink);
}

.cell__yr {
  font-size: 0.62rem;
  color: var(--text-faint);
}

.cell--unmemorized {
  background: repeating-linear-gradient(
    45deg,
    #f4f4f7,
    #f4f4f7 4px,
    #ededf2 4px,
    #ededf2 8px
  );
  border-color: transparent;
}

.cell__dash {
  color: var(--text-faint);
  font-size: 0.8rem;
}

/* The gap worth acting on. */
.cell--never {
  background: var(--hold-bg);
  border: 1.5px solid var(--hold);
}

.cell--never .cell__n,
.cell--never .cell__yr {
  color: var(--hold);
}

/* Revision depth, navy — more revision, more ink. */
.cell--revised.lvl-1 { background: #e6e5ef; border-color: transparent; }
.cell--revised.lvl-2 { background: #cdcbdf; border-color: transparent; }
.cell--revised.lvl-3 { background: #a9a5c6; border-color: transparent; }
.cell--revised.lvl-4 { background: #7e79a8; border-color: transparent; }
.cell--revised.lvl-5 { background: var(--navy); border-color: transparent; }

.cell--revised.lvl-4 .cell__n,
.cell--revised.lvl-5 .cell__n,
.cell--revised.lvl-4 .cell__yr,
.cell--revised.lvl-5 .cell__yr {
  color: var(--on-dark);
}

.legend {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.78rem;
  color: var(--text-muted);
  align-items: center;
}

.legend span {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.sw {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  display: inline-block;
}

.sw--none {
  background: #ededf2;
}
.sw--0 { background: var(--hold-bg); border: 1.5px solid var(--hold); }
.sw--1 { background: #e6e5ef; }
.sw--3 { background: #a9a5c6; }
.sw--5 { background: var(--navy); }

.chips {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.chip {
  display: inline-block;
  padding: 0.25rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--surface-sunk);
  border: 1px solid var(--border);
}

.chip--gap {
  background: var(--hold-bg);
  border-color: var(--hold);
  color: var(--hold);
}

/* Memorization grid states, on top of the Appendix's .seq styling. */
.seq__item--complete {
  background: var(--ok-bg);
  border-color: transparent;
}

.seq__item--partial {
  background: #fdf9ef;
  border-color: var(--hold);
}

.seq__item--untouched {
  opacity: 0.55;
}

.chart {
  width: 100%;
  height: auto;
  display: block;
  margin: 0.5rem 0;
}

.round-item__note {
  display: block;
  font-size: 0.85rem;
  color: var(--text-muted);
  font-style: italic;
  margin-top: 0.2rem;
}

.historyday {
  margin-bottom: 1rem;
}

.historyday__head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.historyday__head h2 {
  margin-bottom: 0;
  font-size: 1rem;
}

/* --- Month grid and summaries (M7) -------------------------------------- */

.monthgrid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 3px;
  margin-top: 0.75rem;
}

.monthgrid th {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 0.2rem;
}

.monthgrid td {
  width: 14.28%;
  vertical-align: top;
}

.mday {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 3rem;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.mday--weekend {
  background: var(--surface-sunk);
}

.mday--outside {
  opacity: 0.3;
}

.mday--recorded {
  background: var(--ok-bg);
  border-color: transparent;
}

/* Amber, not red: a failed round means the student re-recites. */
.mday--failed {
  background: var(--hold-bg);
  border-color: transparent;
}

.mday__n {
  font-size: 0.72rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.mday__lines {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--navy-ink);
  font-variant-numeric: tabular-nums;
  align-self: flex-end;
}

.duecard {
  border-left: 4px solid var(--crimson);
  margin-bottom: 1.25rem;
}

.checkline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  font-weight: 600;
  color: var(--navy-ink);
}

.checkline input {
  width: 1.15rem;
  height: 1.15rem;
}

/* --- The Daily Journal (M8) --------------------------------------------- */

.daynav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}

.journalhalf {
  border-left: 4px solid var(--navy);
}

.journalhalf--home {
  border-left-color: var(--crimson);
}

/* No school record is a FACT, not a failing — grey, never red. It must simply
   never be mistaken for attendance. */
.noschool {
  padding: 0.8rem 1rem;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  color: var(--text-muted);
  font-style: italic;
  margin: 0;
}

.conduct {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.conduct__item {
  font-size: 0.8rem;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-sunk);
}

.conduct__item--ok {
  background: var(--ok-bg);
  color: var(--ok);
  border-color: transparent;
}

/* Something for the family to notice, not a punishment. Amber. */
.conduct__item--note {
  background: var(--hold-bg);
  color: var(--hold);
  border-color: transparent;
}

.conductgrid {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.conductgrid__row {
  display: flex;
  align-items: center;
  gap: 1rem;
  justify-content: space-between;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.conductgrid__label {
  font-weight: 600;
  color: var(--navy-ink);
  font-size: 0.92rem;
}

.conductgrid__choices ul,
.prayers__choices ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 0.9rem;
}

.conductgrid__choices label,
.prayers__choices label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.88rem;
  cursor: pointer;
}

.thread {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.thread__item {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
  border-left: 3px solid var(--navy);
}

.thread__item--parent {
  border-left-color: var(--crimson);
  background: #fdf6f6;
}

.thread__who {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--navy-ink);
  margin-bottom: 0.2rem;
}

.thread__body {
  font-size: 0.94rem;
}

.prayers {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

.prayers__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.prayers__name {
  font-weight: 600;
  color: var(--navy-ink);
  min-width: 5rem;
}

/* Position and target side by side — never a deficit, never in red. */
.pace {
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.pace__figure {
  min-width: 8rem;
}

.pace__n {
  display: block;
  font-size: 2rem;
  font-weight: 650;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.pace__figure--target .pace__n {
  color: var(--text-faint);
}

.pace__label {
  display: block;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.childcard {
  display: block;
  text-decoration: none;
  color: inherit;
}

.childcard:hover {
  box-shadow: var(--shadow-lift);
  color: inherit;
}

/* --- Footer ------------------------------------------------------------ */

.footer {
  border-top: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-faint);
  font-size: 0.82rem;
  padding-block: 1rem;
}

.footer__inner {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  flex-wrap: wrap;
}

.footer__legal {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.76rem;
  color: var(--text-faint);
}

.login__legal {
  text-align: center;
  font-size: 0.72rem;
  color: var(--text-faint);
  margin: 1.25rem 0 0;
}

/* --- Error pages ------------------------------------------------------- */

.notice {
  text-align: center;
  padding-block: 3rem;
}

.notice__code {
  font-family: var(--font-numeric);
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--crimson);
  line-height: 1;
}

/* --- Signing in with a second factor ------------------------------------ */

.login__heading {
  font-size: 1.15rem;
  margin: 0 0 0.5rem;
}

.login__lede {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 0 0 1.25rem;
}

.authform {
  margin-top: 1rem;
}

/* A code is read off one screen and typed into another, digit by digit, often
   by someone holding a phone in their other hand. Wide tracking and a
   monospaced face make it possible to keep your place. */
.authform input[name="code"] {
  font-family: var(--font-numeric);
  font-size: 1.4rem;
  letter-spacing: 0.35em;
  text-align: center;
  padding-block: 0.7rem;
}

.otherways {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  text-align: center;
}

.otherways .linkbtn[disabled] {
  color: var(--text-faint);
  cursor: default;
}

/* --- Choosing a factor --------------------------------------------------- */

.factorlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.factor {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: 0.9rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  text-align: left;
}

/* An enrolled factor is the reassuring state, so it gets the green — this is
   the one screen where a person is checking that they are protected. */
.factor--on {
  border-color: #bfe0d1;
  background: var(--ok-bg);
}

.factor__body {
  display: grid;
  gap: 0.2rem;
}

.factor__state {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ok);
}

.factor--backup {
  margin-top: 0.75rem;
}

.factor__act {
  display: grid;
  gap: 0.35rem;
  justify-items: end;
  flex-shrink: 0;
}

/* --- The QR code --------------------------------------------------------- */

.qr {
  margin: 1rem auto;
  width: min(13rem, 60vw);
}

.qr svg {
  display: block;
  width: 100%;
  height: auto;
}

.qr__manual summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--navy);
}

/* Typed by hand from a screen, so it breaks into readable chunks rather than
   running off the edge of a phone. */
.qr__secret {
  font-family: var(--font-numeric);
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  word-break: break-all;
  background: var(--surface-sunk);
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  margin: 0.5rem 0 0;
}

/* --- Backup codes -------------------------------------------------------- */

.codegrid {
  list-style: none;
  margin: 1.25rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.4rem;
}

.codegrid li {
  font-family: var(--font-numeric);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-align: center;
  padding: 0.45rem 0.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-sunk);
}

/* Named apart from .check, which is the Appendix verification checklist and
   carries a counter. */
.confirmbox {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.steps--compact li {
  font-size: 0.9rem;
}

/* An action that is safe but sounds alarming. Set apart from the ordinary
   fields above it, and carrying its own explanation, so an administrator
   reads what it does before deciding. */
.dangerzone {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.dangerzone .hint {
  display: block;
  max-width: 34rem;
}

@media print {
  /* Printing the backup codes is the recommended way to keep them, so the
     page furniture goes and only the codes remain. */
  .login__crest,
  .login__help,
  .authform,
  .hint {
    display: none;
  }

  .codegrid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* --- The school calendar ----------------------------------------------- */

/* Four shapes of day, and they must be told apart at a glance. Closed is the
   quietest — an empty page reads as "nothing here" without needing a colour.
   The curriculum day is the one that matters most, so it is the one tinted. */
.monthgrid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 3px;
  table-layout: fixed;
}

.monthgrid th {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 0.35rem;
}

.monthgrid td {
  padding: 0;
  vertical-align: top;
}

.cday {
  display: block;
  position: relative;
  min-height: 3.6rem;
  padding: 0.35rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.cday__n {
  font-family: var(--font-numeric);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-muted);
}

/* The rounds figure is the fact a Principal is scanning for, so it carries
   the weight — the date number is only there to find the square. */
.cday__rounds {
  position: absolute;
  top: 0.3rem;
  right: 0.4rem;
  font-family: var(--font-numeric);
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--navy);
}

.cday__label {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.66rem;
  line-height: 1.25;
  font-weight: 600;
  color: var(--crimson);
  overflow-wrap: anywhere;
}

.cday--curriculum {
  background: #f0eff8;
  border-color: #d8d6ea;
}

.cday--no_hifz {
  background: var(--hold-bg);
  border-color: #ecdcbb;
}

.cday--no_hifz .cday__label { color: var(--hold); }

.cday--closed {
  background: var(--surface-sunk);
  border-style: dashed;
}

.cday--closed .cday__n { color: var(--text-faint); }

/* Days spilling in from the neighbouring months are context, not content. */
.cday--outside {
  opacity: 0.4;
}

.cday--today {
  outline: 2px solid var(--crimson);
  outline-offset: 1px;
}

.sw--full { background: var(--surface); border: 1.5px solid var(--border-strong); }
.sw--curriculum { background: #f0eff8; border: 1.5px solid #b9b5d8; }
.sw--nohifz { background: var(--hold-bg); border: 1.5px solid var(--hold); }
.sw--closed { background: var(--surface-sunk); border: 1.5px dashed var(--border-strong); }

/* The shape of the day, called out where a teacher is about to record. */
.daynote {
  margin: 0.4rem 0 0;
  padding: 0.35rem 0.6rem;
  border-left: 3px solid var(--border-strong);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-sunk);
  font-size: 0.84rem;
  color: var(--text-muted);
}

.daynote--curriculum {
  background: #f0eff8;
  border-left-color: var(--navy-soft);
}

.daynote--no_hifz,
.daynote--closed {
  background: var(--hold-bg);
  border-left-color: var(--hold);
  color: var(--hold);
}

/* --- Small screens ----------------------------------------------------- */

@media (max-width: 46rem) {
  .masthead__inner {
    row-gap: 0.35rem;
  }

  /* Seven columns will not fit, so the grid scrolls sideways rather than
     crushing each day into an unreadable sliver. */
  .monthgrid {
    min-width: 34rem;
  }
}

@media (max-width: 30rem) {
  .masthead__inner {
    gap: 0.65rem;
  }

  .masthead__crest {
    height: 38px;
  }

  .masthead__name {
    font-size: 0.92rem;
  }

  /* The panel is wider than a small phone allows on the right edge, so pin it
     to the viewport rather than to the trigger. */
  .usermenu__panel {
    right: -0.5rem;
    min-width: 14rem;
    max-width: calc(100vw - 2rem);
  }

  .card {
    padding: 1.15rem;
  }
}

/* --- Attendance (R3) ---------------------------------------------------
   One mark per student per day. Absence is amber, not red: a child who is
   away is not a failure, and red here would read as an accusation. Leave is
   authorised and quieter still — it must never look like absence, because
   the school does not count the two together. */

.attend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 0.9rem;
  margin-top: 0.9rem;
  padding: 0.7rem 0.85rem;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
}

.attend__label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  margin-right: 0.2rem;
}

.attend__hint {
  margin: 0;
  font-size: 0.86rem;
  color: var(--text-muted);
}

.attend .btn {
  margin-left: auto;
}

/* The letter the school writes, shown where a teacher scans the roster. */
.attendmark {
  display: inline-grid;
  place-items: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.35rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-numeric);
  font-size: 0.74rem;
  font-weight: 700;
  background: var(--surface-sunk);
  color: var(--text-muted);
}

.attendmark--present {
  background: var(--ok-bg);
  color: var(--ok);
}

.attendmark--late {
  background: var(--hold-bg);
  color: var(--hold);
}

.attendmark--absent {
  background: var(--hold-bg);
  color: var(--hold);
  border: 1.5px solid var(--hold);
}

.attendmark--leave {
  background: var(--surface-sunk);
  color: var(--navy-soft);
  border: 1.5px dashed var(--border-strong);
}

/* Away students stay on the roster, legibly quiet rather than hidden. */
.roster__row--away .roster__who {
  opacity: 0.7;
}

/* --- The register (R3) -------------------------------------------------
   Called once at assembly, for everyone, on one page. The four codes sit as
   radios across each row so a teacher reads down a column the way they read
   down the sheet's first column. */

.daypick {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding: 0.75rem 0.9rem;
}

.daypick label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}

.daypick input[type="date"] {
  font: inherit;
  padding: 0.35rem 0.5rem;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}

.register th.num,
.register td.num {
  text-align: center;
  width: 5.5rem;
}

.register__row--away {
  background: var(--hold-bg);
}

.register__pick {
  display: grid;
  place-items: center;
  gap: 0.15rem;
  cursor: pointer;
  padding: 0.2rem 0;
}

.register__pick input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--navy);
  cursor: pointer;
}

/* The column heading already names the code; this repeats it only for
   screens narrow enough to lose the header from view. */
.register__picklabel {
  font-size: 0.68rem;
  color: var(--text-faint);
}

@media (min-width: 45rem) {
  .register__picklabel {
    display: none;
  }
}

.register__batch {
  color: var(--text-muted);
  font-size: 0.86rem;
}

/* --- The navigation rail -----------------------------------------------
   One shape at every level: sections, then the current section's pages, then
   whatever the page is about. It is the same rail on the roster and on a
   single round, so a user never has to learn where the options went. */

.shell {
  display: grid;
  grid-template-columns: 14.5rem minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

.shell__content {
  min-width: 0;
}

.sidebar {
  position: sticky;
  top: 1rem;
  display: grid;
  gap: 1.4rem;
  padding: 1rem 0.9rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.sidebar__title {
  margin: 0 0 0.4rem 0.55rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  /* A student's name can be long; it must not push the rail wider. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.1rem;
}

.sidebar__item {
  display: block;
  padding: 0.42rem 0.55rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
  border-left: 3px solid transparent;
}

.sidebar__item:hover {
  background: var(--surface-sunk);
  color: var(--navy);
}

/* Where you are, stated rather than implied. The old subnav had no active
   state at all, which is half of not knowing where things are. */
.sidebar__item.is-active {
  background: var(--surface-sunk);
  border-left-color: var(--crimson);
  color: var(--navy);
}

/* On a phone the rail becomes a strip above the page: same order, same
   grouping, scrolled sideways rather than hidden behind a menu button. */
@media (max-width: 60rem) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
  }

  .sidebar {
    position: static;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    padding: 0.8rem;
  }

  .sidebar__group {
    min-width: 0;
  }

  .sidebar__title {
    margin-left: 0;
  }

  .sidebar__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
  }

  .sidebar__item {
    border-left: 0;
    border-bottom: 3px solid transparent;
  }

  .sidebar__item.is-active {
    border-left: 0;
    border-bottom-color: var(--crimson);
  }
}

/* --- The register: batch picker, and per-row save state ----------------- */

.daypick__field {
  display: grid;
  gap: 0.2rem;
}

.daypick select {
  font: inherit;
  padding: 0.35rem 0.5rem;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  max-width: 16rem;
}

.register__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.register__state {
  width: 7rem;
  text-align: center;
}

/* Not yet called is a real state and must not resemble present. */
.register__row--uncalled td {
  background: var(--surface-sunk);
}

.register__pending {
  font-size: 0.78rem;
  color: var(--text-faint);
}

.register__saving {
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* A mark that did NOT save has to be impossible to mistake for one that did.
   This is the only red on the page — every attendance code is amber or green,
   because a child being away is not an error. A lost mark is. */
.register__failed {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--danger);
}

.register__row--failed td {
  background: var(--danger-bg);
}

.register__batch {
  display: block;
  color: var(--text-faint);
  font-size: 0.78rem;
}

/* --- The school's student number (R5) ----------------------------------
   Monospaced so a column of them lines up and a transposed digit is visible:
   H22139 and H23150 are two different boys, both called Tamseel. */

.idnum {
  font-family: var(--font-numeric);
  font-size: 0.86rem;
  letter-spacing: 0.02em;
  color: var(--text-muted);
}

.entryhead__id {
  margin: 0.1rem 0 0;
}

/* --- The register as a table -------------------------------------------
   The school has read these figures as a spreadsheet for years, so this is
   dense, right-aligned, monospaced in the figures, with a total row at the
   bottom and a sticky header — the habits of the sheet they already know,
   rather than a different way of seeing the same numbers. */

.sheet {
  font-size: 0.88rem;
}

.sheet thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-sunk);
  vertical-align: bottom;
  padding: 0.45rem 0.5rem;
  white-space: nowrap;
}

.sheet__sort {
  display: inline-block;
  text-decoration: none;
  color: var(--navy);
  font-weight: 700;
}

.sheet__sort:hover {
  text-decoration: underline;
}

.sheet__arrow {
  margin-left: 0.2rem;
  font-size: 0.66rem;
  color: var(--crimson);
}

/* The school's own definition, under the heading it belongs to: people do ask
   what Parts means, and the answer belongs where the question is. */
.sheet__note {
  display: block;
  font-size: 0.66rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-faint);
}

.sheet tbody td {
  padding: 0.35rem 0.5rem;
  white-space: nowrap;
}

.sheet tbody tr:nth-child(even) td {
  background: rgb(29 24 82 / 2.5%);
}

.sheet td.num,
.sheet th.num {
  font-family: var(--font-numeric);
  text-align: right;
}

.sheet th.num .sheet__note {
  text-align: right;
}

/* The sorted column stays visible as the eye travels down it. */
.sheet th.is-sorted {
  background: var(--hold-bg);
}

.sheet td.is-sorted {
  background: rgb(138 90 0 / 6%);
  font-weight: 600;
}

.sheet__name {
  position: sticky;
  left: 0;
  background: var(--surface);
  font-weight: 600;
}

.sheet tbody tr:nth-child(even) .sheet__name {
  background: #f7f7fb;
}

.sheet__name a {
  text-decoration: none;
  color: var(--navy);
}

.sheet__name a:hover {
  text-decoration: underline;
}

/* Month End, in their words: the row they always read last. */
.sheet tfoot td {
  position: sticky;
  bottom: 0;
  background: var(--surface-sunk);
  border-top: 2px solid var(--border-strong);
  font-weight: 700;
  padding: 0.45rem 0.5rem;
  white-space: nowrap;
}

.periodpick {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-bottom: 0.9rem;
}

.periodpick__item {
  padding: 0.32rem 0.7rem;
  border: 1.5px solid var(--border-strong);
  border-radius: 999px;
  text-decoration: none;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--surface);
}

.periodpick__item:hover {
  border-color: var(--navy-soft);
  color: var(--text);
}

.periodpick__item.is-active {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--on-dark);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Above the table: groups, and the columns one person keeps ----------
   Twenty-one columns will not fit on a screen. They are grouped the way the
   questions come, and each teacher can hide what they never look at. */

.deck {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.9rem;
}

.deck__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  border-bottom: 2px solid var(--border);
  flex: 1 1 auto;
}

.deck__tab {
  padding: 0.42rem 0.85rem;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
}

.deck__tab:hover {
  color: var(--navy);
}

.deck__tab.is-active {
  color: var(--navy);
  border-bottom-color: var(--crimson);
}

.deck__columns {
  position: relative;
  flex: none;
}

.deck__button {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.38rem 0.8rem;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
}

/* The default disclosure triangle sits oddly inside a button shape. */
.deck__button::-webkit-details-marker {
  display: none;
}

.deck__button:hover {
  border-color: var(--navy-soft);
  color: var(--navy);
}

.deck__columns[open] .deck__button {
  border-color: var(--navy);
  color: var(--navy);
}

.deck__count {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--crimson);
}

.deck__panel {
  position: absolute;
  right: 0;
  z-index: 5;
  margin-top: 0.35rem;
  padding: 0.85rem;
  width: 21rem;
  max-width: calc(100vw - 2rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
}

.deck__list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.15rem 0.6rem;
}

.deck__check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.86rem;
  cursor: pointer;
}

.deck__check input {
  accent-color: var(--navy);
}

.deck__check input:disabled + span {
  color: var(--text-faint);
}

@media (max-width: 46rem) {
  .deck__panel {
    position: static;
    width: auto;
  }
}

/* --- Which day is being recorded (R4) -----------------------------------
   A back-dated entry is never marked as late in the record — the school asked
   for that. This strip is a different thing: it says which day you are on, so
   Tuesday's work does not land on Thursday. */

.daybar {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding: 0.55rem 0.8rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.daybar label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}

.daybar input[type="date"] {
  font: inherit;
  padding: 0.3rem 0.5rem;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}

/* Amber, not red: filling the register in from paper days later is the normal
   way this school works, not a mistake being made. */
.daybar--past {
  background: var(--hold-bg);
  border-color: var(--hold);
}

.daybar__note {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--hold);
}

/* --- The register grid (R15) --------------------------------------------
   Their sheet with the axes swapped: a name per row, a day per column, the
   month's totals on the right. Dense on purpose — the point is seeing the
   whole month at once, which is what a page per student cannot do. */

.gridsheet {
  font-size: 0.8rem;
  border-collapse: separate;
  border-spacing: 0;
}

.gridsheet th,
.gridsheet td {
  padding: 0;
  border-bottom: 1px solid var(--border);
}

.gridsheet__name {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  padding: 0.3rem 0.6rem 0.3rem 0.2rem;
  white-space: nowrap;
  font-weight: 600;
  border-right: 1px solid var(--border);
}

.gridsheet__name a {
  color: var(--navy);
  text-decoration: none;
}

.gridsheet__name a:hover {
  text-decoration: underline;
}

.gridsheet thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface-sunk);
  font-size: 0.7rem;
  text-align: center;
  padding: 0.25rem 0.1rem;
  min-width: 1.9rem;
}

.gridsheet__weekday {
  display: block;
  font-size: 0.6rem;
  font-weight: 400;
  color: var(--text-faint);
}

.gridsheet__cell {
  text-align: center;
  font-family: var(--font-numeric);
  min-width: 1.9rem;
}

/* The whole cell is the target, not just the character in it: a teacher
   picking out one day of one child should not have to aim. */
.gridsheet__cell a {
  display: block;
  padding: 0.28rem 0.15rem;
  color: var(--text);
  text-decoration: none;
  min-height: 1.5rem;
}

.gridsheet__cell a:hover {
  outline: 2px solid var(--navy);
  outline-offset: -2px;
}

/* Days the school is shut are not gaps in the record. */
.gridsheet .is-weekend,
.gridsheet .is-closed {
  background: var(--surface-sunk);
}

.gridsheet__total {
  background: rgb(29 24 82 / 3%);
  font-weight: 600;
  padding: 0.28rem 0.5rem;
  border-left: 1px solid var(--border);
  white-space: nowrap;
}

.gridsheet tfoot td {
  position: sticky;
  bottom: 0;
  background: var(--surface-sunk);
  border-top: 2px solid var(--border-strong);
  font-weight: 700;
}

/* The attendance codes, in the same colours as everywhere else: absence is
   amber, never red — a child being away is not a failure. */
.gridsheet .tone--present a { color: var(--ok); }
.gridsheet .tone--late a { color: var(--hold); font-weight: 700; }
.gridsheet .tone--absent { background: var(--hold-bg); }
.gridsheet .tone--absent a { color: var(--hold); font-weight: 700; }
.gridsheet .tone--leave a { color: var(--navy-soft); }
.gridsheet .tone--repeat { background: var(--hold-bg); }
.gridsheet .tone--test a { color: var(--navy); font-weight: 700; }
.gridsheet .tone--low a { color: var(--hold); }

/* --- Where he left off (2026-08-27) ------------------------------------
   The school is explicit that whatever a student could not do stays in his
   record and he resumes exactly there. Amber, not red: being held at the same
   Nisf is the method working, not a fault. */

.lastplace {
  border-left: 4px solid var(--hold);
  background: var(--hold-bg);
}

.lastplace__title {
  margin-top: 0;
  font-size: 1rem;
  color: var(--hold);
}

.lastplace__facts {
  margin-bottom: 0.75rem;
}

/* Which year of the course a student is in, and the guide for it. A quiet
   line under the name: context, never a verdict — the school is emphatic that
   pace is not a mark. */
.yearline {
  margin: -0.4rem 0 1rem;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.yearline strong {
  color: var(--navy-ink);
  font-variant-numeric: tabular-nums;
}

/* Adding a fourth round: all that is left of planning a day. A select and a
   button beside the day's heading, not a screen of its own. */
.addround {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.addround select {
  padding: 0.35rem 0.5rem;
  font-size: 0.88rem;
}

.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;
}

/* The half-Nisf lock, on the day rather than a screen of its own. */
.quarterlock {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.quarterlock form {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* "Before this year" — a question with two answers, the second of which asks
   for a page and a line. */
.choice {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.35rem 0;
  cursor: pointer;
}

.choice input {
  width: auto;
  margin: 0;
}

.startpos[hidden] {
  display: none;
}

.startpos {
  margin-top: 0.5rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--border);
}

/* What the entered page and line work out to, said back before saving. Quiet
   but not a footnote: it is the thing that catches a mistyped page. */
.echo {
  margin: 0.6rem 0 0;
  padding: 0.6rem 0.75rem;
  background: var(--ok-bg);
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  line-height: 1.5;
}
