/* The Connected Loop — one stylesheet.
 *
 * Styled to match Flexili: white, Nunito, and the same grey/blue/orange
 * family. One visual language across both products, so a clinician who
 * knows one is not learning a second interface.
 *
 * LIGHT ONLY, deliberately. Flexili is light; a school iPad and a staffroom
 * projector are light; and carrying a second theme means every new component
 * has to be checked twice. The dark variant was dropped rather than left to
 * rot half-maintained.
 *
 * The density rules matter as much as the colours. This screen is read by
 * somebody between lessons with thirty seconds, so: one accent colour at a
 * time, borders instead of shadows, generous whitespace, and nothing shouting
 * unless a child needs somebody.
 */

/* Nunito, served from here rather than from Google.
 *
 * Three reasons, and any one of them would be enough:
 *
 *   1. The CSP forbids third-party stylesheets, so the Google version was
 *      silently blocked and the page was rendering in the system fallback.
 *      document.fonts.check() reported true throughout, because it answers
 *      "is this family named in a rule", not "did it load".
 *   2. The brief tells Eton the application loads no third-party code at
 *      all. Loading a font from a CDN would have made that untrue.
 *   3. Google Fonts' CDN sees every visitor's IP address. For a children's
 *      safeguarding product that is a sub-processor nobody needs, and it has
 *      been found to breach GDPR in at least one European ruling.
 *
 * One variable file per subset covers 400-800, so the whole family is 76KB.
 */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/nunito-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/nunito-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
                 U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                 U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: light;

  /* Flexili's greys, which are the Tailwind family. */
  --plane:        #ffffff;
  --surface:      #ffffff;
  --surface-2:    #F9FAFB;
  --ink:          #111827;
  --ink-2:        #4B5563;
  --ink-muted:    #9CA3AF;
  --hairline:     #E5E7EB;
  --hairline-2:   #F3F4F6;
  --grid:         #F3F4F6;
  --baseline:     #E5E7EB;

  --series-1:     #3B82F6;
  --series-2:     #F97316;

  /* Status. Kept close to the Flexili blues and oranges rather than
   * introducing a third hue family. */
  --good:         #10B981;
  --warning:      #FB923C;
  --serious:      #F97316;
  --critical:     #DC2626;
  --good-ink:     #059669;
  --warning-ink:  #C2410C;
  --serious-ink:  #EA580C;
  --critical-deep:#B91C1C;

  --accent:       #3B82F6;
  --accent-soft:  #EFF6FF;

  --r:            8px;
  --r-lg:         10px;
  /* Almost nothing casts a shadow now. A page of floating cards is the thing
   * that made this feel busy; a hairline says "separate" just as clearly and
   * leaves the page flat and calm. */
  --shadow:       none;
  --shadow-lift:  0 1px 2px rgba(17,24,39,.04);
  --font:         'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; }

/* Several components below set display, which would otherwise beat the UA
 * rule for the hidden attribute. Keep hidden meaning hidden. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--plane);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

button, input, select, textarea { font: inherit; color: inherit; }

/* ------------------------------------------------------------------ shell */

.app {
  display: grid;
  grid-template-columns: 252px 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "brand topbar" "side main";
  height: 100%;
}

.brand {
  grid-area: brand;
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  background: var(--surface);
}
.brand-mark {
  width: 26px; height: 26px; flex: none;
  border-radius: 50%;
  border: 2.5px solid var(--accent);
  border-right-color: transparent;
  transform: rotate(-35deg);
}
.brand h1 { font-size: .95rem; margin: 0; letter-spacing: -.01em; }
.brand span { display: block; font-size: .72rem; color: var(--ink-muted); font-weight: 400; letter-spacing: 0; }

.topbar {
  grid-area: topbar;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  flex-wrap: wrap;
}
#student-picker { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.picker-label { font-size: .78rem; color: var(--ink-muted); margin-right: 2px; }
.topbar-spacer { flex: 1 1 auto; }

.side {
  grid-area: side;
  background: var(--surface);
  border-right: 1px solid var(--hairline);
  overflow-y: auto;
  padding: 16px 14px 28px;
  display: flex; flex-direction: column; gap: 18px;
}
.side-label {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-muted); padding: 0 6px; margin: 0 0 6px;
}

#role-nav { display: flex; flex-direction: column; gap: 4px; }
.role-tab {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 9px 12px; border-radius: var(--r);
  background: transparent; border: 1px solid transparent;
  min-height: 44px;
}
.role-tab strong { font-size: .9rem; font-weight: 600; }
.role-tab span { font-size: .72rem; color: var(--ink-muted); }
.role-tab:hover { background: var(--surface-2); }
.role-tab.is-on {
  background: var(--accent-soft);
  border-color: transparent;
}
.role-tab.is-on strong { color: var(--accent); }

/* Role accents.
 *
 * Pulled into Flexili's blue/orange family rather than six unrelated hues.
 * A page that changes its whole colour scheme when you switch role is doing
 * a lot of work to say something the heading already says. These differ
 * enough to orient you and not enough to be decoration. */
