/* ═══════════════════════════════════════════════════════════
   Advantage — Student Progress Platform
   Cayman Prep & High School house style (CPHS)
   Every colour in the app comes from the tokens in :root below.
   Rules: gold is never text; no blue text on gold; white text only
   on CPHS Blue; no black or navy. Status colours always carry a word.
   ═══════════════════════════════════════════════════════════ */

:root {
  /* ── CPHS brand ── */
  --cphs-blue:   #0872BA;   /* headings, header bar, table headers, links, primary buttons */
  --cphs-gold:   #EAB621;   /* rules, dividers, header-row underline, small accents — never text */
  --text-grey:   #626262;   /* all body and table text */
  --blue-tint:   #F2F7FD;   /* alternate table rows, subtle panels */
  --grid-grey:   #E0E0E0;   /* borders, table cell borders */
  --white:       #FFFFFF;   /* page background, text on blue */

  /* ── Status (the one exception to the brand palette) ──
     Strong = text on white/tint, or a fill under white text. Bg = pale
     fill under strong or Text Grey text. All pairs ≥ 4.5:1. */
  --status-red:       #B42318;
  --status-red-bg:    #FDECEA;
  --status-amber:     #8A4B00;
  --status-amber-bg:  #FEF3DC;
  --status-green:     #17693B;
  --status-green-bg:  #E7F4EC;
  --status-red-mid:   #F8C9C4;  /* heatmap second step only */
  --status-red-deep:  #8E1B13;  /* text on --status-red-mid */

  /* ── Derived from the tokens above (no new hues) ── */
  --on-blue-rule: rgba(255,255,255,0.3);   /* hairlines on the blue bar */
  --focus-ring:   rgba(8,114,186,0.25);    /* CPHS Blue at 25% */
  --shadow-md:    0 4px 16px rgba(98,98,98,0.14);

  --font:        'Montserrat', Arial, sans-serif;

  --radius-sm:   4px;    /* buttons, badges, inputs */
  --radius-md:   4px;    /* cards, panels */
  --radius-lg:   4px;    /* tables, large panels */
}

/* ── RESET ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; scroll-behavior: smooth; }
body {
  font-family: var(--font);
  font-weight: 400;
  font-variant-emoji: text;
  background: var(--white);
  color: var(--text-grey);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
a { color: var(--cphs-blue); text-decoration: none; }
a:hover { color: var(--cphs-blue); text-decoration: underline; }
img { max-width: 100%; }
summary { cursor: pointer; color: var(--cphs-blue); }
/* Keyboard focus: a visible outline on everything interactive. */
a:focus-visible, button:focus-visible, summary:focus-visible,
select:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--cphs-blue);
  outline-offset: 2px;
}
.site-header a:focus-visible, .site-header button:focus-visible,
.hero-stat-headline a:focus-visible {
  outline-color: var(--white);
}

/* ── SITE HEADER ── */
.site-header {
  background: var(--cphs-blue);
  padding: 0;
  position: sticky;
  top: 0;
  z-index: 200;
}
.header-inner {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 24px;
  height: 68px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.header-brand { display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
/* The crest's wordmark is CPHS Blue on a transparent background, so it
   sits on a white plate to stay visible on the blue bar. The image
   itself is never cropped, recoloured or stretched. */
.school-logo { height: 42px; width: auto; background: var(--white); border-radius: 4px; padding: 2px 6px; }
.header-divider { width: 1px; height: 36px; background: var(--on-blue-rule); }
.app-name { display: flex; flex-direction: column; }
.app-name-main {
  font-family: var(--font);
  font-size: 20px;
  font-weight: 700;
  color: var(--white);
  line-height: 1.1;
}
.app-name-sub { font-size: 10px; color: var(--white); letter-spacing: 0.02em; }

.header-nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
/* Regular weight: bold Montserrat across six links overflows the bar
   at common laptop widths. The gold underline marks the active page. */
.nav-link {
  padding: 7px 10px;
  color: var(--white);
  font-size: 13px;
  font-weight: 400;
  border-radius: var(--radius-sm);
  transition: box-shadow 0.12s;
  white-space: nowrap;
}
.nav-link:hover { color: var(--white); text-decoration: none; box-shadow: inset 0 -2px 0 var(--white); }
.nav-link.active { color: var(--white); box-shadow: inset 0 -3px 0 var(--cphs-gold); }

.nav-user { display: flex; align-items: center; gap: 10px; margin-left: 12px; padding-left: 12px; border-left: 1px solid var(--on-blue-rule); }
.user-name { font-size: 13px; color: var(--white); }
/* One style for every role — the word distinguishes them. */
.user-role {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  padding: 2px 7px; border-radius: var(--radius-sm);
  background: var(--white); color: var(--cphs-blue);
}
.btn-logout { font-size: 12px; color: var(--white); padding: 5px 10px; border-radius: var(--radius-sm); border: 1px solid var(--on-blue-rule); }
.btn-logout:hover { color: var(--white); border-color: var(--white); text-decoration: none; }

/* ── MOBILE NAV: HAMBURGER + DRAWER ──
   Both are hidden on desktop; the media query below reveals them and
   hides the inline .header-nav. Markup lives in base.html. */
.nav-hamburger {
  display: none;            /* shown only on mobile (see @media) */
  margin-left: auto;
  width: 42px; height: 42px;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 5px;
  background: transparent; border: 1px solid var(--on-blue-rule);
  border-radius: var(--radius-sm); cursor: pointer;
}
.nav-hamburger span {
  display: block; width: 20px; height: 2px; border-radius: 2px;
  background: var(--white); transition: transform 0.15s, opacity 0.15s;
}
.mobile-drawer {
  display: none;            /* shown only on mobile when .open */
  background: var(--cphs-blue);
  border-top: 1px solid var(--on-blue-rule);
  padding: 8px 12px 14px;
}
.mobile-drawer-links { display: flex; flex-direction: column; gap: 2px; }
.mobile-drawer .nav-link {
  display: block; padding: 13px 12px; font-size: 16px;
  color: var(--white); border-radius: var(--radius-sm);
}
.mobile-drawer .nav-link.active { color: var(--white); box-shadow: inset 4px 0 0 var(--cphs-gold); }
.mobile-drawer-user {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 8px; padding: 12px 8px 4px;
  border-top: 1px solid var(--on-blue-rule);
}
.mobile-drawer .md-identity { display: flex; align-items: center; gap: 8px; }
.mobile-drawer .md-name { font-size: 14px; font-weight: 700; color: var(--white); }

/* ── FLASH MESSAGES ── */
.flash-container { padding: 12px 24px 0; max-width: 1400px; margin: 0 auto; width: 100%; }
.flash {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 16px; border-radius: var(--radius-sm);
  font-size: 14px; margin-bottom: 8px;
  border: 1px solid var(--grid-grey);
}
.flash-success { background: var(--status-green-bg); color: var(--status-green); }
.flash-danger  { background: var(--status-red-bg);   color: var(--status-red); }
.flash-warning { background: var(--status-amber-bg); color: var(--status-amber); }
.flash-info    { background: var(--blue-tint);       color: var(--text-grey); }
.flash-close { background: none; border: none; font-size: 18px; cursor: pointer; color: inherit; }

/* ── MAIN / FOOTER ── */
.site-main { flex: 1; }
.site-footer { background: var(--white); border-top: 2px solid var(--cphs-gold); padding: 14px 24px; }
.footer-inner {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;                  /* tight: half a line height, not a full paragraph break */
  font-size: 12px;
  color: var(--text-grey);
  text-align: center;
}
.footer-line { font-size: 12px; }
.footer-tagline {
  /* Subordinate brand line - smaller and italic; italic rather than
     uppercase because "Assess. Analyse. Act." is marketing copy. */
  font-size: 11px;
  color: var(--text-grey);
  font-style: italic;
}
.footer-sep { opacity: 0.4; }  /* legacy class - harmless; left for any external references */

/* ── PAGE LAYOUT ── */
.page-wrap { max-width: 1400px; margin: 0 auto; padding: 28px 24px 48px; }
.page-narrow { max-width: 800px; }

.page-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 28px;
  padding-bottom: 20px; border-bottom: 1px solid var(--grid-grey);
}
.page-title { font-family: var(--font); font-weight: 700; font-size: 28px; color: var(--cphs-blue); margin-bottom: 4px; }
.page-subtitle { font-size: 14px; color: var(--text-grey); }
.page-actions { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }

.breadcrumb { font-size: 12px; color: var(--text-grey); margin-bottom: 4px; }
.breadcrumb a { color: var(--cphs-blue); }
.breadcrumb a:hover { text-decoration: underline; }

.section-title {
  font-family: var(--font);
  font-weight: 700;
  font-size: 18px; color: var(--cphs-blue);
  margin: 28px 0 14px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--cphs-gold);
  display: inline-block;
}

