:root {
  --navy: #b3492f;
  --navy-2: #5c2519;
  --sky: #1f7a6c;
  --sky-soft: #e3f2ee;
  --gold: #dd9c2e;
  --cream: #faf4ec;
  --white: #ffffff;
  --ink: #2b1e17;
  --muted: #7d6d61;
  --line: #e8ddd2;
  --soft: #f7f1e8;
  --shadow: 0 20px 55px rgba(92, 37, 25, .14);
  --radius: 10px;

  --mem: #1f7a6c;
  --mem-soft: #e3f2ee;
  --work: #b45309;
  --work-soft: #fef3c7;
  --danger: #b91c1c;

  /* Used only for the "goal met" celebration — a deliberately different, cooler-toned
     pair from the site's warm terracotta/teal palette, picked for this boys' section. */
  --boy-blue: #1d4ed8;
  --boy-blue-2: #38bdf8;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font: 16px/1.5 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--soft);
}
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
h1, h2, h3 { font-family: Georgia, "Times New Roman", serif; }
.hidden { display: none !important; }

/* ---------------------------------------------------------------- topbar */
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 16px;
  padding: 14px 24px;
  background: var(--white);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; text-decoration: none; color: inherit; }
.brand-mark {
  width: 40px; height: 40px; flex: none; border-radius: 8px;
  background: linear-gradient(145deg, var(--sky), var(--navy)); color: #fff;
  display: grid; place-items: center; font-size: 19px;
  box-shadow: 0 10px 24px rgba(31,122,108,.24);
}
.brand-mark.lg { width: 56px; height: 56px; font-size: 26px; margin: 0 auto 18px; }
.brand-mark .tally-mark { width: 100%; height: 100%; display: block; }
.brand-copy { display: flex; flex-direction: column; line-height: 1.25; }
.brand-copy strong { font-size: 15px; font-family: Georgia, serif; }
.brand-copy small { font-size: 12px; color: var(--muted); }
.topbar-spacer { flex: 1; }
.who { font-size: 13px; color: var(--muted); }

.settings-toggle {
  display: none; flex: none; width: 34px; height: 34px; border-radius: 6px;
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  align-items: center; justify-content: center;
}
.settings-toggle:hover { background: var(--soft); color: var(--ink); }
.topbar-settings { display: flex; align-items: center; gap: 16px; }

@media (max-width: 640px) {
  .settings-toggle { display: inline-flex; }
  .topbar-settings {
    display: none; position: absolute; top: calc(100% + 6px); right: 16px;
    flex-direction: column; align-items: stretch; gap: 10px;
    background: var(--white); border: 1px solid var(--line); border-radius: 8px;
    box-shadow: var(--shadow); padding: 14px; min-width: 190px; z-index: 40;
  }
  .topbar-settings.open { display: flex; }
  .topbar-settings .who { word-break: break-all; font-size: 12px; }
  .topbar-settings .lang { align-self: flex-start; }
}

.lang {
  position: relative; display: inline-flex; align-items: center;
  background: var(--soft); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px; user-select: none;
}
.lang input { position: absolute; opacity: 0; pointer-events: none; }
.lang-knob {
  position: absolute; top: 3px; left: 3px;
  width: calc(50% - 3px); height: calc(100% - 6px);
  background: var(--navy); border-radius: 999px;
  transition: transform .18s ease;
}
.lang.en .lang-knob { transform: translateX(100%); }
.lang label {
  position: relative; z-index: 1;
  width: 48px; text-align: center; padding: 5px 0;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  color: var(--muted); cursor: pointer; border-radius: 999px;
}
.lang.tr label[for="langTr"], .lang.en label[for="langEn"] { color: #fff; }

/* ------------------------------------------------------------ sign-in gate */
.gate { min-height: calc(100vh - 70px); display: grid; place-items: center; padding: 24px; }
.gate-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); max-width: 420px; width: 100%; padding: 36px 32px;
  text-align: center;
}
.gate-card h1 { margin: 0 0 10px; font-size: 22px; }
.gate-card p { color: var(--muted); margin: 0 0 22px; font-size: 14px; }
#gsiButton { display: flex; justify-content: center; }
/* Home-screen install affordances (install.js) — a quiet secondary action under the
   sign-in button, plus the numbered iPhone steps shown in a modal. */