.accent-blue    { --accent: #3B82F6; --accent-soft: #EFF6FF; }
.accent-aqua    { --accent: #0EA5E9; --accent-soft: #F0F9FF; }
.accent-violet  { --accent: #6366F1; --accent-soft: #EEF2FF; }
.accent-magenta { --accent: #EC4899; --accent-soft: #FDF2F8; }
.accent-orange  { --accent: #F97316; --accent-soft: #FFF7ED; }
.accent-green   { --accent: #10B981; --accent-soft: #ECFDF5; }

#role-context {
  padding: 12px 13px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--hairline);
}
.ctx-who strong { display: block; font-size: .88rem; }
.ctx-who span { font-size: .75rem; color: var(--ink-muted); }
.ctx-blurb { font-size: .78rem; color: var(--ink-2); margin: 8px 0 0; }

.side-links { display: flex; flex-direction: column; gap: 4px; margin-top: auto; }

.main {
  grid-area: main;
  overflow-y: auto;
  /* Narrower than it was, and more air at the top. A measure of about 90
   * characters is a wall of text; this keeps a line readable and gives the
   * page somewhere to breathe. */
  padding: 28px 32px 96px;
  max-width: 920px;
  width: 100%;
  -webkit-overflow-scrolling: touch;
}

/* ------------------------------------------------------------------- hero */

.hero { margin: 0 0 26px; }
.hero h1 { font-size: 1.5rem; font-weight: 800; margin: 0 0 3px; letter-spacing: -.02em; }
.hero p { margin: 0; color: var(--ink-muted); font-size: .9rem; }
/* His name, then the emergency button immediately to the right of it.
 *
 * Not pushed to the far edge of the row: on a 1280px screen that puts it a
 * thousand pixels from his name, which is how the previous placement came to
 * be invisible. Beside the name it belongs to him and cannot be missed. */
.hero-with-aside {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 22px; flex-wrap: wrap;
}
.hero-text { min-width: 0; flex: 0 1 auto; }

.section-break {
  font-size: 1.1rem; margin: 34px 0 12px; padding-top: 18px;
  border-top: 1px solid var(--hairline);
}

/* ------------------------------------------------------------------ cards */

/* A card is a hairline and some breathing room.
 *
 * It used to be a shadowed, rounded, bordered panel, and a page of eight of
 * them read as eight competing objects. Now it is white on white separated
 * by one grey line, which says "these belong together" without shouting it.
 * The whitespace does the work the shadow was doing. */
.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  margin: 0 0 14px;
  overflow: hidden;
}
.card-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 18px 20px 0;
}
.card-head h2 {
  font-size: .95rem; margin: 0; font-weight: 700; letter-spacing: -.005em;
}
/* Quieter and smaller than it was. Several of these ran to three lines of
 * explanation above a card that explained itself, which is most of why the
 * page felt heavy. */
.card-sub {
  margin: 3px 20px 0; font-size: .78rem; line-height: 1.45; color: var(--ink-muted);
  max-width: 62ch;
}
.card-body { padding: 14px 20px 20px; }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.stats-row { margin-bottom: 18px; }
.row { display: flex; gap: 8px; align-items: center; }
.row .text-input { flex: 1; }

/* ------------------------------------------------------------------ forms */

.q { margin: 0 0 16px; }
.q > label {
  display: block; font-size: .84rem; font-weight: 600;
  margin: 0 0 7px; color: var(--ink);
}
.text-input {
  width: 100%; padding: 10px 12px; min-height: 44px;
  border: 1px solid var(--hairline); border-radius: var(--r);
  background: var(--surface-2); color: var(--ink);
  font-size: .92rem;
}
textarea.text-input { min-height: 76px; resize: vertical; line-height: 1.45; }
.text-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }

.btn {
  padding: 10px 16px; min-height: 44px; cursor: pointer;
  border-radius: var(--r); border: 1px solid var(--hairline);
  background: var(--surface-2); font-size: .88rem; font-weight: 500;
  /* The class is used on <a> as well as <button>. Anchors bring an underline
   * and fill their flex line unless told otherwise. */
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; color: var(--ink);
}
a.btn:hover { text-decoration: none; }
.btn-primary, a.btn-primary { color: #fff; }
.btn:hover { background: var(--plane); }
.btn-primary {
  background: var(--accent); color: #fff; border-color: transparent; font-weight: 600;
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-quiet { background: transparent; border-color: transparent; color: var(--ink-2); font-size: .8rem; min-height: 32px; padding: 4px 8px; }
.btn-quiet:hover { background: var(--surface-2); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.check { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; font-size: .85rem; }
.check input { width: 18px; height: 18px; accent-color: var(--accent); }

.scale { display: flex; gap: 8px; }
.scale-dot {
  flex: 1; min-width: 48px; min-height: 48px; cursor: pointer;
  border-radius: var(--r); border: 1px solid var(--hairline);
  background: var(--surface-2); font-size: 1rem; font-weight: 600; color: var(--ink-2);
}
.scale-dot:hover { border-color: var(--accent); }
.scale-dot.is-on { background: var(--accent); color: #fff; border-color: transparent; }
.scale-ends {
  display: flex; justify-content: space-between;
  font-size: .72rem; color: var(--ink-muted); margin-top: 5px;
}

.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.chip {
  padding: 7px 12px; min-height: 38px; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--hairline);
  background: var(--surface-2); font-size: .82rem;
}
.chip.is-on { background: var(--accent); color: #fff; border-color: transparent; }

.levels { display: flex; flex-direction: column; gap: 8px; }
.level {
  text-align: left; cursor: pointer; padding: 11px 13px;
  border-radius: var(--r); border: 1px solid var(--hairline);
  background: var(--surface-2);
}
.level strong { display: block; font-size: .87rem; margin-bottom: 2px; }
.level span { font-size: .78rem; color: var(--ink-muted); }
.level.is-on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.level.is-on strong { color: var(--accent); }

/* ------------------------------------------------------------------ stats */

.stat {
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--r-lg); padding: 16px 18px; box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 2px;
}
.stat-value { font-size: 2rem; font-weight: 650; letter-spacing: -.03em; line-height: 1.1; }
.stat-label { font-size: .78rem; color: var(--ink-muted); }
.stat.tone-good .stat-value { color: var(--good-ink); }

.inline-stats { display: flex; gap: 6px; margin-top: 8px; }
.lead { font-size: 1.05rem; margin: 0; }
.note { font-size: .78rem; color: var(--ink-muted); margin: 12px 0 0; }
.empty { color: var(--ink-muted); font-size: .87rem; margin: 4px 0; }

.pill {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: .72rem; font-weight: 500; white-space: nowrap;
  background: var(--surface-2); border: 1px solid var(--hairline); color: var(--ink-2);
}
.pill-muted { color: var(--ink-muted); }
.pill-good     { color: var(--good-ink);    border-color: color-mix(in srgb, var(--good) 45%, transparent); }
.pill-warning  { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 60%, transparent); }
.pill-serious  { color: var(--serious-ink); border-color: color-mix(in srgb, var(--serious) 60%, transparent); }

.flag-line {
  margin: 0 0 8px; padding: 11px 13px; border-radius: var(--r);
  font-size: .9rem; background: var(--surface-2);
  border-left: 3px solid var(--baseline);
}
.flag-line.tone-good    { border-left-color: var(--good);    }
.flag-line.tone-warning { border-left-color: var(--warning); }
.flag-line.tone-info    { border-left-color: var(--series-1); }
.flag-line:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- patterns */

.pattern {
  padding: 13px 15px; border-radius: var(--r); margin: 0 0 10px;
  background: var(--surface-2); border-left: 3px solid var(--baseline);
}
.pattern.tone-serious { border-left-color: var(--critical); }
.pattern.tone-warning { border-left-color: var(--warning); }
.pattern strong { display: block; font-size: .92rem; margin-bottom: 3px; }
.pattern p { margin: 0 0 8px; font-size: .84rem; color: var(--ink-2); }
.pattern-sources { display: flex; gap: 5px; flex-wrap: wrap; }
.pattern:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- timeline */

.timeline { list-style: none; margin: 0; padding: 0; }
.sig {
  display: flex; gap: 12px; padding: 13px 0;
  border-bottom: 1px solid var(--hairline-2);
}
.sig:last-child { border-bottom: none; padding-bottom: 0; }
.sig-glyph {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; font-size: .85rem;
  background: var(--surface-2); border: 1px solid var(--hairline); color: var(--ink-2);
}
.sig.tone-warning .sig-glyph { border-color: var(--warning); color: var(--warning-ink); }
.sig.tone-serious .sig-glyph { border-color: var(--critical); color: var(--critical); }
.sig-main { min-width: 0; flex: 1; }
.sig-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.sig-head { font-size: .9rem; }
.sig-kind { font-size: .72rem; color: var(--ink-muted); }
.sig-body { margin: 3px 0 0; font-size: .87rem; color: var(--ink-2); }
.sig-action, .sig-guidance {
  margin: 6px 0 0; font-size: .82rem; color: var(--ink-2);
  padding-left: 9px; border-left: 2px solid var(--hairline);
}
.sig-meta { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: .74rem; color: var(--ink-muted); flex-wrap: wrap; }
.sig-author { font-weight: 500; }

.wins { list-style: none; margin: 0 0 12px; padding: 0; }
.wins li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--hairline-2); font-size: .88rem;
}
.wins li:last-child { border-bottom: none; }
.wins em { font-style: normal; color: var(--ink-muted); font-size: .76rem; white-space: nowrap; }

/* ------------------------------------------------------------- profile */

.tag-row { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.profile-block h3 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-muted); margin: 0 0 6px;
}
.profile-block ul { margin: 0; padding-left: 18px; }
.profile-block li { font-size: .87rem; margin-bottom: 4px; color: var(--ink-2); }