/* ── BUTTONS ── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 18px; border-radius: var(--radius-sm);
  font-family: var(--font); font-size: 14px; font-weight: 700;
  border: 1px solid transparent; cursor: pointer; transition: box-shadow 0.12s, background 0.12s;
  text-decoration: none;
}
.btn:hover { text-decoration: underline; }
/* .btn-gold is a legacy name: gold can't carry text, so it renders as primary. */
.btn-primary, .btn-gold { background: var(--cphs-blue); color: var(--white); border-color: var(--cphs-blue); }
.btn-primary:hover, .btn-gold:hover { color: var(--white); box-shadow: 0 0 0 3px var(--focus-ring); }
.btn-secondary { background: var(--white); color: var(--cphs-blue); border-color: var(--grid-grey); }
.btn-secondary:hover { background: var(--blue-tint); color: var(--cphs-blue); }
.btn-danger { background: var(--status-red); color: var(--white); border-color: var(--status-red); }
.btn-danger:hover { color: var(--white); }
.btn-full { width: 100%; justify-content: center; }
.btn-sm { padding: 5px 12px; font-size: 12px; }

/* ── METRIC CARDS ── */
.metrics-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.metric-card {
  background: var(--white); border-radius: var(--radius-lg);
  padding: 18px 20px; border: 1px solid var(--grid-grey);
}
.metric-label { font-size: 12px; font-weight: 700; color: var(--text-grey); margin-bottom: 6px; }
.metric-value { font-family: var(--font); font-weight: 700; font-size: 34px; color: var(--text-grey); line-height: 1; }
.metric-sub { font-size: 11px; color: var(--text-grey); margin-top: 4px; }

/* ── SUBJECT GRID ── */
.subject-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; margin-bottom: 28px; }
.subject-card {
  background: var(--white); border: 1px solid var(--grid-grey); border-radius: var(--radius-md);
  padding: 14px 16px; cursor: pointer; transition: border-color 0.12s;
  display: block; color: var(--text-grey);
}
.subject-card:hover { border-color: var(--cphs-blue); color: var(--text-grey); text-decoration: none; }
.sc-name { font-weight: 700; font-size: 14px; margin-bottom: 10px; }
.sc-bar-wrap { display: flex; height: 8px; border-radius: 4px; overflow: hidden; margin-bottom: 8px; gap: 1px; }
.sc-bar.red { background: var(--status-red); }
.sc-bar.blue { background: var(--cphs-blue); }
.sc-bar.green { background: var(--status-green); }
.sc-stats { display: flex; gap: 8px; font-size: 11px; color: var(--text-grey); flex-wrap: wrap; }
.sc-below { color: var(--status-red); font-weight: 700; }
.sc-above { color: var(--status-green); font-weight: 700; }
.sc-avg { font-size: 12px; font-weight: 700; margin-top: 6px; }
.sc-avg.neg { color: var(--status-red); }
.sc-avg.pos { color: var(--status-green); }

/* ── TABLES ──
   CPHS table, lightened for dense screens: blue header row, bold white
   text, 2px gold line under it, then horizontal Grid Grey rules only
   (no vertical cell borders) and White / Blue Tint zebra starting white.
   Zebra uses :nth-child so it re-stripes after a th[data-sort] sort. */
.table-wrap { background: var(--white); border: 1px solid var(--grid-grey); border-radius: var(--radius-lg); overflow: hidden; margin-bottom: 24px; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
thead tr { background: var(--cphs-blue); }
th {
  text-align: left; vertical-align: middle;
  padding: 9px 14px; font-size: 12.5px; font-weight: 700;
  color: var(--white); white-space: nowrap;
  border-bottom: 2px solid var(--cphs-gold);
}
td { padding: 11px 14px; border-bottom: 1px solid var(--grid-grey); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tbody tr:nth-child(even) > td { background: var(--blue-tint); }
/* A row that needs attention: a red edge, always paired with a word in the row. */
tbody tr.row-flag-red > td:first-child { box-shadow: inset 4px 0 0 var(--status-red); }
/* Column alignment: names/subjects/descriptions left (default),
   codes/dates/short values/year groups centred, counts/numbers right. */
th.col-code, td.col-code { text-align: center; }
td.col-code { white-space: nowrap; }
th.col-num,  td.col-num  { text-align: right; }
.student-name { font-weight: 700; color: var(--text-grey); }
a.student-name { color: var(--cphs-blue); }
.student-group { font-size: 11px; color: var(--text-grey); margin-top: 1px; }

/* ── TEXT UTILITIES ──
   Replace colour-bearing inline styles in templates. */
.note { font-size: 13px; color: var(--text-grey); margin-bottom: 14px; max-width: 90ch; }
.mono { font-family: Consolas, 'Courier New', monospace; font-size: 12px; }
.text-status-red   { color: var(--status-red);   font-weight: 700; }
.text-status-amber { color: var(--status-amber); font-weight: 700; }
.text-status-green { color: var(--status-green); font-weight: 700; }
.text-blue { color: var(--cphs-blue); font-weight: 700; }

/* ── BADGES ── */
.badge {
  display: inline-block; padding: 2px 8px; border-radius: var(--radius-sm);
  font-size: 11px; font-weight: 700; white-space: nowrap;
}
.badge[title] { cursor: help; border-bottom: 1px dotted currentColor; }
.badge-red    { background: var(--status-red-bg);   color: var(--status-red); }
.badge-amber  { background: var(--status-amber-bg); color: var(--status-amber); }
.badge-green  { background: var(--status-green-bg); color: var(--status-green); }
.badge-blue   { background: var(--blue-tint);       color: var(--cphs-blue); }
.badge-navy   { background: var(--cphs-blue);       color: var(--white); }
.badge-role   { background: var(--blue-tint);       color: var(--cphs-blue); }
.badge-gray   { background: var(--white);           color: var(--text-grey); box-shadow: inset 0 0 0 1px var(--grid-grey); }

/* ── RANK NUMBERS ── neutral: a rank is an order, not a status. */
.rank-num {
  display: inline-flex; width: 24px; height: 24px;
  align-items: center; justify-content: center;
  border-radius: 50%; font-size: 11px; font-weight: 700;
  background: var(--blue-tint); color: var(--text-grey);
}

/* ── COLLECTION CARDS ── */
.yg-section { margin-bottom: 32px; }
.yg-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.yg-header-action { margin-left: auto; }
.yg-title { font-family: var(--font); font-weight: 700; font-size: 20px; color: var(--cphs-blue); }
.ks-badge { background: var(--cphs-blue); color: var(--white); font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: var(--radius-sm); letter-spacing: 0.04em; }

.collections-grid { display: flex; gap: 12px; flex-wrap: wrap; }
.collection-card {
  background: var(--white); border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md); padding: 16px 18px;
  min-width: 180px; max-width: 220px;
  transition: border-color 0.12s; display: block;
}
.collection-card:hover { border-color: var(--cphs-blue); text-decoration: none; }
.cc-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.cc-month { font-weight: 700; font-size: 14px; color: var(--cphs-blue); }
.cc-type { font-size: 11px; font-weight: 700; color: var(--text-grey); }
.cc-stats { display: flex; gap: 12px; }
.cc-stat { text-align: center; }
.cc-stat-value { display: block; font-family: var(--font); font-weight: 700; font-size: 22px; color: var(--text-grey); line-height: 1; }
.cc-stat-label { font-size: 10px; color: var(--text-grey); }
.cc-stat.concern .cc-stat-value { color: var(--status-red); }
.cc-stat.warning .cc-stat-value { color: var(--status-amber); }

/* ── QUICK ACCESS ── */
.quick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.quick-card {
  background: var(--white); border: 1px solid var(--grid-grey);
  border-radius: var(--radius-lg); padding: 20px 22px;
  display: flex; flex-direction: column; gap: 4px;
  transition: border-color 0.12s; color: var(--text-grey);
}
.quick-card:hover { border-color: var(--cphs-blue); text-decoration: none; }
.quick-label { font-weight: 700; font-size: 15px; color: var(--cphs-blue); }
.quick-desc { font-size: 12px; color: var(--text-grey); }

/* ── FLAG STRIP ── */
.flag-strip { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 24px; }
.flag-chip {
  padding: 8px 14px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 700; cursor: pointer; transition: border-color 0.12s;
  border: 1px solid var(--grid-grey);
}
.flag-chip.red    { background: var(--status-red-bg);   color: var(--status-red); }
.flag-chip.amber  { background: var(--status-amber-bg); color: var(--status-amber); }
.flag-chip.green  { background: var(--status-green-bg); color: var(--status-green); }
.flag-chip.blue   { background: var(--blue-tint);       color: var(--cphs-blue); }
.flag-chip.gray   { background: var(--white);           color: var(--text-grey); }
.flag-chip:hover { border-color: var(--text-grey); text-decoration: none; }

/* ── ALERT CARDS ── */
.alert-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 12px; margin-bottom: 24px; }
.alert-card {
  background: var(--white); border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 14px 16px;
}
.alert-name { font-weight: 700; font-size: 14px; color: var(--cphs-blue); }
.alert-group { font-size: 11px; color: var(--text-grey); }
.alert-subject { font-size: 12px; color: var(--text-grey); margin-top: 4px; }
.alert-detail { font-size: 12px; color: var(--text-grey); margin-top: 6px; line-height: 1.5; }
.alert-pills { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }

/* ── FORMS ── */
.form-card { background: var(--white); border: 1px solid var(--grid-grey); border-radius: var(--radius-lg); padding: 28px 32px; margin-bottom: 24px; }
.form-group { margin-bottom: 18px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.form-label { display: block; font-size: 13px; font-weight: 700; color: var(--text-grey); margin-bottom: 6px; }
.req { color: var(--status-red); }
.form-input {
  width: 100%; padding: 9px 12px;
  border: 1px solid var(--grid-grey); border-radius: var(--radius-sm);
  font-family: var(--font); font-size: 14px; color: var(--text-grey);
  background: var(--white); outline: none; transition: border-color 0.12s;
}
.form-input:focus { border-color: var(--cphs-blue); box-shadow: 0 0 0 3px var(--focus-ring); }
.form-input::placeholder { color: var(--text-grey); font-style: italic; }
.form-hint { font-size: 12px; color: var(--text-grey); margin-top: 4px; }
.form-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--grid-grey); }
/* Bordered grid of checkboxes (faculty subjects, line-managed HoFs). */
.checkbox-panel { display: grid; gap: 8px; padding: 14px; border: 1px solid var(--grid-grey); border-radius: var(--radius-sm); background: var(--blue-tint); }
.radio-group { display: flex; flex-direction: column; gap: 10px; }
.radio-label { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
.radio-label input { width: 16px; height: 16px; accent-color: var(--cphs-blue); }

/* ── FILE DROP ── */
.file-drop { border: 2px dashed var(--grid-grey); border-radius: var(--radius-md); overflow: hidden; }
.file-input-hidden { position: absolute; opacity: 0; pointer-events: none; }
.file-drop-label { padding: 32px 24px; display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; transition: background 0.12s; }
.file-drop-label:hover { background: var(--blue-tint); }
.file-drop-text { font-size: 14px; font-weight: 700; color: var(--cphs-blue); }
.file-drop-hint { font-size: 12px; color: var(--text-grey); }
.file-selected { padding: 12px 16px; background: var(--status-green-bg); color: var(--status-green); font-weight: 700; font-size: 14px; }

/* ── INFO BOX ── */
.info-box { background: var(--blue-tint); border: 1px solid var(--grid-grey); border-radius: var(--radius-md); padding: 18px 20px; }
.info-title { font-weight: 700; font-size: 14px; color: var(--cphs-blue); margin-bottom: 8px; }
.info-list { padding-left: 20px; font-size: 13px; color: var(--text-grey); line-height: 1.8; }
.info-list code { background: var(--white); border: 1px solid var(--grid-grey); padding: 1px 5px; border-radius: 3px; font-size: 12px; }

/* ── LOGIN ── */
.login-body { background: var(--cphs-blue); display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.login-wrap { width: 100%; max-width: 440px; padding: 24px; }
.login-card { background: var(--white); border-radius: var(--radius-lg); padding: 40px 36px; }
.login-logo-wrap { text-align: center; margin-bottom: 20px; }
.login-logo { height: 50px; }
.login-app-name { text-align: center; margin-bottom: 28px; padding-bottom: 24px; border-bottom: 2px solid var(--cphs-gold); }
.login-title { font-family: var(--font); font-weight: 700; font-size: 32px; color: var(--cphs-blue); }
.login-subtitle { font-size: 13px; color: var(--text-grey); margin-top: 4px; }
.login-form { display: flex; flex-direction: column; gap: 0; }
.login-footer { text-align: center; font-size: 11px; color: var(--text-grey); margin-top: 20px; }

/* ── MAINTENANCE PAGE ── full-page calm message, no nav/header/footer chrome */
.maint-body { background: var(--cphs-blue); display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.maint-wrap { width: 100%; max-width: 520px; padding: 24px; }
.maint-card { background: var(--white); border-radius: var(--radius-lg); padding: 48px 44px; text-align: center; }
.maint-logo-wrap { margin-bottom: 28px; }
.maint-logo { height: 56px; }
.maint-title { font-family: var(--font); font-weight: 700; font-size: 30px; color: var(--cphs-blue); margin-bottom: 14px; }
.maint-subtitle { font-size: 17px; color: var(--text-grey); margin-bottom: 18px; }
.maint-body-text { font-size: 14px; color: var(--text-grey); line-height: 1.6; max-width: 380px; margin: 0 auto 32px; }
.maint-footer { font-size: 11px; letter-spacing: 0.04em; color: var(--text-grey); padding-top: 22px; border-top: 1px solid var(--grid-grey); }

/* ── MAINTENANCE ADMIN PANEL ── lives on the Manage Users page */
.maint-panel { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; border-radius: var(--radius-md); padding: 18px 22px; margin-bottom: 24px; }
.maint-panel-off { background: var(--blue-tint); border: 1px solid var(--grid-grey); }
.maint-panel-on { background: var(--status-amber-bg); border: 1px solid var(--grid-grey); }
.maint-panel-title { font-weight: 700; font-size: 15px; color: var(--cphs-blue); }
.maint-panel-on .maint-panel-title { color: var(--status-amber); }
.maint-panel-sub { font-size: 13px; color: var(--text-grey); margin-top: 4px; line-height: 1.5; }
.maint-enable-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.maint-reason-input { min-width: 320px; }

/* ── LENS VIEW ──
   Persistent cues that the user is viewing as someone else: a gold
   top rule on the page and a Blue Tint banner with a gold underline. */
body.lens-active { border-top: 4px solid var(--cphs-gold); }

.lens-banner {
  background: var(--blue-tint);
  border-bottom: 2px solid var(--cphs-gold);
}
.lens-banner-inner {
  max-width: 1280px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 9px 24px;
}
.lens-banner-text { font-size: 14px; color: var(--text-grey); }
.lens-banner-text strong { color: var(--text-grey); }
.lens-banner-role { color: var(--text-grey); }
.btn-exit-lens {
  flex-shrink: 0;
  background: var(--cphs-blue); color: var(--white);
  font-size: 12px; font-weight: 700;
  padding: 6px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--cphs-blue);
}
.btn-exit-lens:hover { color: var(--white); box-shadow: 0 0 0 3px var(--focus-ring); }

/* "View as…" dropdown in the header nav-user cluster. */
.lens-viewas { position: relative; }
.btn-viewas {
  background: transparent; color: var(--white);
  font-family: var(--font); font-size: 12px; font-weight: 700;
  padding: 5px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--on-blue-rule); cursor: pointer;
}
.btn-viewas:hover { border-color: var(--white); }
.lens-viewas-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 6px);
  width: 320px; max-height: 380px; overflow-y: auto;
  background: var(--white); border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md); box-shadow: var(--shadow-md);
  z-index: 50; padding: 8px;
}
.lens-viewas.open .lens-viewas-menu { display: block; }
.lens-viewas-filter {
  width: 100%; padding: 7px 10px; margin-bottom: 6px;
  border: 1px solid var(--grid-grey); border-radius: var(--radius-sm);
  font-size: 13px; font-family: var(--font); color: var(--text-grey);
}
.lens-viewas-item { margin: 0; }
.lens-viewas-item button {
  width: 100%; text-align: left; background: none; border: none;
  padding: 8px 10px; border-radius: var(--radius-sm); cursor: pointer;
  display: flex; flex-direction: column; gap: 2px;
  font-family: var(--font);
}
.lens-viewas-item button:hover { background: var(--blue-tint); }
.lens-item-name { font-size: 13px; font-weight: 700; color: var(--text-grey); }
.lens-item-role { font-size: 11px; color: var(--text-grey); }

/* ── EMPTY STATE ── */
.empty-state { text-align: center; padding: 80px 24px; }
.empty-icon { font-size: 48px; margin-bottom: 16px; }
.empty-title { font-family: var(--font); font-weight: 700; font-size: 24px; color: var(--cphs-blue); margin-bottom: 8px; }
.empty-desc { font-size: 15px; color: var(--text-grey); margin-bottom: 24px; }

/* ── PROGRESS TABLES ── */
.direction-improved { color: var(--status-green); font-weight: 700; }
.direction-regressed { color: var(--status-red); font-weight: 700; }
.direction-static { color: var(--text-grey); }

/* ── STUDENT PROFILE SUBJECT GRID ──
   (Previously defined twice; merged here with the same cascade result.) */
