:root {
  --accent: #E60000;
  --accent-dark: #c20000;
  --accent-tint: #fdecec;
  --ink: #212529;
  --muted: #5f666d;
  --bg: #f4f6f9;
  --border: #c2c8cf;
  --success-bg: #d4edda;
  --success-text: #155724;
  --success: #2e9e4f;
  --warning-bg: #fff3cd;
  --warning: #c89b04;
  --warning-text: #856404;
  /* Fixed score buckets — anchors mirror _COLOUR_STOPS in routes/results.py; keep in sync. */
  --score-neg: #d9534f;        /* red */
  --score-zero: #e0a800;       /* amber — fills/markers */
  --score-zero-text: #b8860b;  /* darker amber — legible as text on light */
  --score-pos: #1e7e34;        /* green */
  /* Glossary term chip. Blue-grey on purpose: red is a selected answer and a negative score. */
  --term-tint: #e8edf3;
  --term-ink: #1a3a5c;
  --term-line: #6b89a8;
  --radius: 8px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { overflow-y: scroll; }
/* clip, not hidden: beside html's own overflow, hidden makes body a scroll
   container that never scrolls, and nothing inside it can be position: sticky
   (the Useful Links filter box, the action plan's priority list). hidden stays
   first as the fallback for a browser without clip. */
body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; color: var(--ink); background: var(--bg); line-height: 1.6; overflow-x: hidden; overflow-x: clip; }
header { background: var(--ink); color: white; padding: 16px; display: flex; align-items: center; justify-content: space-between; border-bottom: #484848 15px solid; position: relative; }
header h1 { font-size: 20px; font-weight: 700; }
/* The right side holds only the account menu (_account_menu.html), in the corner, so
   nothing in the header tracks the content column: that is 860px on some pages and
   --wide on others, and a link lined up with one would float or jump on the other.
   The right side takes only what the menu needs and the logo + title side takes the
   rest (min-width: 0 so the title wraps rather than push the menu off at mid widths). */
.header-side { flex: 1 1 0; display: flex; align-items: center; gap: 16px; min-width: 0; }
.header-side-right { flex: 0 0 auto; justify-content: flex-end; }
/* Account menu: an outlined button (the old Sign Out button's box) that opens a white
   panel hanging from the header's right edge. A <details>, so it works without
   JavaScript; the partial's script adds outside-click and Escape to close it. */
.account-menu { position: relative; }
.account-button { display: inline-flex; align-items: center; gap: 6px; color: #fff; font-size: 14px; font-weight: 600; line-height: normal; border: 1px solid rgba(255,255,255,0.4); padding: 7px 12px; border-radius: 5px; white-space: nowrap; cursor: pointer; list-style: none; user-select: none; transition: background-color 0.15s, border-color 0.15s; }
.account-button::-webkit-details-marker { display: none; }
.account-button:hover, .account-menu[open] .account-button { background: rgba(255,255,255,0.12); border-color: rgba(255,255,255,0.7); }
.account-button:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.account-button svg { width: 1.2em; height: 1.2em; flex-shrink: 0; }
.account-button .account-chevron { width: 0.85em; height: 0.85em; opacity: 0.8; transition: transform 0.15s; }
.account-menu[open] .account-chevron { transform: rotate(180deg); }
.account-panel { position: absolute; right: 0; top: calc(100% + 8px); z-index: 50; min-width: 240px; max-width: calc(100vw - 16px); background: #fff; color: var(--ink); border: 1px solid #dee2e6; border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0,0,0,0.12); overflow: hidden; }
.account-who { display: flex; flex-direction: column; gap: 2px; padding: 10px 16px; border-bottom: 1px solid #e9ecef; }
.account-who-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.account-email { font-size: 14px; font-weight: 600; line-height: 1.3; word-break: break-all; }
.account-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 16px; font: inherit; font-size: 14px; line-height: 1.3; color: var(--ink); text-decoration: none; text-align: left; background: none; border: 0; cursor: pointer; }
.account-item:hover, .account-item:focus-visible { background: #f8f9fa; color: var(--ink); }
.account-item:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.account-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--muted); }
.account-panel form { margin: 0; border-top: 1px solid #e9ecef; }
/* Below 560px the title hides and the button drops to icon + chevron. The word is
   clipped rather than display: none, so the button is still named "Account". */
@media (max-width: 560px) {
  header { padding: 8px; }
  .header-title { display: none; }
  .account-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 480px) { .status-row, .title-row { flex-direction: column; align-items: flex-start !important; gap: 10px; } }
.container { max-width: 860px; margin: 40px auto; padding: 0 20px 60px; }
.page-landing .container { margin-bottom: 0; }
h2 { font-size: 22px; margin-bottom: 8px; color: var(--ink); }
h3 { font-size: 17px; color: var(--ink); }
a { color: var(--accent); }
a:hover { color: var(--accent-dark); }
.back-link { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 16px; padding: 6px 14px; color: var(--muted); font-size: 14px; line-height: 1.2; background: #fff; border: 1px solid var(--border); border-radius: 5px; text-decoration: none; transition: background-color 0.15s, border-color 0.15s, color 0.15s; }
.back-link:hover { background: var(--bg); border-color: #9aa1a9; color: var(--ink); }
.text-muted { color: var(--muted); }
/* one or two lines under a page's h2 saying what the page is for (register, add a school) */
.page-lead { color: var(--muted); font-size: 15px; line-height: 1.55; margin: 0 0 20px; }
.card { background: white; border-radius: var(--radius); padding: 32px; box-shadow: 0 4px 8px rgba(0,0,0,0.06); margin-bottom: 24px; }
.card-title { font-size: 17px; color: var(--ink); margin-bottom: 4px; }
/* narrow centred column for the sign-in card (and its flash/sent notices) on /retrieve */
.auth-panel { max-width: 560px; margin: 8px auto 0; }
.auth-panel .card { padding: 40px 36px; }
.error-banner { background: #fde8e8; border-left: 4px solid var(--accent); padding: 12px 16px; border-radius: 4px; margin-bottom: 20px; color: #a31515; }
/* status notices — green for success, amber for warnings (mirror .error-banner) */
.notice { padding: 12px 16px; border-radius: 4px; margin-bottom: 20px; font-size: 14px; border-left: 4px solid; }
.notice-success { background: var(--success-bg); border-left-color: var(--success); color: var(--success-text); }
.notice-warning { background: var(--warning-bg); border-left-color: var(--warning); color: var(--warning-text); }
label { display: block; font-weight: 700; margin-bottom: 4px; margin-top: 16px; font-size: 15px; }
.card label:first-child { margin-top: 0; }
.req { color: var(--accent); margin-left: 2px; }
input[type=text], input[type=email], select { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 5px; font-size: 15px; font-family: inherit; background: white; }
input[type=text]:focus, input[type=email]:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(230,0,0,0.15); }
/* custom chevron — the native one sits flush against the right edge, which looks stranded on full-width selects */
select { appearance: none; padding-right: 38px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23555555' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; background-size: 16px; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; background: #484848; color: white; padding: 10px 24px; border: none; border-radius: 5px; font-size: 15px; font-family: inherit; line-height: normal; cursor: pointer; margin-top: 24px; text-decoration: none; transition: background-color 0.15s, box-shadow 0.15s; }
.btn svg { width: 1.1em; height: 1.1em; flex-shrink: 0; }
.btn:hover { background: #2e2e2e; color: white; }
.btn:focus-visible { outline: 3px solid rgba(72,72,72,0.35); outline-offset: 2px; }
.btn-secondary { background: #076a9c; color: white; border: none; }
.btn-secondary:hover { background: #055a87; color: white; }
.btn-dark { background: var(--ink); }
.btn-dark:hover { background: #000; }
.btn-danger { background: white; color: var(--accent); border: 1px solid var(--accent); }
.btn-danger:hover { background: var(--accent); color: white; }
.btn-sm { padding: 8px 16px; font-size: 14px; margin-top: 0; }
.btn:disabled { opacity: 0.85; cursor: default; }
/* "Coming Soon" placeholder button: inert on purpose, so the hover rule is
   pinned to the same values as the resting state (a disabled button still
   matches :hover in browsers, and a colour change there reads as pressable). */
.btn-soon, .btn-soon:hover { background: #e9ecef; color: var(--muted); border: none; opacity: 1; cursor: default; }
/* in-flight spinner for submit buttons (Save, Submit All Responses) */
.btn-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.45); border-top-color: #fff; border-radius: 50%; animation: btn-spin 0.6s linear infinite; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn-spinner { animation: none; } }
.domain-chips { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-bottom: 16px; }
@media (max-width: 560px) { .domain-chips { grid-template-columns: repeat(2, 1fr); } }
/* Section icons (icons.domain_icon, named per section in questions.json). Always
   beside the section's name, never instead of it, and one neutral colour
   everywhere: on the results page colour already means score. */
.domain-name { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.domain-icon { flex-shrink: 0; }
.domain-icon-badge { width: 30px; height: 30px; border-radius: 50%; background: #eef0f3; color: var(--ink); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.domain-icon-badge .domain-icon { width: 17px; height: 17px; }
.domain-icon-badge.lg { width: 40px; height: 40px; }
.domain-icon-badge.lg .domain-icon { width: 22px; height: 22px; }
.domain-icon-badge.sm { width: 20px; height: 20px; }
.domain-icon-badge.sm .domain-icon { width: 12px; height: 12px; }
.domain-name.sm { gap: 7px; }
.meter { background: #e9ecef; border-radius: 20px; height: 12px; overflow: hidden; margin: 8px 0 4px; }
.meter-fill { background: var(--success); height: 100%; border-radius: 20px; transition: width 0.3s ease; }
.option { display: flex; gap: 13px; align-items: flex-start; padding: 8px 12px; border-radius: 8px; border: 1px solid #dde0e4; font-weight: 400; cursor: pointer; transition: background-color 0.12s, border-color 0.12s; margin-top: 0; }
.option:not(.readonly):hover { background: #f7f8fa; border-color: var(--border); }
.option input[type=radio] { position: absolute; opacity: 0; width: 0; height: 0; }
.radio-dot { width: 20px; height: 20px; border: 2px solid #c2c8cf; border-radius: 50%; flex-shrink: 0; margin-top: 2px; position: relative; transition: border-color 0.12s; }
.option input:checked ~ .radio-dot, .radio-dot.checked { border-color: var(--accent); }
.option input:checked ~ .radio-dot::after, .radio-dot.checked::after { content: ""; position: absolute; top: 3px; left: 3px; right: 3px; bottom: 3px; border-radius: 50%; background: var(--accent); }
.option input:focus-visible ~ .radio-dot { box-shadow: 0 0 0 3px rgba(230,0,0,0.18); }
.option:has(input:checked), .option.selected { background: var(--accent-tint); border-color: var(--accent); }
.option.readonly { cursor: default; }
.score-num { font-weight: 700; color: var(--accent); margin-right: 6px; }
/* info "i" button + its popover (e.g. the Sharing card) */
.info-btn { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; padding: 2px; cursor: pointer; color: var(--muted); transition: color 0.12s; }
.info-btn svg { width: 17px; height: 17px; }
.info-btn:hover { color: var(--ink); }
.info-btn:focus-visible { outline: 3px solid rgba(33,37,41,0.3); outline-offset: 2px; border-radius: 50%; }
.info-pop { display: none; position: absolute; left: 0; top: calc(100% + 8px); z-index: 100; width: min(340px, 80vw); background: white; border: 1px solid #dee2e6; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); padding: 14px 16px; font-size: 13.5px; font-weight: 400; color: #555; line-height: 1.55; }
/* dashed empty-state box (e.g. "not shared with anyone yet") */
.empty-state { display: flex; align-items: center; justify-content: center; gap: 8px; background: #f8f9fa; border: 1px dashed var(--border); border-radius: 8px; padding: 16px; color: var(--muted); font-size: 14px; }
.empty-state svg { width: 17px; height: 17px; flex-shrink: 0; }
/* landing sections */
.section { margin-top: 56px; }
/* fsm-style landing type: display-6 titles, light 20px leads */
.section-title { font-size: clamp(26px, 1.375rem + 1.5vw, 40px); font-weight: 300; line-height: 1.2; margin-bottom: 8px; }
.section-lead { color: var(--muted); font-size: 20px; font-weight: 300; margin-bottom: 20px; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 16px; }
.step { background: white; border: 1px solid var(--border); border-radius: 10px; padding: 22px; }
.step-num { width: 34px; height: 34px; border-radius: 50%; background: var(--accent-tint); color: var(--accent); font-weight: 800; display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }
.step h3 { font-size: 18px; margin-bottom: 6px; }
.step p { color: var(--muted); font-size: 14px; }
.faq { background: white; border: 1px solid var(--border); border-radius: 8px; margin-bottom: 10px; }
.faq summary { padding: 18px 20px; font-weight: 600; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--accent); font-size: 24px; font-weight: 400; line-height: 1; flex-shrink: 0; }
.faq[open] summary::after { content: "\2013"; }
.faq-body { padding: 0 18px 16px; color: #444; }
.quote { border-left: 4px solid var(--accent); padding: 4px 0 4px 16px; margin: 18px 0; color: #333; }
.quote p { font-style: italic; }
.quote cite { display: block; font-style: normal; font-weight: 700; color: var(--muted); font-size: 13px; margin-top: 8px; }
.video-embed { position: relative; width: 100%; padding-top: 56.25%; border-radius: 10px; overflow: hidden; background: #000; margin-bottom: 12px; }
.video-embed iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; }
/* testimonial carousel */
.testimonial-card { margin-bottom: 0; box-shadow: 0 8px 24px rgba(0,0,0,0.1); }
@media (max-width: 560px) { .testimonial-card { padding: 20px; } }
.carousel { position: relative; }
.carousel-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: none; -ms-overflow-style: none; }
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-slide { flex: 0 0 100%; scroll-snap-align: center; padding: 4px; }
.carousel-eyebrow { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin-bottom: 10px; }
.carousel-controls { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 18px; }
.carousel-arrow { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border); background: #fff; color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background-color 0.12s, border-color 0.12s; }
.carousel-arrow:hover { background: #f1f3f6; border-color: #b9c0c8; }
.carousel-arrow:focus-visible { outline: 3px solid rgba(230,0,0,0.35); outline-offset: 2px; }
.carousel-dots { display: flex; gap: 8px; align-items: center; }
.carousel-dots button { width: 9px; height: 9px; border-radius: 50%; border: none; background: #c2c8cf; cursor: pointer; padding: 0; transition: background-color 0.12s, transform 0.12s; }
.carousel-dots button.active { background: var(--accent); transform: scale(1.2); }
/* gradient hero — fsm.lgfl.net style (soft red, big light heading, wave below) */
.hero-gradient { background: linear-gradient(to bottom, #d52c2c, #dd5757); color: #fff; text-align: center; padding: 80px 20px 50px; position: relative; }
@media (max-width: 1024px) { .hero-gradient { padding: 70px 15px 50px; } }
@media (max-width: 768px) { .hero-gradient { padding: 50px 10px 30px; } }
@media (max-width: 480px) { .hero-gradient { padding: 35px 10px 30px; } }
.hero-inner { max-width: 800px; margin: 0 auto; text-wrap: balance; }
.hero-image { opacity: .75; margin-top: 40px; margin-bottom: 80px; height: 300px; max-width: 100%; object-fit: contain; }
@media (max-width: 1366px) { .hero-image { height: 225px; margin-top: 30px; margin-bottom: 50px; } }
@media (max-width: 1024px) { .hero-image { height: 200px; margin-top: 20px; margin-bottom: 50px; } }
@media (max-width: 768px) { .hero-image { height: 180px; margin-top: 15px; margin-bottom: 50px; } }
@media (max-width: 480px) { .hero-image { height: 160px; margin-top: 10px; margin-bottom: 50px; } }
.hero-gradient h1 { font-size: clamp(30px, 1.475rem + 2.7vw, 56px); font-weight: 300; margin-bottom: 12px; line-height: 1.2; }
.hero-lead { font-size: 20px; font-weight: 300; opacity: 0.95; max-width: 580px; margin: 0 auto 16px; }
/* layered wave dividers (svg markup lives in landing.html, copied from fsm.lgfl.net) */
.wave-container { position: absolute; bottom: 0; left: 0; width: 100%; overflow: hidden; line-height: 0; transform: rotate(180deg); }
.wave-container svg { position: relative; display: block; width: calc(100% + 1.3px); height: 70px; }
.wave-container .shape-fill { fill: #f9f9f9; } /* must match the top of the .landing-bg gradient */
.footer-wave-container { position: relative; width: 100%; overflow: hidden; line-height: 0; margin-bottom: -2px; background-color: #dcdcdc; } /* bottom of the .landing-bg gradient */
.footer-wave-container svg { position: relative; display: block; width: calc(100% + 1.3px); height: 70px; }
/* subtle card gradient, fsm-style */
.step { background: linear-gradient(to bottom, #ffffff, #f7f8fa); }
/* dark gradient footer (matches fsm.lgfl.net) */
.site-footer { background: linear-gradient(to bottom, #1f1f1f, #000); color: #fff; text-align: center; padding: 48px 20px; }
.site-footer a { color: #fff; }
.footer-logo { display: inline-block; margin-bottom: 4px; }
.footer-logo img { height: 120px; }
.footer-reg { font-weight: 300; font-size: 13px; line-height: 1.65; opacity: 0.85; max-width: 660px; margin: 0 auto 16px; }
.footer-links { font-size: 14px; margin-bottom: 20px; }
.footer-links a { text-decoration: underline; }
/* analytics note + opt-out; the button is styled as a link so it reads as part of
   the footer's small print rather than a call to action */
.footer-analytics { font-weight: 300; font-size: 12px; line-height: 1.65; opacity: 0.75; max-width: 660px; margin: 0 auto 20px; }
.footer-analytics form { display: inline; }
.footer-analytics button { background: none; border: 0; padding: 0; margin: 4px 0 0; width: auto; color: #fff; font: inherit; text-decoration: underline; cursor: pointer; }
.footer-social-label { font-size: 14px; margin-bottom: 12px; }
.social-icons { display: flex; gap: 16px; justify-content: center; }
.social-icons img { height: 30px; width: 30px; transition: transform 0.15s; }
.social-icons a:hover img { transform: translateY(-2px); }
/* buttons for coloured backgrounds (hero + dark CTA) */
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 10px; }
.hero-actions .btn { margin-top: 0; padding: 12px 32px; font-size: 16px; }
.btn-light { background: #fff; color: var(--ink); border: 1px solid var(--ink); }
.btn-light:hover { background: #eee; color: var(--ink); }
.btn-charcoal { background: #484848; color: #fff; border: 1px solid var(--ink); }
.btn-charcoal:hover { background: var(--ink); color: #fff; }
/* landing sections on a single fsm-style gradient (bands are transparent) */
.landing-bg { position: relative; left: 50%; width: 100vw; margin-left: -50vw; margin-top: -40px; margin-bottom: -60px; background: linear-gradient(to bottom, #f9f9f9, #dcdcdc); }
.band { padding: 52px 20px; }
.band-inner { max-width: 920px; margin: 0 auto; }
#how .band-inner { max-width: 820px; }
.band .section-lead { margin-bottom: 20px; }
/* "Still in Development" strip between the site header and the landing hero, so it is
   above the fold; kept short so the hero's buttons barely move. Full width and centred,
   the icon inline in the text so it stays with the first line when the text wraps. */
.dev-notice { background: #fff; border-bottom: 1px solid var(--border); padding: 12px 20px; text-align: center; }
.dev-notice svg { display: inline-block; width: 18px; height: 18px; color: var(--accent); vertical-align: -4px; margin-right: 8px; }
.dev-notice p { color: var(--muted); font-size: 14px; }
.dev-notice strong { color: var(--ink); }
.dev-notice a { overflow-wrap: anywhere; }

/* ===== Confirm sign-in (verify.html) ===== */
.verify-card { text-align: center; max-width: 520px; margin-left: auto; margin-right: auto; padding: 48px 40px 36px; animation: verify-in 0.18s ease-out; }
.verify-card h2 { margin-bottom: 24px; }
.verify-who { font-size: 14px; margin: 0 0 2px; }
.verify-name { font-size: 18px; font-weight: 700; color: var(--ink); margin: 0 0 2px; overflow-wrap: anywhere; }
.verify-email { font-size: 14px; margin: 0; overflow-wrap: anywhere; }
.verify-btn { width: 100%; margin-top: 24px; padding: 12px 24px; font-size: 16px; }
.verify-note { border-top: 1px solid #e5e8ec; margin: 28px 0 0; padding-top: 18px; font-size: 13.5px; line-height: 1.5; }
@keyframes verify-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .verify-card { animation: none; } }

/* ===== Domain question form (domain.html) ===== */
.sticky-actions { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-top: 1px solid #e0e0e0; box-shadow: 0 -2px 10px rgba(0,0,0,0.08); z-index: 100; padding: 12px 20px; }
.sticky-actions-inner { max-width: 860px; margin: 0 auto; display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.sticky-spacer { height: 72px; }
/* The question form's bar: where you are on the left (a progress track, the count and
   the filter that acts on it), Save last on the right. */
.q-progress { display: inline-flex; align-items: center; gap: 10px; }
.q-track { width: 64px; height: 6px; border-radius: 3px; background: #e2e5e9; overflow: hidden; }
.q-track-fill { display: block; width: 0; height: 100%; background: var(--ink); transition: width 0.2s ease-out; }
.q-count { font-size: 14px; line-height: 1; color: var(--muted); white-space: nowrap; }
.q-count strong { color: var(--ink); }
.q-toggle { display: inline-flex; align-items: center; gap: 7px; margin: 0; font-size: 14px; font-weight: 400; line-height: 1; color: var(--muted); cursor: pointer; user-select: none; white-space: nowrap; }
.q-toggle input { width: 16px; height: 16px; margin: 0; cursor: pointer; }
.q-save { margin-left: auto; }
/* On a phone the three don't fit one row: progress takes the first, its track
   stretching to fill it, and the filter and Save share the second. */
@media (max-width: 540px) {
  .q-progress { flex-basis: 100%; }
  .q-track { flex: 1; }
  .sticky-spacer { height: 104px; }
}
@media (prefers-reduced-motion: reduce) { .q-track-fill { transition: none; } }
/* Glossary and Back share the title row, the Glossary styled as Back's twin. On a
   phone the pair moves above the title (the column is reversed), rather than
   squeezing a long section name like "Network, Infrastructure and IT" beside them. */
.domain-title-actions { display: flex; gap: 8px; flex-shrink: 0; }
.domain-title-actions .back-link { margin-bottom: 0; }
.glossary-open { font-family: inherit; color: var(--ink); cursor: pointer; }
.glossary-open svg { width: 15px; height: 15px; flex-shrink: 0; }
@media (max-width: 480px) {
  .domain-title-row { flex-direction: column-reverse; }
  .domain-title-actions { align-self: stretch; justify-content: space-between; }
}
/* A glossary term in the question wording (glossary.py marks each term's first use in a
   question) and the one popover they all share. The box only has a border and padding
   while it has content: shut, it is an empty live region, so it must draw nothing. */
/* The negative margin hands back most of the padding, so the chip doesn't push the text
   apart ("school/MAT" would otherwise read as "school/ MAT"). */
.gloss-term { background: var(--term-tint); color: var(--term-ink); border-radius: 4px; padding: 0 3px; margin: 0 -2px; -webkit-box-decoration-break: clone; box-decoration-break: clone; text-decoration: underline dotted; text-decoration-color: var(--term-line); text-decoration-thickness: 1.5px; text-underline-offset: 3px; cursor: help; }
.gloss-term:hover, .gloss-term[aria-expanded="true"] { background: #d9e3ee; text-decoration-color: var(--term-ink); }
.gloss-term:focus-visible { outline: 3px solid rgba(33,37,41,0.3); outline-offset: 2px; }
.gloss-pop { position: absolute; top: 0; left: 0; z-index: 110; width: max-content; max-width: min(320px, calc(100vw - 32px)); }
.gloss-pop:not(:empty) { background: #fff; border: 1px solid #dee2e6; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); padding: 10px 14px; font-size: 14px; line-height: 1.5; color: #555; }
.gloss-pop strong { display: block; color: var(--term-ink); }
/* The same terms listed at the foot of each card, for print only (see @media print) */
.q-terms { display: none; margin-top: 14px; padding-top: 10px; border-top: 1px solid #eee; font-size: 14px; color: var(--muted); }
.q-terms-label { font-weight: 700; color: var(--ink); }
.q-terms dl { margin: 4px 0 0; }
.q-terms dt, .glossary-item dt { font-weight: 700; color: var(--ink); }
.q-terms dd { margin: 0 0 6px; }
/* Glossary panel: a native <dialog> wearing the share modal's box. The element selector
   outranks .modal-box, which comes later: its position: relative would compute to
   absolute in the top layer and open the panel at the top of the document rather than
   of the screen. margin: auto is what centres a dialog, and the * reset strips it. */
dialog.glossary-dialog { position: fixed; inset: 0; margin: auto; height: fit-content; border: 0; max-width: 460px; width: calc(100% - 32px); max-height: 80vh; padding: 24px; color: var(--ink); }
dialog.glossary-dialog[open] { display: flex; flex-direction: column; }
.glossary-dialog::backdrop { background: rgba(0,0,0,0.5); }
.glossary-dialog input[type=search] { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 5px; font-size: 15px; font-family: inherit; margin-bottom: 12px; }
.glossary-list { overflow-y: auto; min-height: 0; font-size: 14px; color: var(--muted); }
/* Group headings are opaque bands pinned to the top of the scrolling list, each for as
   long as its own group is in view, so you always know which group you're reading.
   Square corners: rounded ones let the row scrolling underneath show through. */
.glossary-heading { position: sticky; top: 0; z-index: 1; display: flex; justify-content: space-between; align-items: center; background: #eef0f3; color: var(--ink); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 6px 10px; margin: 14px 0 4px; }
.glossary-count { font-weight: 400; letter-spacing: 0; color: var(--muted); }
.glossary-group:first-child .glossary-heading { margin-top: 0; }
.glossary-item { padding: 6px 0; border-bottom: 1px solid #f0f0f0; }
.glossary-item dd { margin: 0; }
.glossary-empty { margin: 8px 0 0; }
/* Collapsed (answered) question summary row.
   The summary and the answer body each sit in their own grid-rows collapser on the
   SAME duration and curve, so the summary grows in exactly as the body shrinks out
   and the card's height moves once, in one direction. (The summary used to be
   swapped in with display:none -> flex, which added its whole height in a single
   frame before the card had started easing down — the jolt at the start of a close.)
   --q-dur is the one knob for all of it: zeroing it drops every transition in this
   section at once, which is how both reduced motion and the first paint are handled. */
.q-card { --q-dur: 0.28s; --q-ease: cubic-bezier(0.65, 0, 0.35, 1); transition: padding var(--q-dur) var(--q-ease), margin-bottom var(--q-dur) var(--q-ease); }
.q-card.collapsed { padding: 16px 20px; margin-bottom: 12px; }
.q-summary-wrap, .q-collapse { display: grid; }
.q-summary-wrap > .q-summary, .q-collapse > .q-body { overflow: hidden; min-height: 0; }
.q-card .q-summary { display: flex; width: 100%; background: none; border: 0; padding: 0; margin: 0; font: inherit; text-align: left; cursor: pointer; align-items: center; gap: 12px; color: var(--ink); }
/* Summary: absent when open, present when collapsed. visibility flips on immediately
   so it can fade in, and off only after the animation so it can fade out — which also
   keeps a zero-height summary unfocusable and out of the accessibility tree (the
   question text is repeated in the body, so an open card would otherwise say it twice). */
.q-summary-wrap { grid-template-rows: 0fr; opacity: 0; visibility: hidden; transition: grid-template-rows var(--q-dur) var(--q-ease), opacity var(--q-dur) var(--q-ease), visibility 0s linear var(--q-dur); }
.q-card.collapsed .q-summary-wrap { grid-template-rows: 1fr; opacity: 1; visibility: visible; transition: grid-template-rows var(--q-dur) var(--q-ease), opacity var(--q-dur) var(--q-ease), visibility 0s; }
/* Body: the mirror image of the summary. */
.q-collapse { grid-template-rows: 1fr; opacity: 1; transition: grid-template-rows var(--q-dur) var(--q-ease), opacity var(--q-dur) var(--q-ease); }
.q-card.collapsed .q-collapse { grid-template-rows: 0fr; opacity: 0; }
/* The script collapses answered cards just after first paint; q-no-anim stops that
   playing as an animation on load. Both overrides must stay after the .q-card rule. */
.q-no-anim .q-card { --q-dur: 0s; }
@media (prefers-reduced-motion: reduce) { .q-card { --q-dur: 0s; } }
.q-summary:hover .q-summary-text { text-decoration: underline; text-decoration-color: var(--border); }
.q-summary-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; } /* min-width:0 lets the answer line ellipsise */
.q-summary-text { font-weight: 600; }
.q-summary-answer { font-weight: 400; font-size: 16px; color: var(--muted); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.q-summary-score { flex-shrink: 0; font-weight: 700; font-size: 16px; min-width: 1.4em; text-align: center; }
.q-summary-edit { width: 16px; height: 16px; flex-shrink: 0; color: var(--muted); }
.q-hidden { display: none !important; }

/* ===== Results page (results.html) ===== */
/* The page's type scale, six sizes with one job each, here and in the inline
   styles in results.html: 12 uppercase labels and the small score badges; 14
   secondary text (meta lines, chips, controls, links, captions, notes, tile
   descriptions); 16 what a school reads (questions, descriptors, the ladder,
   section names, tile titles, prose), which is the size it answered them at;
   17 card headings; 22 the page title; 30 the overall score. Pick one of
   these rather than adding a seventh. The header (20) and .btn (15) are site
   chrome. */
.results-bar { position: relative; margin-top: 8px; }
.results-bar .meter { height: 16px; margin: 0; }
/* dotted midpoint (score 0) */
.mid-marker { position: absolute; top: -3px; bottom: -3px; left: 50%; border-left: 2px dotted #9aa3ad; }
/* all-schools average — solid line with a small pin on top (line + triangle share one centre) */
.avg-marker { position: absolute; top: -5px; bottom: -3px; width: 22px; transform: translateX(-50%); cursor: help; }
.avg-marker::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; transform: translateX(-50%); background: #1f1f1f; }
.avg-marker::before { content: ""; position: absolute; left: 50%; top: -1px; transform: translateX(-50%); border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid #1f1f1f; }
/* summary card — two-column hero (overall score | takeaways); stacks on narrow */
.summary-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 28px; align-items: center; }
.summary-takeaways { border-left: 1px solid #eee; padding-left: 28px; display: flex; flex-direction: column; gap: 16px; }
@media (max-width: 560px) {
  .summary-grid { grid-template-columns: 1fr; gap: 20px; }
  .summary-takeaways { border-left: 0; padding-left: 0; border-top: 1px solid #eee; padding-top: 20px; }
}
/* Section bars card: a section's name and score over its bar. */
.section-bar { margin-bottom: 20px; }
.section-bar-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 8px; }
.section-bar-score { font-size: 16px; white-space: nowrap; }
.section-bar-note { font-size: 14px; margin-top: 6px; }
/* A section's name, when it links down to its Your Answers group: plain ink at
   rest, so the card reads as before, and the jump's accent once pointed at. */
.section-bar-link { font-weight: 700; color: inherit; text-decoration: none; }
.section-bar-link:hover, .section-bar-link:focus-visible { color: var(--accent); text-decoration: underline; }
/* The wide width: 1180px by about a 1260px viewport, always leaving 40px each
   side (scrollbar included) so the page never scrolls sideways. --breakout is
   how far a wide card reaches past each side of the column to get there
   (nothing at 900px). 820px is .container's 860px max-width less its 20px
   padding each side: change one, change the other. --breakout is read by the
   dashboard row below and by Useful Links; --wide also by .page-wide. */
:root { --wide: min(1180px, 100vw - 80px); --breakout: calc((820px - var(--wide)) / 2); }
/* A page that goes wide as a whole (compare, the admin area) sets
   body_class "page-wide" rather than marking each element as results does:
   its widths change in one step, at the same 1200px, to the same edges. */
@media (min-width: 1200px) {
  .page-wide .container { max-width: calc(var(--wide) + 40px); }
}
/* The wide page. Once there is room for two cards (1200px), everything marked
   .results-wide (the back link, the title row, the dashboard row, Your Answers
   and the support card) takes the Useful Links width, so the page has one
   pair of edges and the buttons end where the cards do. In the dashboard row
   Summary and Section bars sit side by side: each bar takes one line
   (name | bar | score) and the rows spread to the Summary card's height; the
   Summary card stacks in its narrower column. Print never reaches 1200px, so
   paper keeps the stacked page. */
@media (min-width: 1200px) {
  .results-wide { margin-inline: var(--breakout); }
  .results-dash { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 24px; margin-bottom: 24px; }
  .results-dash > .card { margin-bottom: 0; }
  .results-dash .summary-grid { grid-template-columns: 1fr; gap: 20px; }
  .results-dash .summary-takeaways { border-left: 0; padding-left: 0; border-top: 1px solid #eee; padding-top: 20px; }
  .section-bars { display: flex; flex-direction: column; justify-content: space-between; gap: 14px; }
  /* 230px holds every label on one line but the longest, which wraps rather
     than shortening every bar. A fixed track, so the bars line up. */
  .section-bar { display: grid; grid-template-columns: minmax(0, 230px) minmax(0, 1fr) auto; column-gap: 14px; align-items: center; margin-bottom: 0; }
  .section-bar-head { display: contents; }
  .section-bar .domain-name { grid-column: 1; grid-row: 1; }
  .section-bar .results-bar { grid-column: 2; grid-row: 1; margin-top: 0; }
  .section-bar-score { grid-column: 3; grid-row: 1; min-width: 2.6em; text-align: right; }
  .section-bar-note { grid-column: 2 / -1; margin-top: 4px; }
}
/* answers section (separate card, with score filter) */
.answer-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 18px; }
.fbtn { border: 1px solid var(--border); background: #fff; color: var(--ink); font-size: 14px; font-weight: 600; padding: 4px 12px; border-radius: 14px; cursor: pointer; }
.fbtn:hover { filter: brightness(0.97); }
.fbtn.active { background: var(--ink); color: #fff; border-color: var(--ink); }
/* Sort by rides at the far end of the filter's row, since it narrows nothing;
   on a phone, where the row wraps anyway, it starts its own line at the left. */
.answer-sort { margin-left: auto; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.answer-sort[hidden] { display: none; }
@media (max-width: 560px) { .answer-sort { margin-left: 0; flex-basis: 100%; } }
/* Score filter buttons (_score_mix.html score_filter_buttons): the page's
   colour key. Each carries its score's colour as a swatch the size of an
   answer square, and pressed it takes the same ink fill as All; the white
   ring keeps the deep red and green swatches visible on that fill. */
.fbtn-score { display: inline-flex; align-items: center; gap: 6px; padding-left: 10px; }
.fbtn-sw { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.fbtn-score.active .fbtn-sw { box-shadow: 0 0 0 1px #fff; }
.answer-domain { border-top: 1px solid #eee; }
.answer-domain > summary { padding: 13px 0; font-weight: 700; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.answer-domain > summary::-webkit-details-marker { display: none; }
.answer-domain > summary::after { content: "\25be"; color: var(--muted); }
.answer-domain[open] > summary::after { content: "\25b4"; }
/* Score mix (_score_mix.html): how the answers split across the scale. The
   summary card's bar and the squares on each Your Answers header; the score
   filter buttons above (.fbtn-score) are the key to both (and to the section
   bars). Colours arrive inline from results.colour_for. */
.score-mix { display: flex; gap: 2px; height: 14px; margin-top: 10px; }
.score-mix > span { flex-basis: 0; min-width: 4px; border-radius: 2px; }
/* One square per answer, in a run per score. A run sits further from its
   neighbours than its squares sit from each other, which keeps a -1 run and a
   0 run countable where orange and amber are hard to tell apart. Wraps past
   about 16 squares, so a longer section adds a row rather than crowding its name. */
.answer-mix { margin: 0 4px 0 auto; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 6px; max-width: 196px; }
.answer-mix-run { display: flex; flex-wrap: wrap; gap: 2px; }
.answer-mix-run > span { width: 10px; height: 10px; border-radius: 2px; background: var(--sq); }
/* A phone has no room beside the name: the squares take their own line under
   it, in line with the label (30px badge + 10px gap), and the chevron stays on
   the first line. The name's zero basis is what keeps it there: a name too long
   for one line wraps its own text instead of pushing the chevron down. */
@media (max-width: 560px) {
  .answer-domain > summary { flex-wrap: wrap; row-gap: 8px; }
  .answer-domain > summary > .domain-name { flex: 1 1 0; }
  .answer-domain > summary::after { order: 1; }
  .answer-mix { order: 2; flex-basis: 100%; max-width: none; margin: 0; padding-left: 40px; justify-content: flex-start; }
}
.answer-list { padding-bottom: 10px; }
.answer-row { padding: 14px 0; border-top: 1px solid #f0f0f0; display: grid; grid-template-columns: auto 1fr; column-gap: 14px; align-items: start; transition: background-color 0.6s, box-shadow 0.6s; }
/* The answer whose Useful Links are showing: a light tint while that filter
   holds, and a brief warm one when Back to Answer lands on it. The shadows
   carry the tint a little past the row's edges, which sit on the text. */
.answer-row.is-current { background: #f3f6fa; box-shadow: -10px 0 0 #f3f6fa, 10px 0 0 #f3f6fa; }
.answer-row.is-flash { background: #fdf3d8; box-shadow: -10px 0 0 #fdf3d8, 10px 0 0 #fdf3d8; }
@media (prefers-reduced-motion: reduce) { .answer-row { transition: none; } }
.answer-main { min-width: 0; }
/* score badge — the visual anchor for each answer, colour-coded by score */
.score-badge { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 16px; flex-shrink: 0; }
.score-badge.s-pos { background: #e7f4ec; color: var(--score-pos); }
.score-badge.s-neg { background: #fbeae9; color: var(--score-neg); }
.score-badge.s-zero { background: #fbf3da; color: var(--score-zero-text); }
/* The small inline badge, beside a line of 14px text (the Useful Links
   tiles) or 16px (the ladder). */
.score-badge.sm { width: auto; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 6px; font-size: 12px; }
.answer-q { font-size: 16px; font-weight: 600; color: var(--ink); line-height: 1.5; }
.answer-a { font-size: 16px; color: var(--muted); margin-top: 5px; line-height: 1.5; }
/* Reading text stops at about 80 characters, however wide the card: on the
   wide page a line would otherwise run past 120. The row, its badge and its
   rules still span the card. */
.answer-q, .answer-a, .al-rungs { max-width: 80ch; }
.answer-median { font-size: 14px; margin-top: 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.median-compare { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; white-space: nowrap; padding: 4px 11px; border-radius: 11px; }
/* Only the per-answer badges carry the median tooltip (the overall card reuses
   .median-compare without one), so scope the help cursor to those. */
.answer-median .median-compare { cursor: help; }
.median-compare.above { color: var(--score-pos); background: #e7f4ec; }
.median-compare.below { color: var(--score-neg); background: #fbeae9; }
.median-compare.same { color: var(--muted); background: #f1f3f5; }
/* Folded into the .median-compare badge tooltip on screen; revealed in print
   (see @media print) so the PDF still carries the peer-median figure. */
.median-label { display: none; color: var(--muted); white-space: nowrap; }
.median-label strong { color: var(--ink); }
.adcount { font-weight: 400; font-size: 14px; }
/* A score filter that matches nothing: the same warm grey box as Useful Links'
   "No links match those filters" (.ul-empty). */
.answers-empty { background: #f6f4f2; border-radius: 10px; padding: 20px 18px; font-size: 14px; }
/* See All Answers: the question's whole descriptor ladder, -2 up to +2, behind a
   toggle, with the school's own rung marked. The toggle leads the line it shares
   with the Useful Links jump; opened, it takes the full width, so the jump drops
   below the ladder instead of the toggle moving out from under the pointer. Grey
   rather than accent: it opens in place, where the red jump goes elsewhere. */
.answer-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; margin-top: 8px; }
.answer-actions .ul-jump { margin-top: 0; }
.answer-ladder[open] { flex-basis: 100%; }
.answer-ladder > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; font-size: 14px; font-weight: 600; color: var(--muted); }
.answer-ladder > summary::-webkit-details-marker { display: none; }
.answer-ladder > summary:hover { color: var(--ink); }
.answer-ladder > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.answer-ladder > summary svg { width: 14px; height: 14px; transition: transform 0.12s; }
.answer-ladder[open] > summary svg { transform: rotate(180deg); }
.answer-ladder .al-hide, .answer-ladder[open] .al-show { display: none; }
.answer-ladder[open] .al-hide { display: inline; }
.al-rungs { list-style: none; margin: 8px 0 2px; display: flex; flex-direction: column; gap: 2px; }
.al-rungs li { display: flex; align-items: flex-start; gap: 10px; padding: 5px 8px; border-radius: 6px; font-size: 16px; line-height: 1.5; color: var(--muted); }
.al-rungs li.is-yours { background: #f1f3f5; color: var(--ink); }
/* Centres the 22px badge on the first 24px line of text. */
.al-rungs .score-badge { margin-top: 1px; }
/* A phone indents the ladder by the answer's 34px badge and its 14px gap, which
   leaves 16px text about 20 characters a line. It takes the whole row instead:
   each rung carries its own badge, so it still reads as that answer's list. */
@media (max-width: 560px) { .al-rungs { margin-left: -48px; } }
.al-tag { display: inline-block; margin-left: 4px; padding: 0 8px; border: 1px solid var(--border); border-radius: 10px; font-size: 12px; line-height: 1.5; font-weight: 600; color: var(--muted); white-space: nowrap; vertical-align: 1px; }
/* A compact labelled pill (book icon, soft red): the compare page's help link. */
.answer-help { flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: 12px; border: 1px solid #ecc3c0; background: #fff; color: var(--accent); font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap; transition: background-color 0.12s, color 0.12s, border-color 0.12s; }
.answer-help:hover { border-color: var(--accent); color: var(--accent-dark); background: var(--accent-tint); }
.answer-help svg { width: 13px; height: 13px; flex-shrink: 0; }
/* share modal */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 1000; }
.modal-overlay[hidden] { display: none; }
.modal-box { background: #fff; border-radius: var(--radius); padding: 28px; max-width: 460px; width: 100%; position: relative; box-shadow: 0 12px 40px rgba(0,0,0,0.25); }
.modal-close { position: absolute; top: 10px; right: 14px; background: none; border: none; font-size: 26px; line-height: 1; color: var(--muted); cursor: pointer; padding: 4px; }
.modal-close:hover { color: var(--ink); }
/* quiet text-buttons for the sharing line under the title */
.link-btn { background: none; border: none; padding: 0; font: inherit; font-weight: 600; color: var(--accent); cursor: pointer; }
.link-btn:hover { color: var(--accent-dark); text-decoration: underline; }

/* --- The action plan (_action_plan.html): card A, the being-written card, the
   tab bar and the ready plan. Design: docs/plans/action-plan-on-page.md, "What
   the school sees". Same six sizes as the rest of the page. --- */
/* The tab bar: Your Results / Your Action Plan, directly under the title row.
   A pane the tabs hide stays hidden whatever its own display says (the
   dashboard row is a grid from 1200px). */
[data-pane][hidden] { display: none !important; }
.ap-tabs { display: flex; gap: 4px; border-bottom: 2px solid #dde1e6; margin-bottom: 24px; }
.ap-tabs[hidden] { display: none; }
.ap-tab { background: none; border: 0; border-bottom: 3px solid transparent; margin-bottom: -2px; padding: 10px 16px; font: inherit; font-size: 16px; font-weight: 700; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 8px; }
.ap-tab:hover { color: var(--ink); }
.ap-tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.ap-tab-count { background: var(--accent); color: #fff; font-size: 12px; border-radius: 10px; padding: 0 7px; line-height: 20px; }
.ap-tab-count.is-wait { background: #e9ecef; color: var(--muted); }
@media (max-width: 480px) { .ap-tab { padding: 10px 10px; } }
/* The printed plan's own header (results.html, in #plan): the logo, the school
   and the reference, which on screen are in the header and on the other tab.
   Paper only; laid out under "Print" below. */
.print-only { display: none; }
.ap-head { display: flex; align-items: center; gap: 10px; }
.ap-head h3 { margin: 0; }
.ap-icon { width: 28px; height: 28px; border-radius: 7px; background: var(--accent-tint); color: var(--accent); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ap-icon svg { width: 15px; height: 15px; }
.ap-icon.is-writing svg { animation: ap-pulse 1.6s ease-in-out infinite; }
@keyframes ap-pulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .ap-icon.is-writing svg { animation: none; } }
/* The plan's top card (card A, being written, the summary) runs its text the
   card's full width, the one exception to the 80ch reading cap: at 80ch the
   summary filled barely half of the wide card. */
.ap-lead { font-size: 16px; line-height: 1.6; margin: 12px 0 0; }
.ap-meta { font-size: 14px; color: var(--muted); margin: 8px 0 16px; }
.ap-card .btn { margin-top: 0; }
.ap-card .ap-last { margin-bottom: 0; }
.ap-summary p { font-size: 16px; line-height: 1.6; margin: 0 0 12px; }
.ap-summary p:last-child { margin-bottom: 0; }
.ap-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 18px 0 6px; }
.ap-num { width: 24px; height: 24px; border-radius: 50%; background: var(--ink); color: #fff; font-weight: 800; font-size: 12px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ap-move { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); white-space: nowrap; }
.ap-move svg { width: 13px; height: 13px; }
/* The priorities card. Without the script (no .is-live) it is one column with
   every priority in turn; with it, from 900px, a sticky list beside one
   priority at a time. */
.ap-c { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
@media (min-width: 900px) {
  .ap-c.is-live { grid-template-columns: 290px minmax(0, 1fr); gap: 28px; }
  .ap-c-rail { position: sticky; top: 16px; align-self: start; }
}
.ap-c-rail { display: flex; flex-direction: column; gap: 6px; }
.ap-c-rail[hidden], .ap-c-nav[hidden] { display: none; }
.ap-c-rail .ap-label { margin-top: 0; }
.ap-c-pick { text-align: left; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start; padding: 10px 12px; border: 1px solid #e6e9ed; border-radius: 8px; background: #fff; font: inherit; cursor: pointer; color: var(--ink); }
.ap-c-pick:hover { background: #f6f7f9; }
.ap-c-pick:focus-visible, .ap-c-step:focus-visible, .ap-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ap-c-pick[aria-pressed="true"] { border-color: #9aa3ad; background: #f6f7f9; box-shadow: inset 3px 0 0 var(--accent); }
.ap-c-pick-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ap-c-pick-domain { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.ap-c-pick-q { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 14px; font-weight: 600; line-height: 1.4; }
.ap-c-pick .ap-move { margin-top: 2px; }
.ap-c:not(.is-live) .ap-c-pane + .ap-c-pane { margin-top: 8px; padding-top: 24px; border-top: 1px solid #eee; }
.ap-domain { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); font-weight: 600; }
.ap-c-q { font-size: 17px; line-height: 1.45; margin: 8px 0 4px; max-width: 80ch; }
.al-rungs li.is-aim { background: #fff; box-shadow: inset 0 0 0 2px var(--ink); color: var(--ink); }
.ap-aim-tag { background: var(--ink); border-color: var(--ink); color: #fff; }
/* The answer rows' phone rule pulls their ladder left under its badge; here
   there is no badge to sit under. */
@media (max-width: 560px) { .al-rungs.ap-c-ladder { margin-left: 0; } }
.ap-c-cols { display: grid; gap: 0 32px; }
@media (min-width: 1200px) { .ap-c-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.ap-why { font-size: 16px; line-height: 1.6; max-width: 80ch; margin: 0; white-space: pre-line; }
.ap-steps { margin: 0; padding-left: 22px; max-width: 80ch; display: grid; gap: 6px; }
.ap-steps li { font-size: 16px; line-height: 1.5; padding-left: 4px; }
.ul-well.ap-links { margin-top: 0; }
.ap-c-nav { display: flex; justify-content: space-between; margin-top: 18px; }
.ap-c-step { background: none; border: 1px solid var(--border); border-radius: 7px; padding: 6px 12px; font: inherit; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }
.ap-c-step:hover { background: #f4f6f9; }

/* ===== Useful Links (_useful_links.html) ===== */
/* Every link mapped to this school's answers, once each, as tiles straight on
   the card, each lifted by a soft shadow over a tinted footer strip, so the
   card reads differently from the answer rows above it. Tiles
   in a row share a height (grid stretch + a footer pushed to the bottom), and
   the kind icon sits in the accent tint: a tile is LGfL's offer, not a score,
   so it borrows no score colour. The filters and the description clamp
   are added by the script in results.html.
   It leaves the page's reading column on a wide screen (see the breakout at
   the end of this block), and earlier than the rest of the page does: it is a
   grid, which gains from every extra pixel. */
.useful-links [hidden] { display: none !important; }
.ul-head { display: flex; align-items: center; gap: 10px; }
.ul-head h3 { margin: 0; }
.ul-intro { color: var(--muted); font-size: 14px; margin: 8px 0 14px; }
/* The filters' panel: white on the card with the tiles' warm border, so it
   reads as one control rather than three loose lines of chips. */
.ul-filters { display: grid; gap: 8px; border: 1px solid #e6e1dc; border-radius: 10px; padding: 12px 14px; margin-bottom: 4px; }
.ul-filter-row { display: flex; align-items: flex-start; gap: 12px; }
/* Wide enough for "Your score"; padding-top centres it on a chip's text. */
.ul-filter-label { flex: 0 0 84px; margin: 0; padding-top: 2px; font-size: 14px; font-weight: 600; color: var(--muted); }
.ul-chips { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; }
/* The Search row's box: a chip's height, border and radius, so the label
   centres on it the way it does on the chips below. */
.ul-search { flex: 1; min-width: 0; max-width: 360px; box-sizing: border-box; padding: 4px 12px; border: 1px solid var(--border); border-radius: 14px; background: #fff; color: var(--ink); font: inherit; font-size: 14px; line-height: normal; }
/* After a jump from an answer: a neutral box that says it is a filter, names
   the statement, and ends in real buttons, so it reads as a state to leave
   rather than a line of red text. Pinned to the top of the screen while the
   tiles scroll under it (solid background, above them), so Previous, Next and
   Back to Answer are always to hand; the jump scrolls to it, not to the card.
   A grid of two rows: the statement over Previous / Next, which step from it,
   and Back to Answer / Clear Filter on the right across both rows, centred,
   since they leave the view rather than move through it. That leaves the
   statement most of the box's width. */
.ul-banner { position: sticky; top: 8px; z-index: 2; scroll-margin-top: 8px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "icon text actions" "icon steps actions"; align-items: center; gap: 8px 12px; background: var(--bg); border: 1px solid #d7dde4; border-radius: var(--radius); padding: 10px 12px; margin: 4px 0 0; }
.ul-banner-icon { grid-area: icon; align-self: start; width: 30px; height: 30px; border-radius: 50%; background: #e2e7ee; color: var(--ink); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ul-banner-icon svg { width: 15px; height: 15px; }
.ul-banner-text { grid-area: text; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ul-banner-label { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.ul-banner-sec { font-size: 12px; color: var(--muted); }
/* Baseline, not flex-start: top-aligned, the 22px badge sat 1.5px low against
   the statement's 19.6px first line. On the baseline the badge's number and
   the statement's first line share one, and the badge centres on that line. */
.ul-banner-qline { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.ul-banner-score:empty { display: none; }
.ul-banner-q { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: var(--ink); line-height: 1.4; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
/* At the first or last answer the step that has nowhere to go is hidden but
   keeps its place, so the other never moves under the pointer. */
.ul-banner-steps { grid-area: steps; display: flex; gap: 6px; }
.ul-banner-actions { grid-area: actions; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px; }
.ul-clear { flex-shrink: 0; display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 7px; border: 1px solid var(--border); background: #fff; color: var(--ink); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; transition: background-color 0.12s, border-color 0.12s; }
.ul-clear:hover { background: #eef1f5; border-color: #9aa3ad; }
.ul-clear svg { width: 14px; height: 14px; }
.ul-clear.is-end { visibility: hidden; }
/* No backdrop: the tiles sit straight on the card, set apart by their own
   shadow and footer strip. Still a wrapper, and its 12px margin is what the
   Previous / Next scroll in results.html allows for under the pinned box. */
.ul-well { margin-top: 12px; }
.ul-count { font-size: 14px; color: var(--muted); margin: 0 0 8px; }
/* Its own warm grey box now there is no well behind it, matching .answers-empty. */
.ul-empty { font-size: 14px; margin: 0; padding: 20px 18px; background: #f6f4f2; border-radius: 10px; }
/* As many ~280px columns as fit: one on a phone, two in the page column,
   three once the card breaks out. min() stops a 280px track overflowing a
   phone narrower than that. */
.ul-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 16px; }
/* A tile is two rows of the grid, its body (ending in the button) and its
   footer, shared across the whole row of tiles through subgrid: every body
   and every footer in a row is as tall as the tallest, so the buttons and the
   rules line up even when one tile's badges wrap onto a second line.
   No bottom padding: the footer runs to the tile's sides and bottom edge on
   its own strip, so it borrows the side padding (--tile-pad-x) back. The
   soft shadow lifts the tile just off the white card. */
.ul-tile { --tile-pad-x: 20px; background: #fff; border: 1px solid #e6e1dc; border-radius: 10px; padding: 18px var(--tile-pad-x) 0; box-shadow: 0 2px 6px rgba(0,0,0,0.06); display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 10px; min-width: 0; }
.ul-body { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* Title then icon on one row, the icon in the top right corner, so the title
   starts on the same edge as the description under it. The title's padding
   centres a one-line title on the icon and keeps a two-line one starting
   level with it. */
.ul-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ul-icon { width: 28px; height: 28px; border-radius: 7px; background: var(--accent-tint); color: var(--accent); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ul-icon svg { width: 15px; height: 15px; }
/* The Type filter's chips carry the tiles' kind icon, bare: the tint square
   read oddly inside a chip, so it is just the red icon beside the label, set
   like the score chips' swatches. Pressed, it goes white with the label. */
.ul-type { display: inline-flex; align-items: center; gap: 6px; padding-left: 10px; }
.ul-icon.xs { width: auto; height: auto; background: none; border-radius: 0; }
.ul-icon.xs svg { width: 14px; height: 14px; }
.ul-type.active .ul-icon.xs { color: inherit; }
.ul-title { font-size: 16px; font-weight: 600; color: var(--ink); text-decoration: none; line-height: 1.35; overflow-wrap: anywhere; padding-top: 3px; min-width: 0; }
.ul-title:hover { color: var(--accent); text-decoration: underline; }
/* The wrapper is a flex row only so the description's height is definite,
   which the "More" float below needs to resolve its percentage. */
.ul-desc-wrap { display: flex; }
/* The 21px line height appears three times (here, the float below and .ul-more):
   change them together or "More" leaves the last line. */
.ul-desc { font-size: 14px; color: var(--muted); line-height: 21px; margin: 0; min-width: 0; }
/* --lines is set per tile by the script in results.html: whatever of seven
   lines the title leaves. */
.ul-desc.is-clamped { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--lines, 5); line-clamp: var(--lines, 5); overflow: hidden; }
/* Quiet and inline, at the end of the last visible line. A float the height of
   every line but one pushes the floated button (first in the paragraph) down to
   the last line's right-hand end, and the text wraps round it, so the clamp's
   own ellipsis lands just before "More" rather than under it.
   Only while clamped: there the height is the clamp's, so the float cannot
   change it. Open, the height is the text's, measured before the float lands,
   so a last line with no room for "Less" wrapped a word out of the box. Open,
   the script moves the button to the end of the text instead, where it is one
   more inline word and the paragraph's height counts it. */
.ul-desc.has-more.is-clamped::before { content: ""; float: right; height: calc(100% - 21px); }
.ul-more { margin-left: 6px; background: none; border: 0; padding: 0; font: inherit; line-height: 21px; color: var(--muted); text-decoration: underline; text-decoration-color: #c9ced3; cursor: pointer; }
.ul-desc.is-clamped .ul-more { float: right; clear: both; }
.ul-more:hover { color: var(--ink); }
/* A strip a shade off white, so the answers it serves read as the tile's base
   rather than more of its body. It stretches to fill its subgrid row, so the
   strips in a row stay level. The radius is the tile's less its border, which
   rounds the strip into the tile's corners without overflow: hidden (that
   would clip the summary's focus ring). */
.ul-foot { margin-inline: calc(-1 * var(--tile-pad-x)); padding: 10px var(--tile-pad-x) 12px; background: #faf8f6; border-top: 1px solid #f0ece8; border-radius: 0 0 9px 9px; font-size: 14px; }
/* The body's last line, pinned to its foot so the buttons in a row line up
   even where a description is short or missing. Plain on purpose: 84 red
   buttons would drown out everything else red on the page. */
.ul-go { align-self: flex-start; margin-top: auto; display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; line-height: 1.25; border-radius: 7px; border: 1px solid #d7dde4; background: #fff; color: var(--ink); font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap; transition: background-color 0.12s, border-color 0.12s; }
.ul-go:hover { background: #f4f6f9; border-color: #9aa3ad; color: var(--ink); }
.ul-go svg { width: 13px; height: 13px; color: var(--muted); }
/* Ink, not grey: on the footer's tint a grey label read as faded. */
.ul-for > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-height: 26px; color: var(--ink); }
.ul-for > summary::-webkit-details-marker { display: none; }
.ul-badges { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.ul-chev { width: 14px; height: 14px; color: var(--muted); transition: transform 0.12s; }
.ul-for[open] .ul-chev { transform: rotate(180deg); }
.ul-for > summary:hover .ul-chev { color: var(--ink); }
.ul-for > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ul-answers { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 8px; }
.ul-answers li { display: flex; gap: 8px; align-items: flex-start; line-height: 1.4; }
/* Drops the first line of text onto the 22px badge's centre line ((22px -
   14px x 1.4) / 2). Top-aligned rather than centred so a two-line statement
   still starts beside its badge. */
.ul-answers li > div { padding-top: 1px; }
/* The section name before each statement: a step darker than --muted on the tint. */
.ul-answers .text-muted { color: #495057; }
.ul-note { display: block; margin-top: 2px; color: var(--ink); font-style: italic; }
/* The way in from an answer row or a starting point. */
.ul-jump { display: inline-flex; align-items: center; gap: 5px; margin-top: 8px; font-size: 14px; font-weight: 600; color: var(--accent); text-decoration: none; }
.ul-jump:hover { color: var(--accent-dark); text-decoration: underline; }
.ul-jump svg { width: 13px; height: 13px; }
/* The breakout: negative side margins widen the card past the column, by
   --breakout (defined with the wide page under "Results page"). Unlike the
   rest of the page it starts at 900px, because a grid of tiles gains from
   every extra pixel where two cards side by side need 1200px to be worth it. */
@media (min-width: 900px) {
  .useful-links { margin-inline: var(--breakout); }
}
/* Narrower, Back to Answer and Clear Filter beside the statement would leave
   it under about 450px, so the statement takes the box's width and every
   button shares the row under it: the steps on the left, the way out on the
   right, wrapping if it must. The same two rows, so no taller. No icon: it
   only takes width the statement needs. */
@media (max-width: 1000px) {
  .ul-banner { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "text text" "steps actions"; }
  .ul-banner-icon { display: none; }
  .ul-banner-steps, .ul-banner-actions { align-self: start; }
}
/* A phone has no room for the tiles' full padding either: inside the card it
   would leave a short line of description. */
@media (max-width: 560px) {
  .ul-tile { --tile-pad-x: 16px; padding: 14px var(--tile-pad-x) 0; }
}
/* A phone has no room for a label column: each label sits over its chips. */
@media (max-width: 480px) {
  .ul-filter-row { flex-direction: column; gap: 4px; }
  .ul-filter-label { flex: none; padding-top: 0; }
  .ul-search { flex: none; width: 100%; max-width: none; }
  /* The pinned box has to stay short on a phone: the statement on one line,
     and Previous / Next as arrows (their words kept for screen readers), so
     the buttons need two short rows rather than four. */
  .ul-banner { gap: 8px; padding: 8px 10px; }
  .ul-banner-q { -webkit-line-clamp: 1; line-clamp: 1; }
  .ul-banner .ul-clear { padding-block: 5px; }
  .ul-prev, .ul-next { padding-inline: 9px; }
  .ul-prev .ul-btn-label, .ul-next .ul-btn-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}

/* ===== Compare page (compare.html) ===== */
/* Bars, badges, filter buttons and the collapsible domain sections reuse the
   results-page classes above; this block is just the two-column chrome. */
/* Picker: the two selects share the card's full width (the button sits on its
   own row below), so long "School — Name · DTT-00047 · 12 Mar 2026" labels fit. */
.compare-picker { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px 20px; }
.compare-picker-actions { grid-column: 1 / -1; margin-top: 16px; }
.compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 24px; }
.compare-bar-row { display: grid; grid-template-columns: minmax(72px, 190px) 1fr 74px; gap: 12px; align-items: center; margin-top: 8px; }
.compare-bar-label { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.compare-bar-label strong { color: var(--ink); }
.compare-bar-value { text-align: right; white-space: nowrap; font-size: 14px; }
/* Muted "no answer recorded" badge — the drift case where a question only
   existed for one of the two assessments. */
.score-badge.s-none { background: #f1f3f5; color: var(--muted); font-weight: 600; cursor: help; }
.compare-cols { display: grid; grid-template-columns: 34px 34px 1fr; column-gap: 10px; padding: 8px 0 2px; font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.compare-cols span { text-align: center; }
.compare-row { padding: 12px 0; border-top: 1px solid #f0f0f0; display: grid; grid-template-columns: 34px 34px minmax(0, 1fr); column-gap: 10px; align-items: start; }
.compare-q { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.45; }
.compare-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 7px; font-size: 12px; }
/* The wide page (.page-wide, from 1200px): the bar labels get the room to say
   "A · school — name" in full, and a question keeps the results page's
   reading measure. */
@media (min-width: 1200px) {
  .compare-bar-row { grid-template-columns: minmax(72px, 320px) 1fr 74px; }
  .compare-q { max-width: 80ch; }
}
@media (max-width: 560px) {
  .compare-picker { grid-template-columns: 1fr; }
  .compare-grid { grid-template-columns: 1fr; gap: 16px; }
  .compare-bar-row { grid-template-columns: minmax(60px, 110px) 1fr 60px; gap: 8px; }
}

/* ===== Print / Save-as-PDF (results page): a clean, fileable one-off report ===== */
@media print {
  @page { margin: 16mm; }
  /* Keep the coloured maturity bars, median pills and score colours — browsers
     drop background graphics by default. */
  body { background: #fff !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* Drop interactive / navigation chrome. */
  header,
  .no-print,
  .modal-overlay,
  .answer-filter,
  .answer-help,
  .ul-filters, .ul-banner, .ul-count, .ul-empty,  /* Useful Links prints whole (below) */
  .ul-jump,
  .answer-actions,                             /* See All Answers + the jump */
  .answer-domain > summary::after,
  .admin-bar,
  .admin-pills,
  .sticky-actions,
  a[href="/retrieve"] { display: none !important; }
  /* Flatten cards for paper; avoid splitting a card or a single answer across pages. */
  .card { box-shadow: none !important; border: 1px solid #ccc; break-inside: avoid; }
  #answers-card { break-inside: auto; }          /* long list may span pages */
  #compare-answers { break-inside: auto; }
  .answer-row, .compare-row { break-inside: avoid; }
  .answer-row.is-current, .answer-row.is-flash { background: none; box-shadow: none; }
  .answer-domain > summary { cursor: default; }
  .median-label { display: inline; }            /* tooltip can't print — show the figure */
  .q-terms { display: block !important; }       /* nor can a term's popover — list them */
  .gloss-pop { display: none !important; }
  .gloss-term { background: none; padding: 0; margin: 0; color: inherit; text-decoration: none; }
  .adcount { display: none !important; }
  /* The LGfL line at the top of either tab, in place of the page header. */
  .print-only { display: block !important; }
  .print-only.print-brand { display: flex !important; align-items: center; gap: 14px; margin-bottom: 18px; font-size: 14px; font-weight: 700; color: var(--muted); }
  .print-brand img { height: 40px; width: auto; }
  /* The action plan: whichever tab is showing prints. In the plan, every
     priority in order, each kept on one page where it fits. It opens on its
     own header, naming the school, in place of the page's "Your Report". */
  html[data-tab="plan"] .title-row { display: none !important; }
  .ap-print-note { font-size: 12px; color: var(--muted); margin: -8px 0 16px; }
  .ap-tabs, .ap-c-rail, .ap-c-nav { display: none !important; }
  .ap-c { display: block !important; break-inside: auto; }
  .ap-c-pane[hidden] { display: block !important; }
  .ap-c-pane { break-inside: avoid; }
  .ap-c-pane + .ap-c-pane { margin-top: 8px; padding-top: 18px; border-top: 1px solid #ccc; }
  /* Resources, in the plan and in Useful Links: each one as its title and
     address, a live link in a saved PDF. Useful Links prints every link,
     whatever the filters were showing, since paper has no filter bar to say
     some are missing. */
  .useful-links { break-inside: auto; }
  .useful-links .ul-tile[hidden] { display: block !important; }
  .ap-links .ul-grid, .useful-links .ul-grid { display: block; }
  .ap-links .ul-tile, .useful-links .ul-tile { border: 0; box-shadow: none; padding: 0; margin: 0 0 4px; display: block; break-inside: avoid; }
  .ap-links :is(.ul-desc-wrap, .ul-go, .ul-foot, .ul-icon),
  .useful-links .ul-tile :is(.ul-desc-wrap, .ul-go, .ul-foot, .ul-icon) { display: none !important; }
  .ap-links .ul-title, .useful-links .ul-title { font-size: 14px; color: var(--ink); text-decoration: none; }
  .ap-links .ul-title::after, .useful-links .ul-title::after { content: " (" attr(href) ")"; font-weight: 400; color: var(--muted); word-break: break-all; }
}


/* ===== Admin area (/admin/*) — internal LGfL content tooling =====
   Deliberately plainer than the school-facing pages: a dark nav bar in place of
   the marketing hero, so it is obvious at a glance which side of the app you are
   looking at. */
.admin-bar { background: var(--ink); color: #fff; border-bottom: 3px solid var(--accent); }
.admin-bar-inner { max-width: 860px; margin: 0 auto; padding: 10px 20px; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
/* The admin area is .page-wide (admin/base.html), so the nav follows the
   content out to the wide width and the two keep one pair of edges. */
@media (min-width: 1200px) {
  .page-wide .admin-bar-inner { max-width: calc(var(--wide) + 40px); }
}
.admin-bar-label { font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #fff; }
.admin-bar-who { margin-left: auto; font-size: 13px; color: #c9ced4; }
.admin-nav { display: flex; gap: 4px; flex-wrap: wrap; }
.admin-nav a { color: #dde1e6; text-decoration: none; font-size: 14px; padding: 5px 12px; border-radius: var(--radius); }
.admin-nav a:hover { background: #3a3f44; color: #fff; }
.admin-nav a.is-current { background: var(--accent); color: #fff; font-weight: 600; }
.admin-bar-email { color: #9aa1a9; }
/* The admin screens' filter panel is the results page's own (.ul-filters and
   its rows, under "Useful Links" above), applied in the browser. White, because
   here it sits on the page rather than inside a card. Hidden until its script
   runs, and .ul-filters sets display, so [hidden] needs restating. */
.admin-pills { background: #fff; border-color: var(--border); margin-bottom: 16px; }
.admin-pills[hidden], .admin-none[hidden] { display: none !important; }
/* A pill's count: the Resources screen's Show row is also its work queue, so
   "Needs a Description 3" is the to-do and the filter at once. Red while there
   is something to do; white on a pressed pill like the rest of its label. */
.fbtn-n { margin-left: 6px; font-size: 12px; font-weight: 700; color: var(--muted); }
.fbtn-n.is-due { color: var(--accent); }
.fbtn.active .fbtn-n { color: #fff; }
/* Sort rides at the far end of the Search row, since it narrows nothing and the
   row has the width to spare. On a phone the row stacks and it drops beneath. */
.admin-sort { margin-left: auto; display: flex; align-items: flex-start; gap: 12px; }
.admin-sort .ul-filter-label { flex: none; }
/* In place of the list when the pills leave nothing to show. */
.admin-none { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; font-size: 14px; color: var(--muted); }
.admin-clear { font-size: 14px; color: var(--muted); }
.admin-clear:hover { color: var(--ink); }
/* A button that has to read as a link: used where the control is an in-page
   action rather than navigation, so it must not be an <a href> with no target. */
.admin-linkish { background: none; border: 0; padding: 0; font: inherit; font-size: 13px; color: var(--muted); text-decoration: underline; cursor: pointer; }
.admin-linkish:hover { color: var(--ink); }
.admin-count { font-size: 13px; color: var(--muted); margin-bottom: 8px; }
/* The table scrolls sideways inside its own box on a narrow screen rather than
   pushing the page wider. */
.admin-table-wrap { overflow-x: auto; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); }
.admin-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.admin-table th { text-align: left; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 10px 14px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.admin-table td { padding: 12px 14px; border-bottom: 1px solid #e9ecef; vertical-align: top; }
.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table tbody tr:hover { background: #f8f9fa; }
.admin-row-title { font-weight: 600; text-decoration: none; }
.admin-row-title:hover { text-decoration: underline; }
.admin-row-meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.admin-row-url { word-break: break-all; }
/* The resource library's table. The title cell leads with the kind icon the
   tiles carry, so a row looks like what a school is offered. The description
   takes whatever width the other three leave, which on the wide page is most
   of it, clamped to two lines; the whole text is in the page for the search.
   A floor on the table's width, so a phone scrolls it sideways (inside
   .admin-table-wrap) rather than squeezing the description to a word a line. */
.admin-res-table { min-width: 720px; }
.admin-col-title { width: 36%; }
.admin-col-updated { width: 150px; }
.admin-title-cell { display: flex; align-items: flex-start; gap: 12px; }
.admin-title-cell > div { min-width: 0; }
.admin-cell-n, .admin-cell-updated { white-space: nowrap; color: var(--muted); }
.admin-desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; color: var(--muted); line-height: 1.5; }
.admin-flag-missing { display: inline-block; font-size: 12px; font-weight: 600; color: var(--accent); background: var(--accent-tint); border-radius: 4px; padding: 2px 8px; }
.admin-badge { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); background: #eceff2; border-radius: 4px; padding: 2px 7px; margin-left: 6px; vertical-align: 2px; }
.admin-badge-live { color: var(--warning-text); background: var(--warning-bg); }
.admin-badge-universal { color: #fff; background: var(--ink); }
/* The td rule paints over the row's hover colour, so an inactive row needs its
   own hover state or it looks unclickable. */
.row-inactive td { background: #fbfbfc; }
.row-inactive:hover td { background: #f2f4f6; }
.row-inactive .admin-row-title { color: var(--muted); }
/* The resource editor's own header: the heading and its provenance line on the
   left, Delete on the right. Delete used to be a card at the foot of the page,
   below a row for every question, which read as caution and was really just hard
   to find. Up here it is one click from arriving and still behind a confirm. */
.admin-edit-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
@media (max-width: 480px) { .admin-edit-head { flex-direction: column; } }
/* The resource editor's "How a School Sees It": one Useful Links tile, drawn by
   the results page's own macro and rules, on white as there. Narrow, it
   sits under the description at about a tile's width. From 1200px the editor
   is two columns and the preview rides beside the form, sticky, in a column
   the width of a results-page tile at the full wide width (361px), so
   the title wraps and the description clamps where they will for a school. */
.admin-preview { max-width: 460px; margin-bottom: 20px; }
.admin-preview [hidden] { display: none !important; }
.admin-preview-h { margin: 0 0 2px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.admin-preview-intro { margin: 0 0 10px; font-size: 13px; color: var(--muted); }
.admin-preview .ul-well { margin-top: 0; }
.admin-preview-grid { grid-template-columns: minmax(0, 1fr); }
/* What the tile can't show: that a school sees no description, or no tile. */
.admin-preview-flag { margin: 10px 0 0; font-size: 13px; font-weight: 600; color: var(--accent); }
@media (min-width: 1200px) {
  .admin-edit-grid { display: grid; grid-template-columns: minmax(0, 1fr) 361px; column-gap: 24px; align-items: start; }
  .admin-edit-grid > .card { grid-column: 1; }
  .admin-edit-grid > .admin-preview { grid-column: 2; grid-row: 1 / span 3; align-self: stretch; max-width: none; }
  .admin-preview-inner { position: sticky; top: 16px; }
}
/* The resource editor. The description is a textarea rather than an input, so it
   needs the same border/focus treatment the shared input rule gives the rest. */
.admin-form textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 5px; font-family: inherit; font-size: 15px; line-height: 1.6; background: #fff; resize: vertical; }
.admin-form textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(230,0,0,0.15); }
.admin-check { margin-top: 20px; padding-top: 16px; border-top: 1px solid #e9ecef; }
.admin-check-label { display: flex; align-items: center; gap: 9px; margin: 0; font-size: 15px; cursor: pointer; }
.admin-check-label input { width: 17px; height: 17px; accent-color: var(--accent); flex-shrink: 0; }
.admin-check-hint { margin-top: 5px; margin-left: 26px; font-size: 13px; color: var(--muted); }
/* Action Plan Settings: the fields only the written action plan reads, folded
   under the ones a school's results page uses. The summary says why it is shut,
   so nobody wonders whether they are missing something. */
.admin-fold { margin-top: 20px; padding-top: 14px; border-top: 1px solid #e9ecef; }
.admin-fold > summary { cursor: pointer; font-size: 15px; font-weight: 700; }
.admin-fold > summary:hover { color: var(--accent); }
.admin-fold-hint { display: block; margin: 2px 0 0 18px; font-size: 13px; font-weight: 400; color: var(--muted); }
.admin-fold[open] > summary { margin-bottom: 4px; }
/* "Imported draft:" on a resource no one has saved by hand: the one job the
   2026 import left on every row. */
.admin-draft { color: var(--ink); }
/* The Save bar follows a wide page out to its edges, so Save sits under the
   form's left edge rather than 160px inside it. */
@media (min-width: 1200px) {
  .page-wide .sticky-actions-inner { max-width: var(--wide); }
}
/* "Show this in every report", and the order it takes in that section. The order
   only means something once the box is ticked, so it is revealed rather than
   always shown — hidden, not disabled, so unticking the box and saving does not
   throw away the position an editor chose. */
.universal-check .universal-sort { display: none; }
.universal-check.is-on .universal-sort { display: block; margin: 12px 0 0 26px; max-width: 160px; }
.universal-check.is-on .universal-sort label { margin-top: 0; }

/* The mapping panel: one collapsible section per domain, one row per question.
   A statement is clipped to a single line with the full text in its title
   attribute, so a long row never pushes the checkbox and the uid off-screen. */
.map-count { font-size: 13px; font-weight: 600; color: var(--muted); margin: 0 0 14px; }
/* A universal resource collapses the question list to its summary line: mapping
   is optional for it, but it may legitimately be both, so the list stays one
   click away rather than disappearing. With the box unticked the summary is
   hidden, which leaves the <details open> permanently open and the panel exactly
   as it reads for every other resource. */
.map-targets-summary { display: none; }
#mapping-panel.is-universal .map-targets-summary { display: list-item; cursor: pointer; font-size: 14px; color: var(--muted); padding: 2px 0; }
#mapping-panel.is-universal .map-targets-summary:hover { color: var(--ink); }
#mapping-panel.is-universal .map-intro, #mapping-panel.is-universal .map-count,
/* The open-all control goes with them: the sections it opens are behind the
   summary above, so pressing it would do nothing anyone can see. */
#mapping-panel.is-universal .map-expand { display: none; }
.map-domain { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 10px; background: #fff; }
.map-domain > summary { cursor: pointer; padding: 10px 14px; font-weight: 600; font-size: 15px; list-style-position: inside; }
.map-domain > summary:hover { background: #f8f9fa; }
.map-domain-count { font-size: 12px; font-weight: 600; color: var(--muted); background: #eceff2; border-radius: 10px; padding: 1px 8px; margin-left: 6px; }
/* Tinted where this section already has ticks in it, so a collapsed panel still
   shows at a glance which sections hold the mappings. */
.map-domain-count.is-mapped { color: #fff; background: var(--accent); }
.map-expand { margin: -6px 0 12px; }
.map-row { border-top: 1px solid #e9ecef; padding: 8px 14px; }
.map-row.is-mapped { background: var(--accent-tint); }
.map-tick-label { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 14px; cursor: pointer; min-width: 0; }
.map-tick { width: 17px; height: 17px; accent-color: var(--accent); flex-shrink: 0; }
.map-uid { font-size: 12px; font-weight: 700; color: var(--muted); flex-shrink: 0; min-width: 26px; }
.map-statement { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.map-empty { padding: 10px 14px; margin: 0; font-size: 14px; color: var(--muted); border-top: 1px solid #e9ecef; }
/* Find and Ticked Only, above the sections: the pill panel, sitting inside the
   card here. */
.admin-find { margin: 0 0 12px; }
#map-none { margin-bottom: 12px; }
/* "More options" is closed on the common path, so the note and the score gate
   never crowd out the one thing most rows need, which is the checkbox. It is
   only offered on a ticked row: unticked, its fields are disabled, which read
   as broken, and every question in questions.json carried the link. Ticking a
   box sets .is-mapped (server-side on load, sync() in the editor's script), so
   it appears the moment it can be used. */
.map-row:not(.is-mapped) .map-extra { display: none; }
.map-extra > summary { cursor: pointer; font-size: 12px; color: var(--muted); margin-left: 46px; padding: 2px 0; }
.map-extra > summary:hover { color: var(--ink); }
.map-extra-body { margin: 6px 0 8px 46px; }
.map-extra-body label { margin-top: 6px; margin-bottom: 4px; font-size: 13px; color: var(--muted); font-weight: 600; }
.map-extra-body input[type="text"]:disabled, .map-extra-body select:disabled { background: #f4f5f7; color: var(--muted); cursor: not-allowed; }
.map-gate { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.map-gate select { width: auto; min-width: 110px; }
.map-gate-label { font-size: 13px; color: var(--muted); font-weight: 600; }

/* The question the resource list has been filtered down to, when an editor
   followed a link from the coverage screen. */
.admin-question-banner { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; background: #fff; border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius); padding: 12px 16px; margin-bottom: 12px; }
.admin-question-label { font-size: 14px; font-weight: 700; }
.admin-question-domain { font-size: 12px; font-weight: 600; color: var(--muted); background: #eceff2; border-radius: 10px; padding: 1px 8px; margin-left: 6px; vertical-align: 1px; }

/* The coverage screen. One table per section, and the two colours that make it
   a work queue rather than a report: red where a question has nothing at all,
   amber where it has only just enough. The td rule paints over .admin-table's
   row hover, so each state needs its own hover colour as well — same reason
   .row-inactive does. */
/* The headline figure, above the tables. Same numbers the sections carry, but a
   young library is a screenful of red rows, and a bar reads as a job in progress
   where the rows alone read as failure. */
.coverage-progress { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 20px; }
.coverage-progress-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 15px; }
.coverage-progress-top span { font-size: 20px; font-weight: 700; color: var(--success); }
.coverage-progress-note { margin: 0; font-size: 13px; color: var(--muted); }
.coverage-section { margin-bottom: 24px; }
.coverage-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.coverage-heading-meta { font-size: 13px; font-weight: 400; color: var(--muted); }
/* The universal set, listed above the tables and counted in none of them: an
   editor still needs to see what lands in every school's report, and this is the
   only screen where naming that set is worth the space. */
.coverage-universal { background: #fff; border: 1px solid var(--border); border-left: 4px solid var(--ink); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 20px; }
.coverage-universal h3 { margin-bottom: 4px; }
.coverage-universal ol { margin: 10px 0 0 20px; font-size: 14px; }
.coverage-universal li { margin-bottom: 6px; }
.coverage-universal-order { font-size: 12px; font-weight: 700; color: var(--muted); }

/* One expandable card per question, in place of the table this screen used to be.
   Closed it is the same one-line row: uid, statement, and the two counts, on a
   grid so the columns line up down the list. Open it is the question as a school
   meets it — the five descriptors, what we can offer against it, the guidance
   link. The grid lives on a span *inside* the summary, because setting display on
   a <summary> loses the disclosure marker in Chrome.
   Prefixed cov- because .q-card / .q-summary / .q-body / .q-count are already
   the school-facing form's collapsible answer cards further up this file, and
   `.q-card .q-summary` there is specific enough to hide this grid outright. */
.cov-list { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
/* One count column, not two. There were two, "Resources" and "No Description",
   and between them they took 210px of an 820px row off the question to hold two
   single digits, one of which is a dash on nearly every row. The blank count now
   rides beside the total as a red flag instead. */
.cov-head, .cov-summary { display: grid; grid-template-columns: 26px minmax(0, 1fr) 96px; gap: 14px; align-items: baseline; }
/* The left padding is the disclosure triangle's gutter. A native ::marker is
   drawn outside the summary's box, in its left margin, so that margin is what
   keeps the triangle off the card's edge — and the head is padded to the same
   place so its labels line up with the row underneath. */
.cov-head { padding: 10px 16px 10px 34px; border-bottom: 1px solid var(--border); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.cov-card { border-bottom: 1px solid #e9ecef; break-inside: avoid; }
.cov-card:last-child { border-bottom: none; }
.cov-card > summary { cursor: pointer; padding: 10px 16px 10px 0; list-style-position: outside; margin-left: 34px; }
.cov-card > summary:hover { background: #f8f9fa; }
/* Shown in full, wrapping where it needs to. It was clipped to keep every row one
   line, which made the list shorter and every long question a guess. Set at the
   same 14px the admin tables use: at body size, bold, it was the loudest thing on
   a screen whose point is the counts beside it. */
.coverage-statement { min-width: 0; font-size: 14px; line-height: 1.45; }
.cov-card[open] > summary { background: #f8f9fa; border-bottom: 1px solid #e9ecef; }
/* The total and, when there is one, the flag counting the descriptions still to
   write. Wraps rather than overflows on a question with a lot of both. */
.cov-count { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; font-size: 14px; color: var(--muted); white-space: nowrap; }
/* One mark, on the rows that need an editor: nothing mapped, or a description
   still to write. Nothing else is tinted or striped, so the marks are what the
   eye finds scrolling and the screen needs no key to explain them. On the card
   rather than the summary, so it runs the height of an open one, and an inset
   shadow rather than a border so no row shifts sideways by 4px. */
.coverage-action { box-shadow: inset 4px 0 0 var(--accent); }
/* Left-padded to the summary's own gutter, so an open question's descriptors
   start under its statement rather than 2px off it. */
.cov-body { padding: 14px 16px 16px 34px; }
/* What a school would actually be offered against this question. Set apart from
   the descriptors above it, because the descriptors are the assessment and this
   is our answer to them. */
.cov-offer { margin-top: 14px; padding-top: 12px; border-top: 1px solid #e9ecef; }
.cov-offer-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.cov-offer-title { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.cov-offer-count { font-size: 13px; color: var(--muted); }
.cov-offer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cov-offer li { font-size: 14px; }
.cov-offer-provider { font-size: 12px; font-weight: 600; color: var(--muted); background: #eceff2; border-radius: 10px; padding: 1px 8px; margin-left: 6px; vertical-align: 1px; }
.cov-offer-desc { color: var(--muted); line-height: 1.45; margin-top: 2px; }
/* The one place a mapping's note is shown against the question it was written
   for, so it is quoted rather than just printed. */
.cov-offer-note { margin-top: 4px; padding-left: 10px; border-left: 3px solid var(--border); font-size: 13px; color: var(--ink); }
.cov-offer-gate { margin-top: 3px; font-size: 12px; font-weight: 600; color: var(--muted); }
.cov-offer-empty { margin: 0; font-size: 14px; color: var(--muted); }
/* "Open Every Question" — a plain link to ?open=1, so it works with scripts off
   and the expanded state can be bookmarked or printed. */
.coverage-openall { margin: 0 0 12px; font-size: 13px; }
.coverage-openall a { font-weight: 600; }
.coverage-openall span { color: var(--muted); margin-left: 8px; }
@media (max-width: 640px) {
  /* The count drops under the statement rather than squeezing it to nothing, and
     names itself: the column header is hidden here, so a bare number would have
     nothing to say what it counts. */
  .cov-head { display: none; }
  .cov-summary { grid-template-columns: 26px minmax(0, 1fr); }
  .cov-count { grid-column: 2; font-size: 13px; }
  .cov-count::before { content: "Resources:"; }
}

/* The descriptor ladder inside an open question card. Nothing here is clipped:
   the point is the five descriptors in full, and a school picks between exactly
   these. (These rules had a screen of their own, /admin/assessment, until it was
   folded into /admin/questions.) */
.assess-ladder { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.assess-ladder li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; }
/* Same colour language as the school-facing form and results page, in a smaller
   badge: .score-badge's colours are scoped to that class, so they are restated. */
.assess-score { flex-shrink: 0; width: 26px; text-align: center; border-radius: 6px; font-weight: 800; font-size: 13px; padding: 2px 0; }
.assess-score.s-neg { background: #fbeae9; color: var(--score-neg); }
.assess-score.s-zero { background: #fbf3da; color: var(--score-zero-text); }
.assess-score.s-pos { background: #e7f4ec; color: var(--score-pos); }
.assess-descriptor { color: var(--ink); line-height: 1.45; }
/* The wide admin area (.page-wide, from 1200px): an open question card is
   prose, so it keeps the results page's reading measure instead of running
   the full width. */
@media (min-width: 1200px) {
  .page-wide .assess-descriptor,
  .page-wide .cov-offer-desc,
  .page-wide .cov-offer-note { max-width: 80ch; }
  /* And it has the width for the two halves side by side: the question as a
     school meets it on the left, what we offer against it on the right, so
     opening a question doesn't double the length of the page. Print never
     reaches 1200px, so paper keeps them stacked. */
  .page-wide .cov-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 32px; align-items: start; }
  .page-wide .cov-offer { margin-top: 0; padding-top: 0; border-top: 0; padding-left: 24px; border-left: 1px solid #e9ecef; }
  .page-wide .assess-meta { grid-column: 1 / -1; }
}
.assess-meta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 12px; padding-top: 10px; border-top: 1px solid #e9ecef; font-size: 13px; }

/* --- Action Plans (/admin/action-plans): the list's check-in line, and the
   review page, where the edit form sits beside the plan as the school will see
   it (from 1200px; below that the details come first and the preview last). */
.admin-checkin { font-size: 14px; margin: 0 0 16px; padding: 10px 14px; border-radius: 6px; background: #fff; border: 1px solid var(--border); border-left: 4px solid var(--success); }
.admin-checkin.is-late { border-left-color: var(--accent); background: var(--accent-tint); color: #a31515; }
.plan-ref { font-variant-numeric: tabular-nums; font-weight: 600; }
.admin-plan-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 24px; align-items: start; }
.admin-plan-side { order: -1; }
@media (min-width: 1200px) {
  /* auto 1fr: the form spans both rows, and with two auto rows its height was
     shared between them, which pushed the preview far below the details. */
  .admin-plan-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: auto 1fr; grid-template-areas: "form side" "form preview"; }
  .admin-plan-form { grid-area: form; }
  .admin-plan-side { grid-area: side; order: 0; }
  .admin-plan-preview { grid-area: preview; }
}
.admin-help { font-size: 14px; color: var(--muted); margin: 0 0 10px; }
.admin-help-inline { font-weight: 400; font-size: 14px; color: var(--muted); }
.admin-plan-form label { display: block; font-weight: 700; font-size: 14px; margin: 12px 0 6px; }
.admin-count-line { font-size: 12px; color: var(--muted); margin: 4px 0 0; text-align: right; }
.admin-count-line.is-over { color: var(--accent); font-weight: 700; }
.admin-plan-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.admin-plan-actions .btn { margin-top: 0; }
.admin-plan-meta dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px; margin: 0; font-size: 14px; }
.admin-plan-meta dt { color: var(--muted); }
.admin-plan-meta dd { margin: 0; }
.admin-flags { margin: 0; padding-left: 18px; font-size: 14px; color: #a31515; }
.admin-plan-delete { margin: 0 0 20px; }
.admin-plan-delete .btn { margin-top: 0; }
.admin-plan-preview { margin-bottom: 20px; }
.admin-plan-preview .admin-preview-h { margin-bottom: 8px; }
/* The partial is drawn for the results page's wide column: here it sits in a
   column of its own, so it takes no breakout margins, and the priorities card
   stacks its list above the detail as a narrow results page does. */
.admin-plan-preview .results-wide { margin-inline: 0; }
.admin-plan-preview .ap-c.is-live { grid-template-columns: minmax(0, 1fr); }
.admin-plan-preview .ap-c-rail { position: static; }
.admin-plan-preview .ap-c-cols { grid-template-columns: minmax(0, 1fr); }