.digest-block { margin-bottom: 16px; }
.digest-block:last-child { margin-bottom: 0; }
.digest-block h3 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-muted); margin: 0 0 4px;
}
.digest-block p { margin: 0; font-size: .95rem; }

/* ------------------------------------------------------------------- roll */

.roll { list-style: none; margin: 0; padding: 0; }
.roll-item {
  display: grid; grid-template-columns: 1fr auto auto; gap: 14px; align-items: center;
  padding: 13px 14px; margin-bottom: 8px; cursor: pointer;
  border-radius: var(--r); background: var(--surface-2);
  border: 1px solid var(--hairline-2); border-left: 3px solid var(--baseline);
}
.roll-item:hover { border-color: var(--accent); }
.roll-item.tone-serious { border-left-color: var(--critical); }
.roll-item.tone-warning { border-left-color: var(--warning); }
.roll-item.tone-none    { border-left-color: var(--good); }
.roll-item strong { display: block; font-size: .92rem; }
.roll-sub { font-size: .76rem; color: var(--ink-muted); }
.roll-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.roll-state { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; }

/* ----------------------------------------------------------------- charts */

.chart { position: relative; }
.chart-svg { width: 100%; height: auto; display: block; overflow: visible; touch-action: pan-y; }
.chart-grid { stroke: var(--grid); stroke-width: 1; }
.rail { stroke: var(--baseline); stroke-width: 1; }
.axis-label { fill: var(--ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pt { stroke: var(--surface); stroke-width: 2; }
.line.series-1, .pt.series-1 { stroke: var(--series-1); }
.pt.series-1 { fill: var(--series-1); stroke: var(--surface); }
.line.series-2 { stroke: var(--series-2); }
.pt.series-2 { fill: var(--series-2); stroke: var(--surface); }
.direct-label { font-size: 11px; font-weight: 600; }
.series-1-ink { fill: var(--series-1); }
.series-2-ink { fill: var(--series-2); }

.marker-stem { stroke: var(--hairline); stroke-width: 1; stroke-dasharray: 2 3; }
.marker-dot { fill: var(--surface); stroke: var(--baseline); stroke-width: 1.5; }
.marker-glyph { fill: var(--ink-2); font-size: 9px; }
.marker.tone-warning .marker-dot { stroke: var(--warning); }
.marker.tone-serious .marker-dot { stroke: var(--critical); }
.marker:hover .marker-dot { stroke: var(--accent); stroke-width: 2.5; }

.crosshair { stroke: var(--baseline); stroke-width: 1; }
.hover-layer { opacity: 0; transition: opacity .12s; pointer-events: none; }
.hover-layer.is-on { opacity: 1; }

.tooltip {
  position: absolute; top: 8px; transform: translateX(-50%);
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r); box-shadow: var(--shadow);
  padding: 8px 11px; font-size: .78rem; pointer-events: none;
  display: flex; flex-direction: column; gap: 2px; max-width: 240px; z-index: 5;
}
.tt-row { display: flex; align-items: center; gap: 6px; }
.tt-note { color: var(--ink-muted); font-style: italic; margin-top: 3px; }
.sw, i.sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }
.sw.series-1 { background: var(--series-1); }
.sw.series-2 { background: var(--series-2); }

.chart-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; margin-top: 10px; flex-wrap: wrap;
}
.legend { display: flex; gap: 14px; flex-wrap: wrap; }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: .78rem; color: var(--ink-2); }

.streak-strip { display: flex; gap: 4px; margin-bottom: 18px; }
.streak-cell {
  flex: 1; height: 26px; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--hairline-2);
}
.streak-cell.is-on { background: var(--good); border-color: transparent; }

/* ----------------------------------------------------------------- tables */

.table-scroll { overflow-x: auto; }
.chart-table { overflow-x: auto; margin-top: 12px; }
.data-table { border-collapse: collapse; width: 100%; font-size: .82rem; }
.data-table th, .data-table td {
  text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--hairline-2);
  white-space: nowrap;
}
.data-table th { color: var(--ink-muted); font-weight: 600; font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; }
.data-table td:last-child { white-space: normal; }
.matrix td { font-size: .76rem; }
.matrix .cell-full { color: var(--good-ink); font-weight: 600; }
.matrix .cell-none { color: var(--ink-muted); }
.matrix .cell-part { color: var(--ink-2); }

/* ----------------------------------------------------------------- panels */

#panel-host { position: fixed; inset: 0; z-index: 40; }
.panel-scrim { position: absolute; inset: 0; background: rgba(10,10,8,.45); }
.panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(880px, 100%);
  background: var(--surface); box-shadow: var(--shadow);
  display: flex; flex-direction: column;
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--hairline);
}
.panel-head h2 { margin: 0; font-size: 1.05rem; }
.panel-close {
  border: none; background: transparent; cursor: pointer;
  font-size: 1.6rem; line-height: 1; width: 44px; height: 44px; color: var(--ink-2);
}
.panel-body { padding: 20px; overflow-y: auto; }
.panel-actions { margin-top: 20px; }
.prose h3 { font-size: .9rem; margin: 20px 0 6px; }
.prose h3:first-child { margin-top: 0; }
.prose p, .prose li { font-size: .88rem; color: var(--ink-2); margin: 0 0 8px; }
.prose ul { padding-left: 18px; }

/* ----------------------------------------------------------------- toasts */

#toast-host {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  z-index: 60; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
.toast {
  background: var(--ink); color: var(--plane);
  padding: 11px 18px; border-radius: 999px; font-size: .86rem;
  box-shadow: var(--shadow); transition: opacity .4s, transform .4s;
  max-width: 90vw; text-align: center;
}
.toast.is-out { opacity: 0; transform: translateY(6px); }

/* ------------------------------------------------------------- responsive
 * iPad landscape keeps the sidebar. iPad portrait and below moves the role
 * switcher to a horizontal strip so the content gets the full width. */