.profile-subject-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.profile-subject-cell {
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 12px 14px;
}
.psc-name {
  font-weight: 700;
  font-size: 14px;
  color: var(--text-grey);
  margin-bottom: 6px;
  /* Allow long canonical names like "Computer Science" to wrap rather than clip. */
  overflow-wrap: anywhere;
  word-break: break-word;
}
.psc-grades { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.psc-target { color: var(--text-grey); }
.psc-current { font-weight: 700; color: var(--text-grey); }
.psc-diff { margin-left: auto; font-size: 12px; font-weight: 700; }
.psc-diff.neg { color: var(--status-red); }
.psc-diff.pos { color: var(--status-green); }
.psc-scores { display: flex; gap: 5px; margin-top: 8px; flex-wrap: wrap; }

/* ── INTERVENTION MOBILE CARDS ──
   One tap-target card per student, shown only ≤768px in place of the
   data table (which is hidden at that width). The whole card links to
   the student profile, so it carries only the headline figures. */
.intervention-cards { display: none; }
.stu-card {
  display: block; color: inherit;
  background: var(--white); border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md); padding: 14px;
}
.stu-card:hover { text-decoration: none; }
.stu-card:active { background: var(--blue-tint); }
.stu-card-row1 { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.stu-card-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stu-card-name { font-size: 15.5px; font-weight: 700; color: var(--cphs-blue); line-height: 1.2; }
.stu-card-meta { font-size: 12px; color: var(--text-grey); }
.stu-card-stats {
  display: flex; margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--grid-grey);
}
.stu-stat { flex: 1; min-width: 0; }
.stu-stat + .stu-stat { border-left: 1px solid var(--grid-grey); padding-left: 12px; }
.stu-stat-label {
  display: block; font-size: 10.5px; font-weight: 700;
  color: var(--text-grey);
}
.stu-stat-val {
  display: block; margin-top: 3px;
  font-family: var(--font); font-size: 20px; font-weight: 700;
  color: var(--text-grey); line-height: 1;
}
.stu-stat-val.muted { color: var(--text-grey); font-weight: 400; }

/* ── RESPONSIVE ── */
@media (max-width: 768px) {
  .page-wrap { padding: 16px; }
  .form-row { grid-template-columns: 1fr; }
  .metrics-row { grid-template-columns: repeat(2, 1fr); }
}

@media print {
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .site-header, .site-footer, .page-actions, .flash-container,
  .lens-banner, .heatmap-swipe-hint { display: none !important; }
  body.lens-active { border-top: none; }
  .page-wrap { padding: 0; }
  .table-wrap { box-shadow: none; border: 1px solid var(--grid-grey); overflow: visible; }
  .hero-panel, .metric-card, .yg-strip, .fac-strip, .chart-container, .heatmap-wrap { break-inside: avoid; }
  tr { break-inside: avoid; }
  h1, h2, h3, .section-title, .section-divider { break-after: avoid; }
  /* Charts keep their on-screen canvas size; scale them to the page. */
  .chart-container { height: 300px; }
  .chart-container canvas { max-width: 100% !important; height: auto !important; }
}

/* ── HERO PANEL (school status, faculty view, pupil snapshot) ──
   Light panel: a CPHS Blue title strip with a gold line under it (it
   reads like a table header row), then white tiles on Blue Tint. Kept
   light so status colours stay readable — no status colour reaches
   4.5:1 on solid CPHS Blue. */
.hero-panel {
  --hero-pad: 32px;
  background: var(--blue-tint);
  color: var(--text-grey);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-lg);
  padding: 0 var(--hero-pad) 28px;
  margin-bottom: 32px;
  overflow: hidden;
}
.hero-header {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px;
  background: var(--cphs-blue);
  margin: 0 calc(-1 * var(--hero-pad)) 24px;
  padding: 16px var(--hero-pad);
  border-bottom: 2px solid var(--cphs-gold);
}
.hero-badge {
  display: inline-block;
  color: var(--white);
  font-size: 12px; font-weight: 700;
  padding-right: 14px;
  border-right: 1px solid var(--on-blue-rule);
}
.hero-title {
  font-family: var(--font);
  font-size: 22px; font-weight: 700;
  color: var(--white); margin: 0;
}
.hero-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  grid-template-rows: auto auto;
  gap: 16px;
}
.hero-stat.hero-stat-headline {
  grid-row: span 2;
  display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center;
  background: var(--cphs-blue);
  color: var(--white);
  padding: 24px;
  border-radius: var(--radius-md);
  border: 1px solid var(--cphs-blue);
}
/* The headline tile is the hero's focal point: everything in it is
   white on CPHS Blue (5.09:1). Direction is carried by the arrow and
   words of the change line, so it needs no status colour here. */
.hero-stat-headline .hero-stat-label,
.hero-stat-headline .hero-change-up,
.hero-stat-headline .hero-change-down,
.hero-headline-note { color: var(--white); }
.hero-headline-change { margin-top: 8px; font-size: 13px; }
.hero-headline-note { margin-top: 4px; font-size: 12px; }
.hero-stat {
  background: var(--white);
  border: 1px solid var(--grid-grey);
  padding: 18px;
  border-radius: var(--radius-md);
  display: flex; flex-direction: column;
  gap: 4px;
  text-decoration: none; color: inherit;
  transition: border-color 0.12s;
}
a.hero-stat:hover {
  border-color: var(--cphs-blue);
  cursor: pointer;
  text-decoration: none;
}
.hero-big-number {
  font-family: var(--font);
  font-size: 64px; font-weight: 700;
  line-height: 1; color: var(--white);
}
.hero-stat-value {
  font-size: 28px; font-weight: 700;
  font-family: var(--font);
  color: var(--text-grey);
}
.hero-stat-label {
  font-size: 13px; color: var(--text-grey);
  line-height: 1.4;
}
/* Tile variants. Each value already sits above a word label, so the
   colour reinforces rather than carries the meaning. */
.hero-stat-alert .hero-stat-value { color: var(--status-red); }
.hero-stat-warn .hero-stat-value { color: var(--status-amber); }
.hero-stat-improver .hero-stat-value { color: var(--status-green); font-size: 20px; }
.hero-stat-decliner .hero-stat-value { color: var(--status-red); font-size: 20px; }
/* 'info' is the stretch tile (an opportunity, not a status); 'muted'
   is data checks and empty movement cards. */
.hero-stat-info  .hero-stat-value { color: var(--text-grey); }
.hero-stat-muted .hero-stat-value { color: var(--text-grey); font-size: 20px; }
.hero-footer {
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--grid-grey);
  font-size: 14px; color: var(--text-grey);
}
.hero-improved { color: var(--status-green); }
.hero-regressed { color: var(--status-red); }

/* Headline change indicators (the "↑ 4 pts since Interim 1" line). */
.hero-change-up   { color: var(--status-green); font-weight: 700; }
.hero-change-down { color: var(--status-red);   font-weight: 700; }