.gate-install { display: block; margin: 14px auto 0; }
/* Phones get the banner below instead of a topbar button — the collapsed settings
   menu is already crowded there. */
@media (max-width: 640px) {
  .topbar-settings .install-btn { display: none !important; }
}
.install-banner {
  position: fixed; left: 12px; right: 12px; z-index: 29; /* top set by install.js */
  max-width: 560px; margin: 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 10px 12px 14px; border-radius: 12px;
  background: linear-gradient(120deg, #dc6a1f, var(--navy));
  color: #fff; box-shadow: 0 14px 34px rgba(179, 73, 47, .35);
  cursor: pointer; animation: installBannerIn .35s ease-out;
}
@keyframes installBannerIn {
  from { transform: translateY(-16px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.install-banner-icon {
  flex: none; width: 36px; height: 36px; border-radius: 8px;
  background: linear-gradient(145deg, var(--sky), var(--navy));
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .55);
}
.install-banner-icon svg { width: 100%; height: 100%; display: block; }
.install-banner-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.install-banner-text strong { font-size: 15px; }
.install-banner-text small { font-size: 12.5px; opacity: .9; }
.install-banner-close {
  flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .18); color: #fff; font-size: 20px; line-height: 1;
}
.install-banner-close:hover { background: rgba(255, 255, 255, .3); }
.install-steps { margin: 0; padding-left: 20px; line-height: 1.6; font-size: 14px; }
.install-steps li + li { margin-top: 6px; }
.install-note { margin: 14px 0 0; font-size: 13px; color: var(--muted); }
.gate-msg { margin-top: 16px !important; color: var(--danger) !important; font-size: 13px !important; }
#btnBackToNav { font-weight: 700; color: var(--navy); flex: none; }

.nav-picker { margin-top: 20px; text-align: left; }
.nav-crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; margin-bottom: 12px; }
.nav-crumbs button { border: 0; background: none; padding: 2px 4px; font-weight: 700; color: var(--navy); cursor: pointer; font-size: 13px; }
.nav-crumbs button:disabled { color: var(--ink); cursor: default; }
.nav-crumbs .sep { color: var(--muted); }
/* Pushes the section-level add-people control to the far right of the crumbs row,
   regardless of how long the breadcrumb trail itself is. */
.section-add-wrap { margin-left: auto; flex: none; }

.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 1px solid var(--line); background: #fff; border-radius: 6px;
  padding: 11px 14px; margin-bottom: 8px;
}
.nav-item:hover { border-color: var(--sky); }
.nav-item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; cursor: pointer; }
.nav-item-main:hover { color: var(--sky); }
.nav-item-main strong { font-size: 14px; }
.nav-item-main small { color: var(--muted); font-size: 12px; }
.nav-item-acts { flex: none; display: flex; align-items: center; gap: 2px; }
/* Minimalist icon-only row actions (add/delete) — no border/box, just a glyph that
   picks up a soft background on hover, same low-profile language as .pencil-btn. */
.icon-only-btn {
  border: 0; background: transparent; padding: 6px; border-radius: 6px;
  color: var(--muted); display: inline-flex; align-items: center; justify-content: center;
}
.icon-only-btn:hover { background: var(--soft); color: var(--ink); }
.icon-only-btn.danger { color: var(--danger); }
.icon-only-btn.danger:hover { background: #fdecec; }
.nav-create-btn { width: 100%; margin-top: 4px; }
.nav-empty { color: var(--muted); font-size: 13px; padding: 10px 2px; }

/* Section-view mentor roster — a compact card (echoes .card's head/body split) rather
   than bare unstyled rows, so it reads as its own roster rather than stray text under
   the breadcrumbs. */
.mentors-panel {
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 14px; overflow: hidden;
}
.mentors-panel + .mentors-panel { margin-top: 10px; }
.mentors-panel-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  border: 0; padding: 10px 14px; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); background: var(--soft);
  border-bottom: 1px solid var(--line);
}
.mentors-panel-head:hover { color: var(--ink); }
.mentors-panel-head .chevron { flex: none; display: inline-flex; transition: transform .15s ease; }
.mentors-panel-head .chevron.open { transform: rotate(180deg); }
.mentors-panel-body.hidden { display: none; }
.mentors-panel .nav-empty { padding: 12px 14px; }