@media (max-width: 1024px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto 1fr;
    grid-template-areas: "brand" "side" "topbar" "main";
  }
  .brand { border-right: none; }
  .side {
    border-right: none; border-bottom: 1px solid var(--hairline);
    padding: 10px 12px; gap: 10px; overflow: visible;
  }
  .side-label { display: none; }
  #role-nav {
    flex-direction: row; gap: 6px;
    overflow-x: auto; padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
  }
  .role-tab { width: auto; flex: none; white-space: nowrap; }
  #role-context { display: none; }
  .side-links { flex-direction: row; margin-top: 0; }
  .main { padding: 18px 18px 80px; max-width: none; }
}

@media (max-width: 600px) {
  .hero h1 { font-size: 1.3rem; }
  .main { padding: 14px 13px 80px; }
  .card-body { padding: 12px 14px 15px; }
  .card-head, .card-sub { padding-left: 14px; padding-right: 14px; }
  .roll-item { grid-template-columns: 1fr; gap: 6px; }
  .roll-state { align-items: flex-start; text-align: left; }
  .panel { width: 100%; }
  .scale-dot { min-width: 0; }
}

@media print {
  .side, .topbar, .brand, #panel-host, #toast-host { display: none; }
  .app { display: block; }
  .card { break-inside: avoid; box-shadow: none; border: 1px solid #ccc; }
}

/* -------------------------------------------------------------- sign-in
 * A separate surface from the app shell: nobody is signed in yet, so there
 * is no role, no accent, and nothing to be careful about revealing. */

#signin-host { min-height: 100%; }
.signin {
  min-height: 100vh; min-height: 100dvh;
  display: grid; place-items: center; padding: 24px;
  background: var(--plane);
}
.signin-card {
  width: min(420px, 100%);
  background: var(--surface);
  border: 1px solid var(--hairline-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: 32px 28px;
  text-align: center;
}
.brand-mark-lg {
  width: 40px; height: 40px; margin: 0 auto 14px;
  border-width: 3px; display: block;
}
.signin-card h1 { font-size: 1.25rem; margin: 0 0 4px; letter-spacing: -.02em; }
.signin-sub { margin: 0 0 24px; color: var(--ink-muted); font-size: .88rem; }
.signin-form { text-align: left; display: flex; flex-direction: column; gap: 8px; }
.signin-form label { font-size: .84rem; font-weight: 600; }
.btn-block { width: 100%; justify-content: center; margin-top: 4px; }
.signin-note { font-size: .76rem; color: var(--ink-muted); margin: 10px 0 0; line-height: 1.45; }
.form-error {
  font-size: .82rem; color: var(--critical); margin: 0;
  padding: 8px 10px; border-radius: var(--r);
  background: color-mix(in srgb, var(--critical) 10%, transparent);
}
.booting { padding: 60px; text-align: center; color: var(--ink-muted); }

.dev-note {
  margin: 14px 0; padding: 12px 14px; text-align: left;
  border-radius: var(--r); border: 1px dashed var(--warning);
  background: color-mix(in srgb, var(--warning) 8%, transparent);
}
.dev-note strong { display: block; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--warning-ink); margin-bottom: 4px; }
.dev-note p { font-size: .8rem; margin: 0 0 8px; color: var(--ink-2); }
.token {
  display: block; font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: .72rem; word-break: break-all; padding: 8px;
  background: var(--surface-2); border-radius: 6px; color: var(--ink-2);
}

/* Demo account picker. Development only — the server does not serve the list
   in production, so this never renders there. */
.demo-accounts { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.demo-account {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%; min-height: 40px; padding: 7px 11px; cursor: pointer;
  border-radius: var(--r); border: 1px solid var(--hairline);
  background: var(--surface); text-align: left;
}
.demo-account:hover { border-color: var(--accent); }
.demo-account strong {
  font-size: .84rem; font-weight: 600;
  /* .dev-note strong is a small-caps heading; a person's name is not. */
  text-transform: none; letter-spacing: 0; color: var(--ink); margin: 0;
}
.demo-account span { font-size: .74rem; color: var(--ink-muted); }

/* ------------------------------------------------------- safeguarding UI
 * Talk to someone, and the queue of boys who have used it. Both are given
 * more visual weight than anything else on their page, on purpose. */

.card-help { border-color: color-mix(in srgb, var(--good) 35%, transparent); }
.card-urgent { border-color: color-mix(in srgb, var(--critical) 45%, transparent); }
.card-urgent .card-head h2 { color: var(--critical); }

.help-emergency {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  padding: 12px 14px; margin-bottom: 12px; border-radius: var(--r);
  background: color-mix(in srgb, var(--critical) 8%, transparent);
  border-left: 3px solid var(--critical);
}
.help-emergency strong { font-size: .88rem; }
.help-action { font-size: 1.05rem; font-weight: 700; color: var(--critical); }
.help-emergency .help-detail { flex-basis: 100%; }
.help-detail { font-size: .78rem; color: var(--ink-muted); display: block; }

.help-ask { margin: 0 0 14px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--hairline); }
.help-ask summary {
  cursor: pointer; padding: 12px 14px; font-size: .92rem; font-weight: 600;
  min-height: 44px; display: flex; align-items: center;
}
.help-ask summary::marker { color: var(--ink-muted); }
.help-ask-body { padding: 0 14px 14px; }
.help-ask-body .q { margin-top: 12px; }

.help-lead { font-size: .84rem; color: var(--ink-2); margin: 0 0 8px; }
.help-list { list-style: none; margin: 0; padding: 0; }
.help-list li {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--hairline-2);
}
.help-list li:last-child { border-bottom: none; }
.help-list strong { font-size: .88rem; }
.help-contact {
  font-size: .88rem; font-weight: 600; color: var(--accent);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}

.concern {
  padding: 13px 15px; margin: 0 0 10px; border-radius: var(--r);
  background: var(--surface-2); border-left: 3px solid var(--critical);
}
.concern:last-child { margin-bottom: 0; }
.concern-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.concern-top strong { font-size: .95rem; }
.concern-note { margin: 0 0 10px; font-size: .89rem; }
.concern-note.empty { color: var(--ink-muted); font-style: italic; }

@media (max-width: 600px) {
  .help-list li { flex-direction: column; gap: 2px; }
  .concern .row { flex-direction: column; align-items: stretch; }
}

/* --------------------------------------------------------------- the tour
 * A guide for somebody who did not build this. Sits beside the app rather
 * than over it: the interface stays visible and usable behind it, because
 * the point is to look at the thing being described. */

#tour-host {
  position: fixed; z-index: 50;
  right: 20px; bottom: 20px; width: min(400px, calc(100vw - 40px));
}
.tour {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  box-shadow: 0 4px 12px rgba(20,20,15,.10), 0 16px 48px rgba(20,20,15,.16);
  padding: 18px 20px 16px;
  max-height: min(70vh, 620px);
  display: flex; flex-direction: column;
}
.tour-head { display: flex; align-items: center; justify-content: space-between; }
.tour-count {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-muted); font-weight: 600;
}
.tour-close {
  border: none; background: transparent; cursor: pointer; color: var(--ink-muted);
  font-size: 1.4rem; line-height: 1; width: 32px; height: 32px; margin: -6px -8px 0 0;
}
.tour-close:hover { color: var(--ink); }
.tour h2 { font-size: 1.05rem; margin: 6px 0 10px; letter-spacing: -.01em; }
.tour-body { overflow-y: auto; margin-bottom: 14px; }
.tour-body p { font-size: .89rem; line-height: 1.55; color: var(--ink-2); margin: 0 0 10px; }
.tour-body p:last-child { margin-bottom: 0; }
.tour-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; }