/* Data-quality footer line links to the incomplete-records page. */
.hero-footer-link {
  color: var(--cphs-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-size: 12px;
}
.hero-footer-link:hover { color: var(--cphs-blue); }

/* ── HoF FACULTY YEAR-GROUP STRIP ──
   Mirrors .yg-strip dimensions (white card, blue title, hover lift) but
   reads subject-first: subject label on the left, year-group tiles
   wrapping on the right. One row per subject in user.faculty_subjects. */
.fac-strip {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 20px;
  align-items: center;
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 18px 22px;
  margin-bottom: 12px;
}
.fac-strip-title {
  font-family: var(--font);
  font-size: 18px;
  font-weight: 700;
  color: var(--cphs-blue);
}
.fac-strip-tiles {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.fac-tile {
  display: flex; flex-direction: column; gap: 4px;
  min-width: 140px;
  padding: 10px 14px;
  border: 2px solid var(--blue-tint);
  background: var(--blue-tint);
  color: var(--text-grey);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: all 0.12s;
}
.fac-tile:hover {
  border-color: var(--cphs-blue);
  text-decoration: none;
}
.fac-tile-year {
  font-family: var(--font);
  font-size: 14px; font-weight: 700;
  color: var(--cphs-blue);
}
.fac-tile-bar {
  position: relative;
  height: 6px;
  background: var(--grid-grey);
  border-radius: 3px;
  overflow: hidden;
}
.fac-tile-bar-fill {
  position: absolute; top: 0; left: 0; bottom: 0;
  background: var(--cphs-blue);
  border-radius: 3px;
  transition: width 0.2s;
}
.fac-tile-pct  { font-size: 13px; font-weight: 700; }
.fac-tile-count { font-size: 11px; color: var(--text-grey); }

@media (max-width: 700px) {
  .fac-strip { grid-template-columns: 1fr; }
}

/* Single-letter Smart Flag badges used on the faculty year-group page.
   Compact pills so the Flag column stays narrow even when a student
   carries three or four flags. One mapping app-wide: academic support
   red, engagement amber, stretch blue, data checks grey. */
.flag-badge {
  display: inline-block;
  min-width: 20px;
  padding: 2px 6px;
  margin-right: 3px;
  font-size: 11px; font-weight: 700;
  text-align: center;
  border-radius: 4px;
  font-family: var(--font);
}
.flag-badge-academic_support    { background: var(--status-red-bg);   color: var(--status-red); }
.flag-badge-stretch_opportunity { background: var(--blue-tint);       color: var(--cphs-blue); }
.flag-badge-engagement          { background: var(--status-amber-bg); color: var(--status-amber); }
.flag-badge-data_inconsistency  { background: var(--white);           color: var(--text-grey); box-shadow: inset 0 0 0 1px var(--grid-grey); }

/* Sortable table affordance — an underline on hover hints that column
   headers are clickable. */
table.sortable thead th:hover { text-decoration: underline; text-decoration-color: var(--white); }

/* Effort score pill on the faculty year-group click-through. Coloured
   on the 1–5 rubric so the flag-gate (Academic Support requires Effort
   ≤ 2) is obvious at a glance — keep this visually separate from the
   plain Avg-attitudinal cell next to it. */
.effort-pill {
  display: inline-block;
  min-width: 22px;
  padding: 2px 8px;
  font-size: 12px; font-weight: 700;
  text-align: center;
  border-radius: 4px;
}

/* "+N elsewhere" tag in the Flags column — muted so the primary
   single-letter badges remain the dominant signal. */
.elsewhere-tag {
  display: inline-block;
  margin-left: 6px;
  font-size: 11px;
  color: var(--text-grey);
  font-style: italic;
  cursor: help;
}

/* HoF inline panels (Celebrate + Worth Discussing). They sit below the
   stat grid and have a softer accent than the alarm-coloured tiles. */
.hof-panel {
  display: flex; gap: 10px; align-items: flex-start;
  margin-top: 18px; padding: 14px 16px;
  border-radius: var(--radius-sm); font-size: 14px; line-height: 1.5;
  background: var(--white); border: 1px solid var(--grid-grey);
  color: var(--text-grey);
}
.hof-celebrate .student-name { color: var(--cphs-blue); text-decoration: underline; }

/* Spans the full hero-grid row so it reads as a footer note rather
   than another tile. Smart Flag categories overlap, so the four tile
   counts may add up to more than the number of unique students. */
.hero-multicat-note {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--text-grey);
  font-style: italic;
  padding: 4px 2px 0;
}

/* Movement tiles share .hero-stat dimensions with the count tiles so
   the second hero-grid row reads as a uniform 4-tile band. Their value
   (year-group + subject) is wordy, so we use a smaller label-style font
   instead of the 28px count number. */
.hero-stat-movement {
  justify-content: space-between;
  min-height: 92px;
}
.hero-movement-label {
  font-family: var(--font);
  font-size: 16px; font-weight: 700;
  line-height: 1.2;
  color: var(--text-grey);
  /* Two-line clamp so very long faculties (e.g. "Y10 Religious Education")
     don't push the change line out of the tile. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Names what a movement tile shows, now that it carries no icon. */
.hero-movement-kind { font-size: 12px; font-weight: 700; color: var(--text-grey); }
.hero-movement-change {
  font-size: 13px; font-weight: 400;
  color: var(--text-grey);
}
.hero-stat-improver /* Names what a movement tile shows, now that it carries no icon. */
.hero-movement-kind { font-size: 12px; font-weight: 700; color: var(--text-grey); }
.hero-movement-change { color: var(--status-green); }
.hero-stat-decliner /* Names what a movement tile shows, now that it carries no icon. */
.hero-movement-kind { font-size: 12px; font-weight: 700; color: var(--text-grey); }
.hero-movement-change { color: var(--status-red); }

@media (max-width: 800px) {
  .hero-grid { grid-template-columns: 1fr 1fr; }
  .hero-stat.hero-stat-headline { grid-row: auto; grid-column: span 2; }
}

.hero-footer a { text-decoration: none; }
.hero-footer a:hover { text-decoration: underline; }

/* ── SECTION DIVIDER ── */
.section-divider {
  font-family: var(--font);
  font-weight: 700;
  font-size: 22px;
  color: var(--cphs-blue);
  margin: 36px 0 18px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--cphs-gold);
  display: inline-block;
  padding-right: 30px;
}

/* ── YEAR GROUP STRIP ── */
.yg-strip {
  display: grid;
  grid-template-columns: 140px 1fr 240px;
  gap: 20px;
  align-items: center;
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 18px 22px;
  margin-bottom: 12px;
}

.yg-strip-title {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}
.yg-strip-year {
  font-family: var(--font);
  font-size: 22px;
  font-weight: 700;
  color: var(--cphs-blue);
}
.yg-strip-ks {
  background: var(--cphs-blue);
  color: var(--white);
  font-size: 10px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  letter-spacing: 0.04em;
}

.yg-strip-points {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* Collection-point tiles: white, with a top accent for the type
   (Interim gold, Mock grey, Final blue). The word names the type. */
.yg-point {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 90px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: 12px;
  background: var(--white);
  color: var(--text-grey);
  border: 1px solid var(--grid-grey);
  transition: border-color 0.12s;
}
.yg-point-name {
  font-weight: 700;
  font-size: 13px;
  color: var(--cphs-blue);
}
.yg-point-status {
  font-size: 10px;
  margin-top: 2px;
  color: var(--text-grey);
}
.yg-point:hover { border-color: var(--cphs-blue); text-decoration: none; }
.yg-point-incomplete { border-style: dashed; }
.yg-point-placeholder {
  background: var(--white);
  border: 2px dashed var(--grid-grey);
  color: var(--text-grey);
  cursor: default;
}
.yg-point-placeholder:hover { border-color: var(--grid-grey); }
.yg-point-placeholder .yg-point-name { color: var(--text-grey); }

.yg-strip-summary {
  border-left: 1px solid var(--grid-grey);
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.yg-summary-row {
  font-size: 12px;
  color: var(--text-grey);
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.yg-summary-pct {
  font-family: var(--font);
  font-size: 22px;
  font-weight: 700;
  color: var(--text-grey);
}
.yg-summary-label {
  font-size: 12px;
  color: var(--text-grey);
}
.yg-summary-warn { color: var(--status-amber); font-weight: 700; }
.yg-summary-muted { color: var(--text-grey); font-size: 11px; }

@media (max-width: 900px) {
  .yg-strip {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .yg-strip-summary {
    border-left: none;
    border-top: 1px solid var(--grid-grey);
    padding-left: 0;
    padding-top: 12px;
  }
}

.yg-summary-row[title] { cursor: help; }

/* ── AGGREGATE STRIP ── */
.agg-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 28px;
  padding: 18px;
  background: var(--blue-tint);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
}
.agg-stat {
  text-align: center;
  padding: 8px;
}
.agg-value {
  font-family: var(--font);
  font-size: 32px;
  font-weight: 700;
  color: var(--text-grey);
  line-height: 1;
}
.agg-value.agg-alert { color: var(--status-red); }
.agg-value.agg-warn { color: var(--status-amber); }
.agg-label {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-grey);
  margin-top: 6px;
}

/* ── CHART CONTAINER ── */
.chart-container {
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 20px;
  margin-bottom: 28px;
  height: 360px;
}

/* ── HEATMAP ──
   A colour matrix, not a data table, so it opts out of the CPHS table
   header and cell borders. */
.heatmap-wrap {
  overflow-x: auto;
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 12px;
  margin-bottom: 28px;
}
.heatmap {
  width: 100%;
  border-collapse: separate;
  border-spacing: 3px;
}
.heatmap thead tr { background: none; }
.heatmap th, .heatmap td { border: none; }
.heatmap tbody tr:nth-child(even) > td:first-child { background: var(--white); }
.heatmap tbody tr:hover > td:first-child { box-shadow: 1px 0 0 var(--grid-grey); }
.heatmap th {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-grey);
  padding: 6px 4px;
  text-align: center;
  white-space: nowrap;
}
.heatmap th.heatmap-subj {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  height: 100px;
}
.heatmap td {
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  padding: 8px 6px;
  border-radius: 4px;
  min-width: 40px;
  cursor: help;
}
.heatmap-cell.heatmap-empty {
  background: var(--blue-tint);
  color: var(--text-grey);
}
/* Small-cohort cells (n<5): dimmed so the user knows the average has low
   statistical confidence. Hover tooltip carries the actual n. */
.heatmap-cell.heatmap-cell-small-cohort {
  font-style: italic;
  outline: 1px dashed currentColor;
  outline-offset: -4px;
}
.heatmap td:first-child {
  font-size: 13px;
  text-align: left;
  padding-left: 10px;
  background: var(--white);
  cursor: default;
}
/* Keep the Year-group label column pinned while subjects scroll
   horizontally, so cells never lose their row context on narrow screens.
   Harmless on desktop where the table doesn't overflow. */
.heatmap th:first-child,
.heatmap td:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--white);
  box-shadow: 1px 0 0 var(--grid-grey);
}
.heatmap th:first-child { z-index: 3; }
/* "Swipe for more" affordance — mobile only. */
.heatmap-swipe-hint { display: none; }
@media (max-width: 768px) {
  .heatmap-swipe-hint {
    display: block;
    font-size: 11px; font-style: italic;
    color: var(--text-grey); margin-bottom: 6px;
  }
}
/* ═══════════════════════════════════════ */
/* MOBILE RESPONSIVE STYLES                */
/* ═══════════════════════════════════════ */