/* Top-level sections list, super-admin only — public group pages that no section has
   claimed yet. Dashed border deliberately distinguishes these from real .nav-item rows. */
.missing-sites { margin-bottom: 14px; }
.missing-sites-head { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.missing-site-row {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  border: 1px dashed var(--line); background: transparent; border-radius: 6px;
  padding: 9px 14px; margin-bottom: 6px; color: var(--muted); text-align: left;
}
.missing-site-row:hover { border-color: var(--sky); color: var(--ink); }
.missing-site-row .missing-site-cta { flex: none; font-size: 12px; font-weight: 700; color: var(--sky); }

.mentor-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-bottom: 1px solid var(--line);
}
.mentor-row:last-child { border-bottom: 0; }
.mentor-row:hover { background: var(--soft); }
.mentor-email { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.avatar.sm { width: 24px; height: 24px; font-size: 11px; }

.gate-loading { margin-top: 20px; display: flex; align-items: center; justify-content: center; gap: 10px; color: var(--muted); font-size: 14px; }
.spinner {
  width: 18px; height: 18px; flex: none; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--navy);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ layout */
.wrap { display: grid; grid-template-columns: 300px 1fr; gap: 20px; padding: 20px; align-items: start; max-width: 1240px; margin: 0 auto; }
@media (max-width: 900px) { .wrap { grid-template-columns: 1fr; } }
/* A signed-in student gets only their own page — no roster rail beside it. */
.student-mode #appRoot { grid-template-columns: minmax(0, 900px); justify-content: center; }
.student-mode #appRoot > div:first-child { display: none; }
/* Single-column sibling of .wrap for the section/class dashboard — no left-rail
   sidebar to make room for, so the header card and chart tiles just stack full-width. */
.dashboard-wrap { display: flex; flex-direction: column; gap: 16px; padding: 20px; max-width: 1240px; margin: 0 auto; }

.card { background: var(--white); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); }
.card + .card { margin-top: 16px; }
.card-head { padding: 14px 16px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.card-head h2 { margin: 0; font-size: 15px; letter-spacing: .01em; font-family: Inter, sans-serif; font-weight: 700; }
.card-body { padding: 16px; }

.btn {
  border: 1px solid var(--line); background: #fff; border-radius: 6px;
  padding: 9px 14px; font-weight: 600; font-size: 14px; white-space: nowrap;
}
.btn:hover { background: var(--soft); }
.btn-primary { background: var(--navy); border-color: var(--navy); color: #fff; }
.btn-primary:hover { background: var(--navy-2); }
.btn-ghost { border-color: transparent; background: transparent; color: var(--muted); padding: 6px 8px; }
.btn-ghost:hover { background: var(--soft); color: var(--ink); }
.btn-sm { padding: 6px 10px; font-size: 13px; }
.btn-danger { color: var(--danger); }
/* Minimal "mobile app" field style for single-line inputs and selects — no box, just
   an underline, so the field reads as a line to fill in rather than a bordered box.
   The border stays 2px at rest (transparent-ish, just --line) so focus only changes its
   color, not its width — otherwise the field would visibly jump on focus/blur. */
input[type=text], input[type=number], select {
  width: 100%; border: 0; border-bottom: 2px solid var(--line); border-radius: 2px;
  padding: 7px 2px; background: transparent;
}
input[type=text]:focus, input[type=number]:focus, select:focus {
  outline: none; border-bottom-color: var(--sky);
}
input[type=text]::placeholder, input[type=number]::placeholder { color: var(--muted); opacity: .65; }
/* Same underline treatment as the single-line fields, not a boxed outline — reads as a
   multi-line "short answer" to fill in rather than a bordered textarea. min-height keeps
   it tall enough (a few lines) to feel like a short-answer box, not a one-liner. */
textarea {
  width: 100%; border: 0; border-bottom: 2px solid var(--line); border-radius: 2px;
  padding: 6px 2px; background: transparent; resize: vertical; min-height: 84px;
  font-size: 13px;
}
textarea:focus { outline: none; border-bottom-color: var(--sky); }
textarea::placeholder { color: var(--muted); opacity: .65; }
label.field { display: block; font-size: 13px; font-weight: 600; color: var(--muted); margin: 0 0 6px; }
.field-row + .field-row { margin-top: 12px; }

/* ---------------------------------------------------------------- students */
.student-list { max-height: 60vh; overflow: auto; }
.student {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 16px; border: 0; border-bottom: 1px solid var(--line);
  background: transparent; text-align: left;
}
.student:hover { background: var(--soft); }
.student.active { background: var(--sky-soft); box-shadow: inset 3px 0 0 var(--sky); }
.student .nm { flex: 1; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.student .ct { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.avatar {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  background: var(--sky-soft); color: var(--sky);
  display: grid; place-items: center; font-size: 13px; font-weight: 700;
}

/* ------------------------------------------------------------ detail */
.detail-head { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; padding: 18px 20px; }
.detail-head h2 { margin: 0; font-size: 24px; }
.detail-head .sub { font-size: 13px; color: var(--muted); font-family: Inter, sans-serif; }
.head-actions { margin-left: auto; display: flex; gap: 6px; }
.detail-name { flex: 1 1 260px; min-width: 0; }

.mini-goals { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; width: 100%; max-width: 560px; }
.mini-goals-label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; margin-bottom: 2px; }
.mini-goal { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.mg-label { flex: 0 0 50px; color: var(--muted); font-weight: 600; }
.mg-bar { flex: 1; height: 6px; border-radius: 999px; background: var(--soft); overflow: hidden; }
.mg-bar i { display: block; height: 100%; background: var(--mem); }
.mg-pct { flex: 0 0 36px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink); }
.mg-empty { flex: 1; color: var(--muted); }
.mini-goal.hit .mg-bar i {
  background-image: linear-gradient(90deg, var(--boy-blue), var(--boy-blue-2), var(--boy-blue));
  background-repeat: repeat-x; background-size: 320px 100%;
  animation: goalShimmer 4.2s linear infinite;
}
.mini-goal.hit .mg-pct { color: var(--boy-blue); }

.menu { position: relative; }
.menu-toggle {
  width: 32px; height: 32px; border-radius: 6px; border: 1px solid var(--line);
  background: #fff; color: var(--muted); display: flex; align-items: center; justify-content: center;
}
.menu-toggle:hover { background: var(--soft); color: var(--ink); }
.menu-dropdown {
  display: none; position: absolute; top: calc(100% + 6px); right: 0;
  background: var(--white); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: var(--shadow); padding: 6px; flex-direction: column; min-width: 140px; z-index: 30;
}
.menu-dropdown.open { display: flex; }
.menu-dropdown button {
  text-align: left; padding: 8px 10px; border-radius: 6px; border: 0;
  background: transparent; font-size: 13px; font-weight: 600; color: var(--ink);
}
.menu-dropdown button:hover { background: var(--soft); }
.menu-dropdown button.danger { color: var(--danger); }

.stats { display: flex; gap: 10px; flex-wrap: wrap; padding: 0 20px 16px; }
.stat { flex: 1 1 120px; border: 1px solid var(--line); border-radius: 6px; padding: 10px 12px; }
.stat b { display: block; font-size: 22px; line-height: 1.2; font-variant-numeric: tabular-nums; font-family: Inter, sans-serif; }
.stat span { font-size: 12px; color: var(--muted); }
.stat.mem b { color: var(--mem); }
.stat.work b { color: var(--work); }
.bar { height: 10px; border-radius: 999px; background: var(--soft); overflow: hidden; margin: 0 20px 18px; display: flex; }
.bar i { display: block; height: 100%; }
.bar .b-mem { background: var(--mem); }
.bar .b-work { background: var(--gold); }

.hw-meta { font-size: 12px; color: var(--muted); margin-top: 8px; }

.toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 6px 12px; font-size: 13px; font-weight: 600; color: var(--muted);
}
.chip.on { background: var(--navy); border-color: var(--navy); color: #fff; }

.group-title {
  padding: 12px 16px 6px; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
  background: var(--cream); border-bottom: 1px solid var(--line);
}
.item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.item:hover { background: var(--cream); }
.item .num {
  flex: none; min-width: 34px; height: 26px; padding: 0 6px; border-radius: 6px;
  background: var(--soft); color: var(--muted);
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.item .label { flex: 1; min-width: 120px; font-weight: 600; }
.item .label small { display: block; font-weight: 400; font-size: 12px; color: var(--muted); }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; flex: none; }
.seg button {
  border: 0; background: #fff; padding: 8px 12px; font-size: 13px; font-weight: 600;
  color: var(--muted); border-left: 1px solid var(--line); white-space: nowrap;
}
.seg button:first-child { border-left: 0; }
.seg button.on[data-s="not"] { background: var(--soft); color: var(--ink); }
.seg button.on[data-s="mem"] { background: var(--mem-soft); color: var(--mem); }
.seg button.on[data-s="work"] { background: var(--work-soft); color: var(--work); }
.item .rm { flex: none; }

.empty { padding: 40px 20px; text-align: center; color: var(--muted); }
.empty h3 { margin: 0 0 6px; color: var(--ink); font-size: 17px; }

/* ------------------------------------------------------------- goal tiles */
.goals-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px; margin-top: 16px;
}
.goal-tile {
  background: var(--white); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow); overflow: hidden;
}
.goal-tile.wide { grid-column: 1 / -1; }
.goal-head {
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  font-size: 13px; font-weight: 700; letter-spacing: .01em; color: var(--navy-2);
  background: var(--cream);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.goal-body { padding: 14px; }
.goal-body textarea { min-height: 64px; }
.goal-foot { display: flex; align-items: center; gap: 12px; margin-top: 10px; flex-wrap: wrap; }

.pending-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gold); flex: none; }
.pending-card { margin-top: 16px; }
.pending-row {
  display: grid; grid-template-columns: 44px repeat(3, minmax(0, 1fr)) auto;
  align-items: center; gap: 10px 16px; padding: 12px 16px;
}
.pending-row + .pending-row { border-top: 1px solid var(--line); }
.pending-week { font-size: 14px; color: var(--ink); }
.pending-stat { display: flex; flex-direction: column; min-width: 0; }
.pending-stat span { font-size: 11px; font-weight: 600; color: var(--muted); }
.pending-stat b { font-size: 16px; color: var(--ink); font-variant-numeric: tabular-nums; }
.pending-stat small { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pending-actions { display: flex; gap: 6px; justify-content: flex-end; }
/* Phone width: the three values keep their own row of columns, week label above and
   the buttons below instead of squeezing all five side by side. */
@media (max-width: 600px) {
  .pending-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pending-week, .pending-actions { grid-column: 1 / -1; }
}
.homework-readonly { white-space: pre-wrap; font-size: 14px; }

/* Student entry form — book name on its own full-width row, then the three weekly
   numbers in equal columns. */
.entry-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 16px; }
.entry-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.entry-field span { font-size: 11px; font-weight: 600; color: var(--muted); }
.entry-field input { width: 100%; }
.entry-field input[type="number"] { text-align: center; }
.entry-title { grid-column: 1 / -1; }