@media (max-width: 700px) {
  #tour-host { right: 10px; left: 10px; bottom: 10px; width: auto; }
  .tour { max-height: 60vh; }
}

/* ------------------------------------------------------------- feedback
 * Two questions the software should not answer for itself. */

.fb-q { margin: 0 0 1.75rem; }
.fb-q h3 { font-size: .98rem; margin: 0 0 .35rem; color: var(--ink); }
.fb-context { font-size: .85rem; color: var(--ink-muted); margin: 0 0 .75rem; line-height: 1.55; }
.fb-options { display: grid; gap: 6px; margin-bottom: 10px; }
.fb-option {
  text-align: left; cursor: pointer; padding: 10px 13px; min-height: 44px;
  border-radius: var(--r); border: 1px solid var(--hairline);
  background: var(--surface-2); font-size: .88rem;
}
.fb-option:hover { border-color: var(--accent); }
.fb-option.is-on {
  border-color: var(--accent); color: var(--accent); font-weight: 600;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.fb-out {
  margin-top: 12px; font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: .76rem; line-height: 1.5;
}

/* ------------------------------------------------------------- policies
 * A document, not a dashboard: one readable column, generous leading, and
 * no chrome competing with the text. */

.pol-page { background: var(--plane); }
.pol-bar {
  background: var(--surface); border-bottom: 1px solid var(--hairline);
  padding: 12px 20px;
}
.pol-back {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--ink); text-decoration: none; font-weight: 600; font-size: .9rem;
}
.pol-back:hover { color: var(--accent); }

.pol-main { max-width: 46rem; margin: 0 auto; padding: 32px 20px 80px; }
.pol-head h1 {
  font-size: clamp(1.5rem, 4vw, 1.9rem); margin: 0 0 6px;
  letter-spacing: -.02em; text-wrap: balance; line-height: 1.2;
}
.pol-sub { color: var(--ink-muted); font-size: .92rem; margin: 0 0 20px; }

.pol-tabs { display: flex; gap: 6px; margin-bottom: 28px; flex-wrap: wrap; }
.pol-tab {
  padding: 9px 15px; min-height: 44px; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--hairline);
  background: var(--surface); font-size: .88rem; font-weight: 500;
}
.pol-tab:hover { border-color: var(--accent); }
.pol-tab.is-on { background: var(--accent); color: #fff; border-color: transparent; }

.pol-qa {
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--r-lg); padding: 20px 22px; margin: 0 0 14px;
  box-shadow: var(--shadow);
}
.pol-qa h2 { font-size: 1.05rem; margin: 0 0 8px; letter-spacing: -.01em; }
.pol-qa p { font-size: .94rem; line-height: 1.62; color: var(--ink-2); margin: 0 0 10px; }
.pol-qa p:last-child { margin-bottom: 0; }
.pol-qa .note { font-size: .82rem; color: var(--ink-muted); }
.pol-foot {
  font-size: .82rem; color: var(--ink-muted); margin: 22px 0 0;
  padding-top: 16px; border-top: 1px solid var(--hairline);
}

/* ------------------------------------------------------------- landing
 * The public front door. A document-weight page, not a dashboard: one
 * column, generous rhythm, and the two things a visitor might do put where
 * they cannot be missed. */

.land-page { background: var(--plane); height: auto; }
.land-page main { display: block; }

.land-nav {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 12px 24px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--hairline);
}
.land-brand {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--ink); text-decoration: none; font-weight: 650; font-size: .95rem;
}
.land-links { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.land-links a {
  color: var(--ink-2); text-decoration: none; font-size: .86rem;
  padding: 8px 11px; border-radius: var(--r); min-height: 40px;
  display: inline-flex; align-items: center;
}
.land-links a:hover { color: var(--ink); background: var(--surface-2); }
.land-links .land-cta {
  background: var(--accent); color: #fff; font-weight: 600;
}
.land-links .land-cta:hover { background: var(--accent); filter: brightness(1.08); }
.land-links .land-signin { border: 1px solid var(--hairline); }

.land-hero { max-width: 46rem; margin: 0 auto; padding: 64px 24px 56px; }
.land-eyebrow {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-muted); font-weight: 600; margin: 0 0 14px;
}
.land-hero h1 {
  font-size: clamp(2rem, 5.5vw, 3rem); line-height: 1.08; letter-spacing: -.03em;
  margin: 0 0 18px; text-wrap: balance;
}
.land-lede {
  font-size: 1.1rem; line-height: 1.62; color: var(--ink-2);
  margin: 0 0 28px; max-width: 34rem;
}
.land-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.btn-lg { padding: 13px 22px; min-height: 50px; font-size: .95rem; }
.land-note { font-size: .84rem; color: var(--ink-muted); margin: 0; }

.land-band {
  border-top: 1px solid var(--hairline);
  padding: 56px 24px;
}
.land-band > h2 {
  max-width: 46rem; margin: 0 auto 12px;
  font-size: clamp(1.4rem, 3.5vw, 1.75rem); letter-spacing: -.02em;
}
.land-band-lede {
  max-width: 46rem; margin: 0 auto 32px;
  font-size: 1rem; line-height: 1.65; color: var(--ink-2);
}
.land-band-alt { background: var(--surface); }

.land-steps { max-width: 46rem; margin: 0 auto; padding: 0; list-style: none;
  display: grid; gap: 22px; }
.land-steps li { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: start; }
.land-step-n {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent); font-weight: 700; font-size: .82rem;
  font-variant-numeric: tabular-nums;
}
.land-steps h3 { font-size: 1rem; margin: 3px 0 5px; letter-spacing: -.01em; }
.land-steps p { font-size: .93rem; line-height: 1.6; color: var(--ink-2); margin: 0; }