@media (max-width: 768px) {
  /* Header stays a single compact row; the inline nav is swapped for a
     hamburger that toggles the slide-down drawer. */
  .header-inner {
    height: 56px;
    gap: 10px;
    padding: 0 14px;
  }
  .school-logo { height: 30px; padding: 2px 4px; }
  .header-divider { display: none; }
  .app-name-main { font-size: 18px; line-height: 1; }
  .app-name-sub { font-size: 9px; }

  .header-nav { display: none; }
  .nav-hamburger { display: flex; }
  .mobile-drawer.open { display: block; }

  /* Hero panel mobile */
  .hero-panel {
    --hero-pad: 16px;
    padding-bottom: 18px !important;
  }
  .hero-grid {
    grid-template-columns: 1fr 1fr !important;
  }
  .hero-stat-headline {
    grid-column: span 2 !important;
    grid-row: auto !important;
    padding: 18px !important;
  }
  .hero-big-number {
    font-size: 48px !important;
  }
  .hero-title {
    font-size: 18px !important;
  }
  .hero-stat {
    padding: 14px !important;
  }
  .hero-stat-value {
    font-size: 22px !important;
  }
  .hero-stat-label {
    font-size: 11px !important;
  }

  /* Year group strip mobile */
  .yg-strip {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
  }
  .yg-strip-summary {
    border-left: none !important;
    border-top: 1px solid var(--grid-grey) !important;
    padding-left: 0 !important;
    padding-top: 12px !important;
  }

  /* Page header */
  .page-header {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 12px !important;
  }
  .page-title {
    font-size: 22px !important;
  }
  .page-actions {
    width: 100% !important;
    flex-wrap: wrap !important;
  }

  /* Tables scrollable by default… */
  .table-wrap {
    overflow-x: auto !important;
  }
  /* …but the intervention list swaps its table for tap-friendly cards. */
  .intervention-table { display: none !important; }
  .intervention-cards { display: flex; flex-direction: column; gap: 10px; }

  /* Page wrap padding */
  .page-wrap {
    padding: 16px 12px !important;
  }

  /* Forms: full-width fields, 16px text (stops iOS zoom-on-focus), and
     44px+ tap targets. Labels are already above fields in the markup. */
  .form-card { padding: 20px 18px; }
  .form-input,
  select.form-input,
  textarea.form-input {
    font-size: 16px;
    min-height: 46px;
  }
  .form-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .form-actions .btn { width: 100%; justify-content: center; }

  /* Every button is a comfortable tap target on mobile. */
  .btn { min-height: 44px; }
  .btn-sm { min-height: 36px; }

  /* Footer: a touch tighter on small screens. */
  .site-footer { padding: 14px 16px; }
}

@media (max-width: 480px) {
  .agg-strip {
    grid-template-columns: 1fr 1fr !important;
  }
  .heatmap th.heatmap-subj {
    height: 70px !important;
    font-size: 9px !important;
  }
  .hero-grid {
    grid-template-columns: 1fr !important;
  }
  .hero-stat-headline {
    grid-column: auto !important;
  }
  .nav-search { width: 100% !important; max-width: 100% !important; }
  .nav-search-input { width: 100% !important; }
  .nav-search-results { left: 0 !important; right: 0 !important; }
}

/* ── GLOBAL SEARCH ── */
.nav-search {
  position: relative;
  width: 210px;
  margin-left: 12px;
}
.nav-search-input {
  width: 100%;
  background: var(--white);
  border: 2px solid var(--white);
  color: var(--text-grey);
  font-family: var(--font);
  font-size: 13px;
  padding: 6px 11px;
  border-radius: var(--radius-sm);
  outline: none;
  transition: border-color 0.15s;
}
.nav-search-input::placeholder { color: var(--text-grey); font-style: italic; }
.nav-search-input:focus { border-color: var(--cphs-gold); }
.nav-search-results {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  max-height: 360px;
  overflow-y: auto;
  z-index: 300;
}
.nav-search-results.open { display: block; }
.nav-search-item {
  display: block;
  padding: 9px 12px;
  border-bottom: 1px solid var(--grid-grey);
  text-decoration: none;
  color: var(--text-grey);
  cursor: pointer;
}
.nav-search-item:last-child { border-bottom: none; }
.nav-search-item:hover,
.nav-search-item.active {
  background: var(--blue-tint);
  color: var(--cphs-blue);
  text-decoration: none;
}
.nav-search-name { font-weight: 700; font-size: 13px; }
.nav-search-meta { font-size: 11px; color: var(--text-grey); margin-top: 1px; }
.nav-search-empty { padding: 12px; font-size: 12px; color: var(--text-grey); text-align: center; }

/* ── STATUS PILL (profile header) ── */
.status-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 700;
  border: 1px solid var(--grid-grey);
}
.status-pill.status-red    { background: var(--status-red-bg);   color: var(--status-red); }
.status-pill.status-amber  { background: var(--status-amber-bg); color: var(--status-amber); }
.status-pill.status-green  { background: var(--status-green-bg); color: var(--status-green); }

/* ── PROFILE FLAGS ── */
.flag-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
.flag-card {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 14px 18px; border-radius: var(--radius-md);
  background: var(--white); border: 1px solid var(--grid-grey);
}
.flag-card .flag-title { font-weight: 700; color: var(--text-grey); font-size: 14px; }
.flag-card .flag-action { font-size: 12.5px; color: var(--text-grey); margin-top: 2px; }
.flag-empty {
  background: var(--status-green-bg); color: var(--status-green);
  padding: 12px 18px; border-radius: var(--radius-md);
  font-size: 14px; font-weight: 700;
}

/* ── ATTENDANCE PATTERN ── */
.att-pattern { display: flex; gap: 12px; flex-wrap: wrap; align-items: stretch; margin-bottom: 24px; }
.att-pattern-cell {
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  min-width: 110px;
  flex: 1;
}
.att-pattern-label { font-size: 11px; font-weight: 700; color: var(--text-grey); }
.att-pattern-value { font-family: var(--font); font-weight: 700; font-size: 22px; color: var(--text-grey); margin-top: 4px; }
.att-trend { font-size: 12px; margin-top: 4px; }
.att-trend.up    { color: var(--status-green); }
.att-trend.down  { color: var(--status-red); }
.att-trend.flat  { color: var(--text-grey); }

/* ── MOVEMENT ROWS ── */
.move-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 24px; }
.move-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 12px;
  align-items: center;
  background: var(--white);
  border: 1px solid var(--grid-grey);
  border-radius: var(--radius-md);
  padding: 10px 16px;
  font-size: 13.5px;
}
.move-row .move-label { font-weight: 700; color: var(--text-grey); }
.move-row .move-val { color: var(--text-grey); }

/* ── AVERAGE-ATTITUDINAL PILL (student profile subject card) ── */
.psc-avg-att {
  display: inline-flex; align-items: baseline; gap: 6px;
  margin-top: 8px;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  font-size: 12px; font-weight: 700;
  line-height: 1.2;
}
.psc-avg-att-label { font-size: 10px; font-weight: 700; }
.psc-avg-att-value { font-family: var(--font); font-size: 14px; font-weight: 700; }


/* Expandable details inside a subject card. */
.psc-details {
  margin-top: 10px;
  border-top: 1px solid var(--grid-grey);
  padding-top: 10px;
}
.psc-details > summary {
  cursor: pointer;
  font-size: 12px;
  color: var(--cphs-blue);
  font-weight: 700;
  list-style: none;
  user-select: none;
}
.psc-details > summary::-webkit-details-marker { display: none; }
.psc-details > summary::before {
  content: '▸ ';
  display: inline-block;
  transition: transform 0.15s;
}
.psc-details[open] > summary::before { content: '▾ '; }
.psc-details > summary:hover { color: var(--cphs-blue); text-decoration: underline; }

/* ── ATTITUDE BANDS ──
   One scale for every 1-5 attitudinal or progress score (lower is
   better), matching the school rubric. Fill strength follows severity
   at both ends; Good is deliberately quiet. Used by badges, the
   profile's average pill, effort pills, mobile stat values and hero
   tiles. Each place shows the score or its rubric word, so colour
   reinforces rather than carries the meaning. */