/* Left-to-right percentage fill bar used inside the Prayers/Book/Qur'an-pages tiles. */
.goal-progress-wrap { position: relative; margin-bottom: 12px; }
.goal-progress {
  position: relative; height: 32px; border-radius: 6px; background: var(--soft);
  overflow: hidden;
}
.goal-progress-fill {
  position: absolute; top: 0; left: 0; bottom: 0; background: var(--mem);
  transition: width .4s ease;
}
.goal-progress-label {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums;
  padding: 0 8px; text-align: center;
}
.goal-progress.empty .goal-progress-label { color: var(--muted); font-weight: 600; }
.goal-progress.hit .goal-progress-fill {
  background-image: linear-gradient(90deg, var(--boy-blue), var(--boy-blue-2), var(--boy-blue));
  background-repeat: repeat-x;
  background-size: 320px 100%;
  animation: goalShimmer 6.4s linear infinite;
}
.goal-progress.hit { box-shadow: 0 0 0 2px var(--boy-blue-2) inset; }
.goal-progress.hit .goal-progress-label { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
.goal-progress-badge {
  position: absolute; top: -9px; right: 8px; z-index: 2;
  background: var(--boy-blue); color: #fff; font-size: 10px; font-weight: 800;
  padding: 2px 8px; border-radius: 999px; box-shadow: 0 4px 10px rgba(29,78,216,.45);
  animation: goalBadgePop .35s ease;
}
/* Pixel-based (not percentage) shift, moved by exactly one background-size tile — this
   is what actually makes the loop seamless. A percentage-based background-position
   doesn't shift by the literal percentage of the element's own box; it's resolved
   against (box size - background size), which for an oversized, percentage-sized
   background produces a shift that doesn't land on a tile boundary — that mismatch is
   what made the old version visibly "jump"/restart at the end of every loop. */
@keyframes goalShimmer { from { background-position: 0 0; } to { background-position: -320px 0; } }
@keyframes goalBadgePop { 0% { transform: scale(.5); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }

/* Persistent goal value — a static display + a low-profile colorful pencil (no button
   chrome around it) that reveals a number input, rather than an always-editable box, so
   it reads as something you rarely change. Label sits left, pencil sits at the far right. */
.goal-edit { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.goal-edit .goal-display { color: var(--muted); font-weight: 600; font-size: 12px; }
.goal-edit .goal-display b { color: var(--ink); font-weight: 700; }
.pencil-btn {
  border: 0; background: transparent; padding: 4px; flex: none; border-radius: 6px;
  color: var(--sky); display: inline-flex; align-items: center; justify-content: center;
}
.pencil-btn:hover { color: var(--navy); background: var(--sky-soft); }
.goal-input-wrap input { width: 70px; padding: 4px 2px; font-size: 12px; }
.goal-input-wrap select { width: auto; padding: 4px 2px; font-size: 12px; }

/* flex-end (not center) bottom-aligns the label and the input's box. The input itself
   gets a shorter top padding and a taller bottom padding than the default field style —
   that pushes its typed value up closer to the label's own text height, leaving a clear
   gap before the underline, the way an underline would sit under the label text too. */
.week-value-field { display: flex; align-items: flex-end; gap: 10px; font-size: 12px; color: var(--muted); font-weight: 600; margin-bottom: 10px; }
/* line-height: 1 removes the inherited 1.5 half-leading (invisible on an empty field,
   but it pushes typed text noticeably higher above the underline once there's a glyph
   to actually compare against it). */
.week-value-field input { width: 70px; flex: none; padding: 2px 2px 2px; line-height: 1; text-align: center; }

.prev-week-toggle {
  border: 0; background: transparent; color: var(--sky); font-size: 12px; font-weight: 700;
  padding: 4px 0; text-decoration: underline; text-underline-offset: 2px;
}
.prev-week-toggle:hover { color: var(--navy); }
.prev-week-reveal { font-size: 12px; color: var(--muted); margin-top: 4px; }
.prev-week-reveal b { color: var(--ink); }

.surah-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px;
}
.surah-row:last-child { border-bottom: 0; }
.surah-row.cur { padding: 8px 0; }
.surah-lbl { color: var(--muted); font-weight: 600; flex: none; }
.surah-val { text-align: right; }
.surah-row.cur select { width: auto; max-width: 62%; padding: 6px 8px; font-size: 13px; }

/* History dashboard — hand-rolled SVG line charts, no charting library (consistent
   with this repo's no-bundler/no-CDN rule). */
.history-chart { width: 100%; height: 150px; }
.history-chart-line { fill: none; stroke: var(--mem); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.history-chart-goal { fill: none; stroke: var(--gold); stroke-width: 1; stroke-dasharray: 2 2; vector-effect: non-scaling-stroke; }
.history-chart-grid { stroke: var(--line); stroke-width: .6; vector-effect: non-scaling-stroke; }
.history-chart-dot { fill: var(--mem); }
.history-chart-axis-label { fill: var(--muted); font-size: 7px; font-family: Inter, sans-serif; }
.single-history-chart .history-chart-axis-label { font-size: 10px; }
.history-chart-multiline { fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.history-chart-multidot { stroke: var(--white); stroke-width: 1; vector-effect: non-scaling-stroke; }
.history-chart-multidot.is-hover { stroke: var(--ink); stroke-width: 1.5; }
/* Taller on desktop, where there's width to spare — the SVG's own viewBox keeps its
   aspect ratio (default preserveAspectRatio="xMidYMid meet"), so a taller box scales
   the whole drawing up proportionally rather than just stretching it. The dashboard's
   multi-line chart gets the bigger bump since it's a full-width .wide tile with many
   more lines/legend entries to tell apart, not squeezed next to sibling tiles the way
   the per-student History view's three charts are. */
@media (min-width: 901px) {
  .history-chart { height: 180px; }
  .multi-history-chart { height: 260px; }
}

.chart-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 2px 4px 10px; }
.chart-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.chart-legend-swatch { width: 9px; height: 9px; border-radius: 50%; flex: none; }

.chart-tooltip {
  position: fixed; z-index: 50; pointer-events: none;
  max-width: 240px; padding: 8px 10px;
  background: var(--white); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: var(--shadow); font-size: 12px; color: var(--muted);
}
.chart-tooltip-week { font-weight: 700; margin-bottom: 4px; }
.chart-tooltip-row { display: flex; align-items: center; gap: 6px; line-height: 1.6; }
.chart-tooltip-row b { color: var(--ink); }
.chart-tooltip-key { width: 12px; height: 2px; border-radius: 1px; flex: none; }

.surah-span { display: flex; width: 100%; border-radius: 6px; overflow: hidden; height: 38px; }
.surah-span-seg {
  background: var(--sky-soft); border-right: 1px solid var(--white);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; color: var(--navy-2); font-weight: 600; overflow: hidden; white-space: nowrap; padding: 0 2px;
}
.surah-span-seg:nth-child(even) { background: var(--soft); }
.surah-span-seg:last-child { border-right: 0; }

/* Dashboard-only memorization chart — every student's current surah position as a
   horizontal bar, surah list as the bottom axis (see charts.js's surahProgressChartHtml).
   The name column and the axis spacer share one fixed width so the track and its axis
   stay lined up underneath each other. */
.surah-progress-chart { width: 100%; }
.surah-progress-rows { display: flex; flex-direction: column; gap: 10px; }
/* .surah-progress-row and .surah-progress-axis are two separate flex rows (bars, then
   the shared axis below them) that have to land in identical columns for the ticks to
   actually sit under the bars they're ticks for — so the name column/axis spacer and
   the row/axis gap are each written as ONE rule covering both rows, not two rules that
   happen to repeat the same numbers (that's what let them drift out of sync below —
   the axis spacer never got the same mobile-width override the name column did, and
   the axis row never had a gap at all while the bar rows did). */
.surah-progress-row, .surah-progress-axis { display: flex; gap: 10px; }
.surah-progress-row { align-items: center; }
.surah-progress-axis { margin-top: 16px; }
.surah-progress-name, .surah-progress-axis-spacer { flex: 0 0 120px; max-width: 120px; }
.surah-progress-name {
  text-align: right; font-size: 12px; font-weight: 600;
  color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* margin-right pulls the track's own background groove in from the card's right edge
   (independent of how far any bar's fill reaches inside it) — on the axis track too,
   so its ticks stay aligned under the bars above them. */
.surah-progress-track, .surah-progress-axis-track { flex: 1; position: relative; height: 14px; margin-right: 60px; }
.surah-progress-track { background: var(--soft); border-radius: 4px; }
.surah-progress-fill {
  position: absolute; left: 0; top: 0; height: 100%; min-width: 2px;
  background: var(--mem); border-radius: 0 4px 4px 0;
}
.surah-progress-end {
  position: absolute; left: 100%; top: 50%; transform: translateY(-50%);
  margin-left: 6px; font-size: 11px; color: var(--muted); white-space: nowrap;
}
.surah-progress-axis-track { border-top: 1px solid var(--line); }
.surah-progress-tick {
  position: absolute; top: 4px; transform: translateX(-50%);
  font-size: 10px; color: var(--muted); white-space: nowrap;
}
/* A phone-width card has too little room to spare the same fixed 120px name column +
   60px right gutter desktop uses — that alone could eat most of the available width,
   squeezing the actual bars down to a sliver. Both shrink here; the per-bar end label
   is dropped entirely (see .surah-progress-end below), since there's no longer
   reliably enough margin room for it to sit past the bar without wrapping or
   overlapping the next row. */
@media (max-width: 640px) {
  .surah-progress-rows { gap: 3px; }
  .surah-progress-row, .surah-progress-axis { gap: 6px; }
  /* Shrunk well past the desktop 120px — a class-wide roster view only needs enough
     of the name to tell rows apart at a glance, so it gives most of its space back to
     the bars (the fixed-width column is still what was reading as oversized left
     padding for anyone with a short name, not literal CSS padding). The name column
     and its axis-row counterpart have to shrink together, or the axis ticks drift out
     from under the bars again exactly like before. */
  .surah-progress-name, .surah-progress-axis-spacer { flex-basis: 52px; max-width: 52px; }
  .surah-progress-name { font-size: 10px; }
  .surah-progress-track, .surah-progress-axis-track { margin-right: 8px; }
  /* The per-bar end label (each student's exact surah name+number) is the one thing
     cut on a small screen, not the shared bottom axis — the axis alone is enough for a
     rough left-to-right read of relative progress at a glance, and exact granularity
     is still there per student (their own surah tracker control, in class-view.js) if
     a mentor wants it precisely. */
  .surah-progress-end { display: none; }
}

/* ------------------------------------------------------------- modal */
.modal-back {
  position: fixed; inset: 0; background: rgba(43,30,23,.45);
  display: grid; place-items: center; padding: 16px; z-index: 60;
}
.modal {
  background: var(--white); border-radius: 8px; width: min(560px, 100%);
  max-height: 88vh; display: flex; flex-direction: column; box-shadow: 0 20px 50px rgba(43,30,23,.28);
}
.modal header { padding: 16px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; }
.modal header h3 { margin: 0; font-size: 17px; }
.modal .body { padding: 16px 18px; overflow: auto; }
.modal footer { padding: 14px 18px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }
.tabs { display: flex; gap: 6px; padding: 12px 18px 0; }
.tab { border: 1px solid var(--line); background: #fff; border-radius: 6px 6px 0 0; padding: 8px 14px; font-weight: 600; font-size: 14px; color: var(--muted); border-bottom-color: transparent; }
.tab.on { background: var(--sky-soft); color: var(--sky); border-color: var(--line); }
.pick { max-height: 46vh; overflow: auto; border: 1px solid var(--line); border-radius: 6px; }
.pick label { display: flex; gap: 10px; align-items: center; padding: 9px 12px; border-bottom: 1px solid var(--line); }
.pick label:hover { background: var(--cream); }
.pick input { width: 18px; height: 18px; accent-color: var(--navy); flex: none; }
.pick .num {
  flex: none; min-width: 34px; height: 24px; padding: 0 6px; border-radius: 6px;
  background: var(--soft); color: var(--muted);
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.hint { font-size: 13px; color: var(--muted); }

.toast {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%) translateY(20px);
  background: var(--ink); color: #fff; padding: 10px 16px; border-radius: 999px;
  font-size: 14px; opacity: 0; pointer-events: none; transition: all .18s ease; z-index: 80;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.err { background: var(--danger); }