.land-roles, .land-gates {
  max-width: 46rem; margin: 0 auto;
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.land-roles article, .land-gates article {
  background: var(--plane); border: 1px solid var(--hairline-2);
  border-radius: var(--r-lg); padding: 16px 18px;
}
.land-band-alt .land-roles article { background: var(--plane); }
.land-roles h3, .land-gates h3 { font-size: .94rem; margin: 0 0 5px; }
.land-roles p, .land-gates p { font-size: .88rem; line-height: 1.55; color: var(--ink-2); margin: 0; }
.land-gates { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.land-gates article { border-left: 3px solid var(--warning); }

.land-boundary { background: var(--surface); }
.land-not {
  max-width: 46rem; margin: 0 auto 20px;
  display: grid; gap: 10px;
}
.land-not p {
  margin: 0; font-size: .95rem; line-height: 1.55; color: var(--ink-2);
  padding-left: 14px; border-left: 2px solid var(--critical);
}
.land-boundary-note {
  max-width: 46rem; margin: 0 auto; font-size: .87rem;
  line-height: 1.6; color: var(--ink-muted);
}
.land-boundary-note a { color: var(--accent); }

.land-foot {
  border-top: 1px solid var(--hairline); background: var(--surface);
  padding: 32px 24px 48px;
  display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap;
}
.land-foot p { margin: 0 0 4px; font-size: .86rem; color: var(--ink-muted); }
.land-foot strong { color: var(--ink); }
.land-foot nav { display: flex; flex-direction: column; gap: 6px; }
.land-foot nav a { font-size: .86rem; color: var(--ink-2); text-decoration: none; }
.land-foot nav a:hover { color: var(--accent); }

@media (max-width: 640px) {
  .land-nav { padding: 10px 14px; }
  .land-links { gap: 2px; }
  .land-links a { padding: 7px 9px; font-size: .82rem; }
  .land-hero { padding: 40px 18px 40px; }
  .land-band { padding: 40px 18px; }
  .land-actions .btn { width: 100%; justify-content: center; }
}

/* ----------------------------------------------------------- guidance
 * Collapsed by default. An adult who knows this pupil does not need to be
 * lectured; one who does not can open it. */
.guide { border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--hairline); }
.guide summary {
  cursor: pointer; padding: 11px 14px; font-size: .89rem; font-weight: 600;
  min-height: 44px; display: flex; align-items: center;
}
.guide summary::marker { color: var(--ink-muted); }
.guide-body { padding: 0 14px 8px; display: grid; gap: 14px; }
.guide-item { padding-left: 11px; border-left: 2px solid var(--accent); }
.guide-item h3 { font-size: .85rem; margin: 0 0 4px; color: var(--ink-muted);
  text-transform: none; font-weight: 600; }
.guide-do { font-size: .91rem; margin: 0 0 3px; color: var(--ink); }
.guide-why { font-size: .83rem; margin: 0; color: var(--ink-muted); font-style: italic; }

/* ------------------------------------------------------- programme layer */
/*
 * The oversight screen. Deliberately plainer than every other view: it is a
 * governance instrument, not a place anybody spends their day, and it should
 * not look like it is showing you a child.
 */

.stats {
  display: grid; gap: 12px; margin-bottom: 4px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
/* A suppressed figure is shown, never hidden — the board should see that a
 * number exists and is being withheld, rather than wonder if it is zero. */
.stat-soft .stat-value { font-size: 1.25rem; color: var(--ink-muted); font-weight: 600; }
.stat-note { font-size: .72rem; color: var(--ink-muted); }

.card-note { font-size: .78rem; color: var(--ink-muted); margin: 12px 0 0; }
.ok-note   { font-size: .82rem; color: var(--good-ink); margin: 10px 0 0; word-break: break-all; }

/* The boundary card sits above the numbers and is styled to be read, not
 * skimmed past. */
.card-boundary { border-color: color-mix(in srgb, var(--accent) 35%, var(--hairline-2)); }
.card-boundary .card-head h2 { color: var(--accent); }
.card-key { border-left: 3px solid var(--accent); }

.plain-list { margin: 0; padding-left: 18px; }
.plain-list li { margin: 0 0 6px; font-size: .86rem; line-height: 1.45; }

.seg { display: flex; gap: 6px; }
.lens-use { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }

.row-warn td { background: color-mix(in srgb, var(--warning) 14%, transparent); }

/* A categorical answer, where a 1-5 would be false precision. Sized for a
 * finger on an iPad like the scale dots are. */
.choices { display: flex; gap: 8px; flex-wrap: wrap; }
.choice {
  flex: 1 1 0; min-width: 96px; min-height: 48px; padding: 10px 14px;
  border: 1px solid var(--hairline-2); border-radius: var(--r-lg);
  background: var(--surface); color: var(--ink); font: inherit; font-weight: 550;
  cursor: pointer;
}
.choice:hover { border-color: var(--accent); }
.choice.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }

/* An adjustment and how far it has got. The open ones are marked, because
 * "agreed six weeks ago and never passed on" is the thing worth seeing. */
.adj {
  border: 1px solid var(--hairline-2); border-radius: var(--r-lg);
  padding: 12px 14px; margin-bottom: 10px; background: var(--surface);
}
.adj-open { border-left: 3px solid var(--warning-ink); }
.adj-foot { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.adj .note { margin-top: 6px; }

.states { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 8px; }
.state {
  font-size: .72rem; padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--hairline-2); color: var(--ink-muted);
}
.state.is-done { color: var(--ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.state.is-now  { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

.env-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; padding: 6px 0; }
.env-when { font-size: .76rem; color: var(--ink-muted); }
.env-note { font-size: .85rem; }

/* ------------------------------------------------- the ⓘ explainers */
/*
 * "What is this, and where does it go." Tap as well as hover: half the people
 * using this are on an iPad, where hover does not exist.
 */
.info { position: relative; display: inline-flex; vertical-align: middle; margin-left: 6px; }
.info-dot {
  width: 18px; height: 18px; line-height: 1; padding: 0;
  border-radius: 50%; border: 1px solid var(--hairline-2);
  background: var(--surface); color: var(--ink-muted);
  font: 600 11px/1 Georgia, 'Times New Roman', serif; font-style: italic;
  cursor: help; display: inline-flex; align-items: center; justify-content: center;
}
.info-dot:hover, .info-dot:focus-visible { border-color: var(--accent); color: var(--accent); }
.info-panel {
  position: absolute; z-index: 30; top: 24px; left: -8px;
  width: min(320px, 78vw); padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
  font-size: .8rem; line-height: 1.45; color: var(--ink); text-align: left;
  font-weight: 400; text-transform: none; letter-spacing: normal;
}
.info-panel strong { display: block; margin-bottom: 6px; }
.info-panel p { margin: 0 0 6px; }
.info-panel p:last-child { margin-bottom: 0; }
.info-panel b { color: var(--ink-2); }
.labelled { display: inline-flex; align-items: center; }

/* -------------------------------------------- the pupil's written notes */
.note-q { margin: 0 0 20px; }
.note-hint { font-size: .82rem; color: var(--ink-muted); margin: 2px 0 8px; line-height: 1.45; }
.share-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.share-opt {
  padding: 7px 12px; min-height: 40px; border-radius: 999px;
  border: 1px solid var(--hairline-2); background: var(--surface);
  color: var(--ink-muted); font: inherit; font-size: .82rem; cursor: pointer;
}
.share-opt.is-on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.share-who { font-size: .78rem; color: var(--ink-muted); margin: 8px 0 0; line-height: 1.45; }

/* ------------------------------------------------- the emergency button */
/*
 * Round, deep red, beside his own name at the top of his own page.
 *
 * It has moved twice. It was two full-width red bars above everything, which
 * made a wellbeing check-in look like an emergency service; then a rectangle
 * at the bottom of the sidebar, where it cleared the fold by twenty pixels
 * and nobody could find it. A round shape belongs to nothing else in this
 * interface, so it reads as its own thing at a glance.
 */
.emg { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }

.emg-btn {
  width: 74px; height: 74px; flex: 0 0 74px;
  border: none; border-radius: 50%;
  background: var(--critical-deep); color: #fff;
  font: inherit; font-size: 1.02rem; font-weight: 750; letter-spacing: .06em;
  cursor: pointer;
  box-shadow: 0 2px 5px rgba(0,0,0,.22);
  transition: transform .08s ease, filter .12s ease;
}
.emg-btn:hover  { filter: brightness(1.12); }
.emg-btn:active { transform: scale(.96); }
.emg-btn:focus-visible { outline: 3px solid var(--critical-deep); outline-offset: 3px; }

.emg-caption {
  margin: 0; max-width: 11ch;
  font-size: .78rem; line-height: 1.3; color: var(--ink-muted);
}

/* After it is pressed. The instruction is the largest thing in the panel,
 * because it is the only part he has to act on. */
.emg-sent {
  border: 2px solid var(--critical-deep); border-radius: var(--r-lg);
  padding: 14px 16px; background: var(--surface); max-width: 340px;
}
.emg-sent strong {
  display: block; font-size: 1.05rem; line-height: 1.3;
  margin-bottom: 8px; color: var(--critical-deep);
}
.emg-sent p { margin: 5px 0; font-size: .84rem; line-height: 1.45; color: var(--ink-2); }
.emg-contact { font-size: 1.15rem !important; font-weight: 700; color: var(--ink) !important; }
.emg-999 { color: var(--ink) !important; font-weight: 600; }

/* Narrow: the button drops under his name rather than squeezing it. */
@media (max-width: 560px) {
  .hero-with-aside { gap: 14px; }
  .emg-sent { max-width: none; }
}

/* What a pupil wrote, in a staff timeline. A withheld note is shown as
 * withheld rather than omitted: "he wrote something and kept it" is itself
 * worth a housemaster knowing. */
.sig-notes { margin: 8px 0 0; display: flex; flex-direction: column; gap: 8px; }
.sig-note {
  border-left: 2px solid var(--hairline-2); padding: 2px 0 2px 10px;
}
.sig-note-withheld { border-left-style: dashed; }
.sig-note-q { font-size: .74rem; color: var(--ink-muted); display: block; }
.sig-note-a { margin: 2px 0 4px; font-size: .88rem; }
.sig-note-withheld .sig-note-a { color: var(--ink-muted); font-style: italic; }

/* An unanswered emergency. Louder than anything else a pastoral screen shows,
 * and deliberately not collapsible. */
.card-emergency {
  border: 2px solid var(--serious-ink);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--serious) 18%, transparent);
}
.card-emergency .card-head h2 { color: var(--serious-ink); }
.concern-emergency { border-left: 3px solid var(--serious-ink); padding-left: 10px; }
.concern-where { font-weight: 650; margin: 6px 0; }

/* ------------------------------------------- the guide, on the landing page */
/*
 * The walkthrough is the point of the public site, so it gets a card at the
 * top of the first screen rather than a link under three sections of prose.
 */
.land-guide {
  margin: 28px 0 8px; padding: 24px 26px;
  border: 1px solid var(--hairline-2); border-left: 3px solid var(--accent);
  border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--shadow);
  max-width: 640px;
}
.land-guide h2 { margin: 0 0 8px; font-size: 1.2rem; }
.land-guide > p { margin: 0 0 14px; font-size: .92rem; line-height: 1.55; color: var(--ink-2); }
.land-guide-steps {
  margin: 0 0 20px; padding: 0 0 0 20px;
  font-size: .86rem; line-height: 1.7; color: var(--ink-2);
  columns: 2; column-gap: 28px;
}
.land-guide-steps li { break-inside: avoid; }
.land-guide .land-actions { margin: 0 0 12px; }
@media (max-width: 620px) { .land-guide-steps { columns: 1; } }