.band-outstanding, .effort-1 { background: var(--status-green);    color: var(--white); }
.band-excellent,   .effort-2 { background: var(--status-green-bg); color: var(--status-green); }
.band-good,        .effort-3 { background: var(--white);           color: var(--text-grey); box-shadow: inset 0 0 0 1px var(--grid-grey); }
.band-concern,     .effort-4 { background: var(--status-amber-bg); color: var(--status-amber); }
.band-critical,    .effort-5 { background: var(--status-red);      color: var(--white); }
.band-missing                { background: var(--blue-tint);       color: var(--text-grey); }
/* Text-only and tile contexts take the colour, not the fill. */
.stu-stat-val[class*="band-"] { background: none; box-shadow: none; }
.stu-stat-val.band-outstanding, .stu-stat-val.band-excellent { color: var(--status-green); }
.stu-stat-val.band-good, .stu-stat-val.band-missing { color: var(--text-grey); }
.stu-stat-val.band-concern  { color: var(--status-amber); }
.stu-stat-val.band-critical { color: var(--status-red); }
.hero-stat[class*="band-"] { background: var(--white); color: var(--text-grey); box-shadow: none; }
.hero-stat.band-outstanding .hero-stat-value, .hero-stat.band-excellent .hero-stat-value { color: var(--status-green); }
.hero-stat.band-concern  .hero-stat-value { color: var(--status-amber); }
.hero-stat.band-critical .hero-stat-value { color: var(--status-red); }

/* ── HEATMAP SCALE ──
   Average gap from target in grade points. Every cell shows its signed
   value, so colour reinforces the number. Six steps, matching the
   thresholds in slr.html. Scoped to .heatmap td so the table zebra
   stripe can't override a cell's colour. */
.heatmap td.heat-n3 { background: var(--status-red);      color: var(--white); }
.heatmap td.heat-n2 { background: var(--status-red-mid);  color: var(--status-red-deep); }
.heatmap td.heat-n1 { background: var(--status-red-bg);   color: var(--text-grey); }
.heatmap td.heat-0  { background: var(--white);           color: var(--text-grey); box-shadow: inset 0 0 0 1px var(--grid-grey); }
.heatmap td.heat-p1 { background: var(--status-green-bg); color: var(--text-grey); }
.heatmap td.heat-p2 { background: var(--status-green);    color: var(--white); }

/* ── VALUES AS TEXT ──
   In tables and score lists a value is plain text in its status colour;
   a wall of pills hides the cells that matter. Only the attitude
   extremes (Inconsistent, Cause for concern) keep a fill. */
td .badge:not(.band-concern):not(.band-critical),
td .effort-pill:not(.effort-4):not(.effort-5),
.psc-scores .badge:not(.band-concern):not(.band-critical),
.psc-avg-att:not(.band-concern):not(.band-critical),
.alert-pills .badge,
.att-pattern-cell .badge,
.move-row .badge {
  background: none; box-shadow: none; padding: 0; border-radius: 0;
}
td .badge-gray, td .badge-blue, td .badge-navy, td .badge-role,
td .band-good, td .band-missing, td .effort-3,
.psc-scores .band-good, .psc-scores .band-missing,
.psc-avg-att.band-good, .psc-avg-att.band-missing,
.alert-pills .badge, .move-row .badge-gray {
  color: var(--text-grey);
}
td .badge-gray, td .badge-navy, td .band-good, td .band-missing, td .effort-3,
.psc-scores .band-good, .alert-pills .badge { font-weight: 400; }
td .band-outstanding, td .effort-1,
.psc-scores .band-outstanding, .psc-avg-att.band-outstanding { color: var(--status-green); }
.alert-pills { gap: 4px 14px; }

/* ── HEADER FIT (769px and up) ──
   The admin nav overflowed the bar below about 1366px. These rules
   come after the base header and search rules so they take effect. */
/* Keep the account controls on one line each (they wrapped to two). */
.btn-viewas, .btn-logout, .user-name { white-space: nowrap; }
/* Desktop: spacing tight enough that the full nav fits on one row. */
@media (min-width: 769px) {
  .header-inner { gap: 12px; }
  .header-divider { display: none; }
  .header-brand { gap: 10px; }
  .nav-link { padding: 7px 7px; }
  .nav-search { width: 170px; margin-left: 6px; }
  .nav-user { margin-left: 6px; padding-left: 10px; gap: 8px; }
}
/* Narrower: the brand takes the first row and the whole nav (links,
   search, account) a second, full-width row, so every control stays
   visible. The mobile drawer has no search or View as. */
@media (min-width: 769px) and (max-width: 1440px) {
  .header-inner { flex-wrap: wrap; height: auto; padding-top: 8px; padding-bottom: 8px; row-gap: 4px; }
  .header-nav { flex-basis: 100%; margin-left: 0; }
  .nav-search { margin-left: auto; }
}
/* Tablet portrait: the second row is tight, so narrow the search and drop
   the name text (the role badge and Sign out stay). */
@media (min-width: 769px) and (max-width: 960px) {
  .nav-search { width: 120px; }
  .nav-link { padding: 7px 5px; }
  .user-name { display: none; }
}

/* ═══════════════════════════════════════════════════════════
   CHARTS — drawn on the server as HTML + inline SVG
   (templates/_charts.html, app/charts.py). One chart per page, headed by
   the question it answers. Position carries the meaning (left of the
   zero line = below), colour repeats it, shape marks the second measure.
   Numbers live in the hover title and behind "Show data".
   ═══════════════════════════════════════════════════════════ */
.viz { margin: 0 0 28px; }
.viz-q {
  font-family: var(--font); font-weight: 700; font-size: 18px; color: var(--cphs-blue);
  margin: 0; padding-bottom: 8px; border-bottom: 2px solid var(--cphs-gold);
}
.viz-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 20px; margin: 10px 0 10px; }
.viz-key { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 12px; color: var(--text-grey); }
.viz-key > span { display: inline-flex; align-items: center; gap: 6px; }
.viz-key svg { width: 18px; height: 14px; flex: none; overflow: visible; }

/* Marks (shared by every chart) */
.mk-neg  { fill: var(--status-red); }
.mk-pos  { fill: var(--status-green); }
.mk-zero { fill: var(--text-grey); }
.mk-cat  { fill: var(--white); stroke: var(--cphs-blue); stroke-width: 2; }
.mk-past { fill: var(--white); stroke: var(--text-grey); stroke-width: 1.5; }
.mk-line { stroke: var(--text-grey); stroke-width: 1.5; fill: none; }
.mk-mock { fill: var(--text-grey); font-size: 15px; font-weight: 700; }
.mk-exam { fill: var(--cphs-blue); stroke: var(--white); stroke-width: 1.5; }
.mk-track { fill: var(--blue-tint); }
.mk-blue { fill: var(--cphs-blue); }
.mk-small { fill: var(--white); stroke-width: 1.5; stroke-dasharray: 3 2; }
.mk-small.mk-neg  { fill: var(--white); stroke: var(--status-red); }
.mk-small.mk-pos  { fill: var(--white); stroke: var(--status-green); }
.mk-small.mk-zero { fill: var(--white); stroke: var(--text-grey); }
.gl      { stroke: var(--grid-grey); stroke-width: 1; stroke-dasharray: 2 3; }
.gl-zero { stroke: var(--text-grey); stroke-width: 1.5; }

/* Measure switch: a ruled segmented control. */
.viz-switch { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--grid-grey); border-radius: var(--radius-sm); font-size: 12.5px; }
.viz-switch a, .viz-switch span { padding: 6px 12px; color: var(--cphs-blue); border-left: 1px solid var(--grid-grey); white-space: nowrap; }
.viz-switch > :first-child { border-left: none; }
.viz-switch .on { background: var(--cphs-blue); color: var(--white); font-weight: 700; }
.viz-switch .later { color: var(--text-grey); font-style: italic; cursor: default; }

/* Row chart: label | plot | tail, ruled like a printed table. */
.vchart { border-top: 2px solid var(--cphs-blue); }
.vrow {
  display: grid; grid-template-columns: minmax(130px, 220px) minmax(0, 1fr) minmax(80px, 150px);
  column-gap: 14px; align-items: center; min-height: 30px;
  border-bottom: 1px solid var(--grid-grey); color: var(--text-grey); font-size: 13px;
}
a.vrow:hover { text-decoration: none; background: var(--blue-tint); }
a.vrow:hover .vlabel { text-decoration: underline; }
.vlabel { padding: 4px 0 4px 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.vrow .vlabel { color: var(--cphs-blue); font-weight: 700; }
.vlabel small { font-weight: 400; color: var(--text-grey); margin-left: 6px; font-size: 11px; }
.vtail { font-size: 12px; padding-right: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vplot { display: block; width: calc(100% - 24px); margin: 0 12px; height: 26px; overflow: visible; }
.vaxis { min-height: 26px; font-size: 11px; font-weight: 700; }
.vaxis .vplot { position: relative; }
.vaxis .tick { position: absolute; top: 6px; transform: translateX(-50%); }
.vaxis .dir { position: absolute; top: 6px; font-weight: 400; font-style: italic; }
.vaxis .dir.l { left: 0; } .vaxis .dir.r { right: 0; }
.vsub { background: var(--blue-tint); font-size: 12px; font-weight: 700; padding: 6px 8px;
  border-bottom: 1px solid var(--grid-grey); color: var(--cphs-blue); }
.vrow.vgroup .vlabel { font-weight: 400; }

/* Bar table (school overview): subjects down, years across. */
.bartable-wrap { overflow-x: auto; border-top: 2px solid var(--cphs-blue); }
.bartable { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; min-width: 640px; }
.bartable thead tr { background: none; }
.bartable th { color: var(--cphs-blue); background: var(--white); border-bottom: 2px solid var(--cphs-gold);
  text-align: center; padding: 6px 4px; font-size: 12.5px; white-space: nowrap; }
.bartable th small { display: block; font-weight: 400; color: var(--text-grey); font-size: 11px; }
.bartable th:first-child { text-align: left; width: 160px; padding-left: 8px; }
.bartable td { padding: 0 6px; border-bottom: 1px solid var(--grid-grey); height: 26px; }
.bartable td + td, .bartable th + th { border-left: 1px solid var(--grid-grey); }
.bartable tbody tr:nth-child(even) > td { background: none; }
.bartable td:first-child { padding-left: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bartable tr.all td { font-weight: 700; border-bottom: 2px solid var(--grid-grey); height: 32px; }
.bartable td a { display: block; }
.bartable tbody tr:hover > td { background: var(--blue-tint); }
.bartable svg { display: block; width: 100%; height: 20px; overflow: visible; }
.bartable .nil { display: block; text-align: center; color: var(--grid-grey); }
.bartable .nil.muted { color: var(--text-grey); font-size: 11px; }

/* Dot (unit) chart: one square per pupil, stacked in bins. */
.spread { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  align-items: end; border-bottom: 1.5px solid var(--text-grey); border-top: 2px solid var(--cphs-blue); }
.spread-bin { display: flex; flex-wrap: wrap-reverse; justify-content: center; align-content: flex-start;
  gap: 2px; padding: 12px 2px 3px; height: 100%; }
.spread-bin.zero { background: var(--blue-tint); }
.dot { width: 16px; height: 16px; border-radius: 2px; border: 1.5px solid; display: inline-flex;
  align-items: center; justify-content: center; font-size: 10px; font-weight: 700; line-height: 1; color: var(--white); }
a.dot:hover { text-decoration: none; outline: 2px solid var(--cphs-blue); outline-offset: 1px; color: var(--white); }
.dot.neg  { border-color: var(--status-red);   background: var(--status-red-bg); }
.dot.pos  { border-color: var(--status-green); background: var(--status-green-bg); }
.dot.zero { border-color: var(--text-grey);    background: var(--white); }
.dot:not(.hit) { color: var(--text-grey); }
.dot.hit.neg  { background: var(--status-red); }
.dot.hit.pos  { background: var(--status-green); }
.dot.hit.zero { background: var(--text-grey); }
.spread-axis { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  font-size: 11px; font-weight: 700; text-align: center; padding-top: 4px; }
.spread-dir { display: flex; justify-content: space-between; font-size: 11px; font-style: italic; margin-top: 2px; }

/* The five-second rule: axis words, how to read, sub-headings. */
.viz-axis { font-size: 12px; margin: 0 0 6px; }
.viz-how { font-size: 12px; margin: 8px 0 0; max-width: 110ch; }
.viz-sub { font-size: 14px; font-weight: 700; color: var(--cphs-blue); margin: 18px 0 8px; }
.viz-lead { font-size: 14px; margin: 0 0 10px; }
.drop-table { max-width: 900px; }
.vaxis .tick.zero { color: var(--text-grey); font-style: italic; }
.vaxis-words { grid-column: 2; display: flex; justify-content: space-between; font-size: 11px; font-weight: 400; font-style: italic; padding: 0 12px 4px; }
.spread-zero { font-style: italic; }

/* Small line chart: % on target by collection (school overview). */
.viz-q-small { font-size: 15px; }
.trend { display: grid; grid-template-columns: 40px minmax(0, 1fr); grid-template-rows: 220px auto;
  border-top: 2px solid var(--cphs-blue); padding-top: 6px; max-width: 900px; }
.trend-y { position: relative; font-size: 11px; }
.trend-y span { position: absolute; right: 6px; transform: translateY(-50%); }
.trend-plot { width: 100%; height: 220px; overflow: visible; }
.trend-x { grid-column: 2; position: relative; height: 20px; font-size: 11px; font-weight: 700; }
.trend-x span { position: absolute; top: 4px; transform: translateX(-50%); white-space: nowrap; }
.gl-base { stroke: var(--text-grey); stroke-width: 1; }
.tl line { stroke-width: 2; fill: none; }
.tl circle { fill: var(--white); stroke-width: 2; }
.tl-blue line, .tl-blue circle, .tl-blue .mk-mockpt { stroke: var(--cphs-blue); }
.tl-grey line, .tl-grey circle, .tl-grey .mk-mockpt { stroke: var(--text-grey); }
.tl:hover line { stroke-width: 3.5; }
.mk-mockpt { fill: var(--white); stroke: var(--text-grey); stroke-width: 1.5; }
.tl-label { font-size: 11px; font-weight: 700; fill: var(--text-grey);
  paint-order: stroke; stroke: var(--white); stroke-width: 3px; }

/* Flag counts as tiles that open their lists. Flat and ruled. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border-top: 2px solid var(--cphs-blue); border-bottom: 1px solid var(--grid-grey); margin-bottom: 28px; }
.tile { display: block; padding: 10px 14px; border-left: 1px solid var(--grid-grey); color: var(--text-grey); }
.tile:first-child { border-left: none; }
a.tile:hover { text-decoration: none; background: var(--blue-tint); }
a.tile:hover .tile-label { text-decoration: underline; }
.tile-n { font-size: 26px; font-weight: 700; line-height: 1.15; color: var(--text-grey); }
.tile-label { font-size: 12px; color: var(--cphs-blue); font-weight: 700; }

/* "Show data": the numbers behind the chart. */
.show-data { margin: 14px 0 24px; }
.show-data > summary { display: inline-block; font-size: 13px; font-weight: 700; padding: 6px 12px;
  border: 1px solid var(--grid-grey); border-radius: var(--radius-sm); list-style: none; }
.show-data > summary::-webkit-details-marker { display: none; }
.show-data > summary::before { content: '+ '; }
.show-data[open] > summary::before { content: '\2212  '; }
.show-data > summary:hover { border-color: var(--cphs-blue); }
.show-data[open] > summary { margin-bottom: 14px; }

/* Short facts line (pupil profile). */
.facts { display: flex; flex-wrap: wrap; border-top: 1px solid var(--grid-grey);
  border-bottom: 1px solid var(--grid-grey); margin: 0 0 24px; font-size: 12px; }
.facts > div { padding: 8px 18px; border-left: 1px solid var(--grid-grey); }
.facts > div:first-child { border-left: none; padding-left: 8px; }
.facts b { display: block; font-size: 17px; color: var(--text-grey); }

@media (max-width: 900px) {
  .vrow { grid-template-columns: minmax(110px, 160px) minmax(0, 1fr) minmax(64px, 100px); column-gap: 8px; }
  .dot { width: 13px; height: 13px; font-size: 8.5px; }
}
@media print {
  .show-data:not([open]) { display: none; }
  .viz, .vrow { break-inside: avoid; }
}

/* ── SECONDARY TEXT ──
   There is only one text colour, so supporting lines are set apart by
   size, weight and spacing instead: 12px, regular, slightly open.
   Last in the file so it settles each element's own size rule. */
.text-secondary,
.breadcrumb, .student-group, .metric-sub, .quick-desc,
.cc-stat-label, .alert-group, .alert-subject, .form-hint, .file-drop-hint,
.stu-card-meta, .fac-tile-count, .yg-summary-muted, .hero-multicat-note,
.lens-item-role, .nav-search-meta, .elsewhere-tag, .login-footer {
  font-size: 12px; font-weight: 400; letter-spacing: 0.01em; line-height: 1.5;
}

/* Small multiples (item B): one small trend chart per year group. */
.tsm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px 24px;
  border-top: 2px solid var(--cphs-blue); padding-top: 8px; }
.tsm { margin: 0; min-width: 0; }
.tsm figcaption { font-size: 12px; color: var(--text-grey); margin-bottom: 2px; white-space: nowrap; }
.tsm figcaption b { color: var(--cphs-blue); font-size: 13px; }
.tsm-plot { display: block; width: 100%; height: 96px; overflow: visible; }
.tsm-plot .tl circle { r: 3; }
.tsm-x { position: relative; height: 16px; font-size: 10px; font-weight: 700; }
.tsm-x span { position: absolute; top: 2px; transform: translateX(-50%); white-space: nowrap; }
.tsm-y { font-size: 9px; fill: var(--text-grey); }