/* ===================================================== the argument diagram */
/*
 * One week, four people, on one time base. Colours come from the chart series
 * and status tokens so the picture agrees with every other chart in the
 * product, and every value is a token so it survives the dark theme.
 */
.land-argument { }
.land-figure { margin: 26px 0 0; }
.land-svg {
  width: 100%; height: auto; max-width: 860px;
  display: block; margin: 0 auto;
  font-family: var(--font);
}
.land-figure figcaption {
  max-width: 62ch; margin: 18px auto 0;
  font-size: .9rem; line-height: 1.6; color: var(--ink-2);
}

.d-grid line { stroke: var(--grid); stroke-width: 1; }
.d-rule { stroke: var(--hairline); stroke-width: 1; }

/* The six days in which all four things happened. Filled rather than outlined,
 * so the eye reads "this period" rather than "this box". */
.d-window {
  fill: color-mix(in srgb, var(--accent) 7%, transparent);
  stroke: color-mix(in srgb, var(--accent) 28%, transparent);
  stroke-width: 1;
}

.d-day text { font-size: 12px; fill: var(--ink-muted); }
.d-who  { font-size: 14px; font-weight: 600; fill: var(--ink); }
.d-what { font-size: 11.5px; fill: var(--ink-muted); }
.d-caption { font-size: 12px; fill: var(--accent); font-weight: 600; letter-spacing: .04em; }

/* A different shape per source as well as a different colour: the picture has
 * to survive being printed in grey, and about one boy in twelve at any school
 * cannot tell these two colours apart. */
.d-mark-1 { fill: var(--series-1); }
.d-mark-2 { fill: var(--series-2); }
.d-mark-3 { fill: var(--warning-ink); }
.d-mark-4 { fill: none; stroke: var(--good-ink); stroke-width: 2.5; stroke-linecap: round; }

/* Below the width at which the labels stay readable, the figure scrolls
 * rather than shrinking. A hint is shown so nobody misses that it does. */
.land-figure-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 700px) {
  .land-svg { min-width: 620px; }
  .land-figure-scroll::after {
    content: 'Scroll sideways to see the whole week';
    display: block; font-size: .74rem; color: var(--ink-muted); padding: 4px 0 0;
  }
}

/* ------------------------------------------------- what the pupil decides */
.land-share {
  display: grid; gap: 22px; margin: 24px 0 28px;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  align-items: start;
}
.land-share-prompt {
  font-size: 1.12rem; font-weight: 600; line-height: 1.45;
  margin: 0 0 10px; color: var(--ink);
}
.land-share-sub { font-size: .88rem; color: var(--ink-muted); margin: 14px 0 0; line-height: 1.55; }
.land-share-opts { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.land-share-opts li {
  padding: 13px 16px; border: 1px solid var(--hairline-2);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-lg); background: var(--surface);
}
.land-share-opts strong { display: block; font-size: .95rem; margin-bottom: 3px; }
.land-share-opts span { font-size: .85rem; color: var(--ink-2); line-height: 1.5; }

.land-two { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.land-two h3 { margin: 0 0 8px; font-size: 1rem; }
.land-two p { margin: 0; font-size: .9rem; line-height: 1.62; color: var(--ink-2); }

.land-pilot { margin-top: 24px; }

@media (max-width: 760px) { .land-share { grid-template-columns: 1fr; } }

/* The way back to the landing page, first in the sidebar of the walkthrough.
 * The landing page is the front door: it explains what the walkthrough is
 * before dropping anybody inside it. */
.btn-home { font-weight: 600; }

/* --------------------------------------------------------- Magnificent Me */
/*
 * A win shown back to a boy weeks later. Deliberately warm rather than
 * clinical: this is the one card on his page that exists to be pleasant.
 * The method is given the most weight, because it is the half he can use
 * again — the rest is just a nice memory.
 */
.card-win {
  border: 1px solid color-mix(in srgb, var(--good) 40%, var(--hairline-2));
  background: linear-gradient(180deg, color-mix(in srgb, var(--good) 6%, var(--surface)), var(--surface));
}
.card-win .card-head h2 { color: var(--good-ink); }
.win-what { font-size: 1.15rem; font-weight: 600; margin: 0 0 8px; line-height: 1.35; }
.win-felt { font-style: italic; color: var(--ink-2); margin: 0 0 14px; }
.win-how {
  border-left: 3px solid var(--good); padding: 2px 0 2px 12px; margin: 0 0 12px;
}
.win-how-l {
  display: block; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--good-ink); font-weight: 700; margin-bottom: 2px;
}
.win-how p { margin: 0; font-size: .95rem; line-height: 1.5; }
.win-when { font-size: .78rem; color: var(--ink-muted); margin: 0; }

/* ------------------------------------------------ flags, and replies to them */
.flagrow {
  border: 1px solid var(--hairline-2); border-radius: var(--r-lg);
  padding: 12px 14px; margin-bottom: 10px; background: var(--surface);
}
.replies { list-style: none; margin: 10px 0; padding: 0 0 0 12px; border-left: 2px solid var(--hairline-2); }
.replies li { margin: 0 0 8px; font-size: .87rem; line-height: 1.5; }
.replies strong { display: block; font-size: .78rem; color: var(--ink-2); }
.replies em { display: block; font-size: .72rem; color: var(--ink-muted); font-style: normal; }
.flag-next { font-size: .78rem; color: var(--accent); margin: 10px 0 0; font-weight: 600; }

/* A live character count for a parent's note. Shown as it is typed, never
 * sprung on submit: a parent told to cut four hundred words will not write
 * again. */
.charcount { font-size: .76rem; color: var(--ink-muted); margin: 4px 0 0; text-align: right; }
.charcount.is-near { color: var(--warning-ink); }
.charcount.is-over { color: var(--critical); font-weight: 600; }

/* ------------------------------------------------- density, after Flexili */
/*
 * The page was not wrong, it was loud. These are the rules that quieten it:
 * fewer competing surfaces, less chrome per element, and anything secondary
 * one tap away rather than open by default.
 */

/* A disclosure that does not look like a widget. */
.help-more, .help-ask { border-top: 1px solid var(--hairline); margin-top: 14px; padding-top: 12px; }
.help-more > summary, .help-ask > summary {
  cursor: pointer; font-size: .85rem; font-weight: 600; color: var(--accent);
  list-style: none; padding: 4px 0; min-height: 36px; display: flex; align-items: center; gap: 6px;
}
.help-more > summary::-webkit-details-marker, .help-ask > summary::-webkit-details-marker { display: none; }
.help-more > summary::before, .help-ask > summary::before {
  content: '+'; font-weight: 700; width: 14px; display: inline-block;
}
.help-more[open] > summary::before, .help-ask[open] > summary::before { content: '\2013'; }

/* The 999 line. Quieter than it was — it was a filled red panel competing
 * with the SOS button two inches above it. Still unmissable. */
.help-emergency {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
  padding: 10px 12px; border-radius: var(--r);
  background: #FEF2F2; border: 1px solid #FECACA;
}
.help-emergency strong { font-size: .85rem; }
.help-action { font-weight: 800; color: var(--critical-deep); }
.help-detail { font-size: .78rem; color: var(--ink-muted); }
.help-list { list-style: none; margin: 8px 0 0; padding: 0; }
.help-list li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 8px 0; border-bottom: 1px solid var(--hairline-2);
}
.help-list li:last-child { border-bottom: 0; }
.help-list strong { display: block; font-size: .87rem; }
.help-contact { font-weight: 700; color: var(--accent); white-space: nowrap; font-size: .87rem; }
.help-lead { font-size: .78rem; color: var(--ink-muted); margin: 8px 0 0; }

/* Numbers row: smaller, flatter, no longer three floating panels. */
.stat {
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: var(--r); padding: 12px 14px; box-shadow: none;
}
.stat-value { font-size: 1.5rem; font-weight: 800; }
.stats-row { margin-bottom: 16px; }

/* ---------------------------------------------------------- walkthrough gate

   Covers the page until a school code is accepted. Deliberately plain: it is
   the first thing a head teacher sees, and a wall of product copy in front of
   a single text box reads as a sales page rather than a tool. */

.gate {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--plane);
}

.gate-card {
  width: 100%;
  max-width: 26rem;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.gate-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.gate-sub {
  margin: 0 0 8px;
  color: var(--ink-2);
  line-height: 1.5;
}

.gate-label {
  font-weight: 600;
  color: var(--ink);
}

.gate-input {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 10px;
}

.gate-input:focus-visible {
  outline: 2px solid var(--series-1);
  outline-offset: 1px;
  border-color: var(--series-1);
}

/* Spoken by a screen reader the moment it appears, because the person who
   mistyped the code is often the person who cannot see it turn red. */
.gate-error {
  margin: 0;
  color: var(--bad, #DC2626);
  line-height: 1.5;
}

.gate-go { margin-top: 4px; }

.gate-foot {
  margin: 4px 0 0;
  color: var(--ink-muted);
}

.gate-foot a { color: var(--ink-2); }

/* Below the sign-in form: the way out for someone who has not met this
   before. Separated by a hairline so it reads as a different question, not as
   another step in signing in. */
.signin-foot {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.signin-foot .signin-note { text-align: center; margin: 0; }

/* ------------------------------------------------------------ instance band

   Only ever rendered on a labelled instance — a test or staging copy. It has
   to survive being scrolled past and must sit above the walkthrough gate,
   because the one moment it matters is the moment somebody is about to type
   something real into the wrong system. */

.instance-band {
  position: sticky;
  top: 0;
  z-index: 70;
  padding: 7px 16px;
  text-align: center;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: #7C2D12;
  background: #FFEDD5;
  border-bottom: 1px solid #FDBA74;
}
