/* ============================================================
   Self-hosted fonts (SIL Open Font Licence; licences in site/fonts/licences).
   Nothing loads from a font service.
   ============================================================ */
@font-face { font-family: "Atkinson Hyperlegible"; src: url("../fonts/AtkinsonHyperlegible-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Atkinson Hyperlegible"; src: url("../fonts/AtkinsonHyperlegible-Bold.ttf") format("truetype"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Atkinson Hyperlegible"; src: url("../fonts/AtkinsonHyperlegible-Italic.ttf") format("truetype"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "OpenDyslexic"; src: url("../fonts/OpenDyslexic-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "OpenDyslexic"; src: url("../fonts/OpenDyslexic-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }

/* ============================================================
   Scatter: the look. Colours are named once here. The supports kit
   (css/supports.css, from Home Ground) sets classes on <html> such as
   hg-s-contrast-on; the rules below follow those classes.
   ============================================================ */
:root {
  /* The sign-in field (before we know the year): a bright morning field. */
  --sky-top: #fdf3dc;
  --sky-mid: #f7e2b4;
  --sunrise: #e6cf8a;
  --dawn: #a9c56f;
  --hill-back: #c9d58c;
  --hill-mid: #a7c46e;
  --paper: #fffaf0;
  --card: #ffffff;
  --ink: #1d2340;
  --ink-soft: #4a5275;
  --line: #e3dccb;
  --grain: #ffb02e;
  --accent: #2d6a4f;       /* buttons: a deep field green */
  --accent-ink: #ffffff;
  --good: #1f9d55;
  --quiet: #8a8fa6;
  --warn-bg: #fff1c2;
  --warn-ink: #5b4300;
  --focus: #ff4fa3;
  --shadow: 0 10px 30px rgba(29, 35, 64, .18);
  --radius: 22px;
  --heading: "Atkinson Hyperlegible", system-ui, sans-serif;   /* Fredoka dropped: rounded type reads young */
  --sky-ink: #1f2410;   /* text on the header band; each year sets its own */
  /* "Tell my teacher": one calm colour in every look, never an alarm red */
  --calm: #35506b; --calm-ink: #ffffff;
  --reading: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 17px;
}
/* Stronger contrast: black on white, thick lines, no soft greys. */
html.hg-s-contrast-on {
  --sky-top: #fff; --sky-mid: #fff; --sunrise: #fff; --dawn: #fff; --sky-ink: #000; --calm: #000; --calm-ink: #fff;
  --paper: #fff; --card: #fff; --ink: #000; --ink-soft: #000; --line: #000;
  --accent: #000; --accent-ink: #fff; --quiet: #000; --focus: #0047ff;
  --warn-bg: #fff; --warn-ink: #000; --shadow: none;
}
html.hg-s-contrast-on .card, html.hg-s-contrast-on .panel, html.hg-s-contrast-on dialog, html.hg-s-contrast-on .btn, html.hg-s-contrast-on input, html.hg-s-contrast-on select { border: 3px solid #000 !important; }
html.hg-s-contrast-on .sky { background: #fff !important; }
html.hg-s-contrast-on .sky * { color: #000 !important; }

* { box-sizing: border-box; }
body {
  margin: 0; color: var(--ink); background: var(--paper);
  font-family: var(--reading); line-height: 1.55;
}
h1, h2, h3, .brand { font-family: var(--heading); line-height: 1.2; }
a { color: var(--accent); }
:focus-visible { outline: 4px solid var(--focus); outline-offset: 3px; border-radius: 8px; }
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 16px; }
/* Anything marked hidden stays hidden, whatever display rule it also has. */
[hidden] { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }


/* ---- the sky header ---- */
.sky {
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 55%, var(--sunrise) 88%, var(--dawn) 100%);
  color: #fff; position: relative; overflow: hidden;
}
.sky .wrap { position: relative; z-index: 1; }
.sky-hills { display: block; width: 100%; height: 70px; margin-top: -1px; }
.topbar { display: flex; align-items: center; gap: 12px; padding-top: 14px; padding-bottom: 14px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: 10px; font-size: 1.5rem; font-weight: 800; letter-spacing: .01em; color: var(--sky-ink); text-decoration: none; }
.brand svg { width: 38px; height: 38px; }
.topbar .spacer { flex: 1; }

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 10px 20px; border-radius: 12px; border: 2px solid transparent;
  background: var(--accent); color: var(--accent-ink);
  font: 700 1rem/1.2 var(--heading); cursor: pointer; text-decoration: none;
}
.btn:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; color: var(--sky-ink); border-color: var(--sky-ink); }
.btn.light { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.big { min-height: 58px; font-size: 1.15rem; padding: 12px 28px; }
.btn.small { min-height: 38px; padding: 6px 14px; font-size: .9rem; }
.btn.danger { background: #c8323a; }
html.hg-s-contrast-on .btn.ghost { background: #fff; color: #000; }

/* ---- panels and fields ---- */
.panel { background: var(--card); color: var(--ink); border-radius: var(--radius); box-shadow: var(--shadow); padding: 24px; border: 1px solid var(--line); }
label { display: block; font-weight: 700; margin: 14px 0 6px; }
input, select, textarea {
  width: 100%; min-height: 50px; padding: 10px 14px; font: 1.05rem var(--reading);
  border: 2px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink);
}
textarea { min-height: 110px; resize: vertical; }
.hint { color: var(--ink-soft); font-size: .92rem; margin: 6px 0 0; }
.pin-boxes { display: flex; gap: 8px; }
.pin-boxes input { width: 3rem; text-align: center; font-size: 1.4rem; padding: 6px 0; }

/* ---- sign-in page ---- */
.arrive { display: grid; grid-template-columns: 1.1fr 1fr; gap: 28px; align-items: center; padding-top: 24px; padding-bottom: 48px; }
.arrive h1 { font-size: 2.4rem; margin: 0 0 10px; color: var(--sky-ink); }
.arrive .lead { font-size: 1.15rem; color: var(--sky-ink); max-width: 32ch; }
.doors { display: flex; gap: 10px; margin-top: 18px; }
.doors span { width: 54px; height: 76px; border-radius: 28px 28px 6px 6px; border: 3px solid rgba(255,255,255,.9);
  box-shadow: 0 0 18px rgba(255, 230, 150, .7); position: relative; }
.doors span::after { content: ""; position: absolute; right: 9px; top: 40px; width: 6px; height: 6px; border-radius: 50%; background: #ffe9a8; }
/* One door per world, in that world's colour. */
.doors span:nth-child(1) { background: #2b9a5a; }
.doors span:nth-child(2) { background: #6d3fd1; }
.doors span:nth-child(3) { background: #e0823d; }
.doors span:nth-child(4) { background: #c9902b; }
.doors span:nth-child(5) { background: #e8434f; }
html.hg-s-contrast-on .doors span { background: #fff; border-color: #000; box-shadow: none; }
.steps { display: flex; gap: 8px; margin: 0 0 8px; padding: 0; list-style: none; }
.steps li { flex: 1; height: 6px; border-radius: 3px; background: var(--line); }
.steps li.on { background: var(--accent); }
.codename-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chip { border: 2px solid var(--line); border-radius: 999px; padding: 8px 14px; background: #fff; font: 600 1rem var(--reading); cursor: pointer; color: var(--ink); }
.chip[aria-pressed="true"] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, #fff); }
html.hg-s-contrast-on .chip[aria-pressed="true"] { background: #000; color: #fff; }
.notice { border-radius: 14px; padding: 12px 16px; background: var(--warn-bg); color: var(--warn-ink); font-weight: 600; }
.notice.locked { background: #ffe3e3; color: #6b1016; }
html.hg-s-contrast-on .notice { border: 3px solid #000; }

/* ---- the verse under the sign-in heading (Mark 4:28) ---- */
.verse { margin: 0 0 12px; font-size: 1.05rem; font-style: italic; color: var(--sky-ink); opacity: .95; max-width: 34ch; }
.verse cite { font-style: normal; font-weight: 700; margin-left: 4px; white-space: nowrap; }
html.hg-s-look-night .verse { color: var(--ink-soft); }
html.hg-s-contrast-on .verse { color: #000; }

/* ---- welcome ---- */
.welcome { display: flex; align-items: center; gap: 22px; padding-top: 18px; padding-bottom: 36px; flex-wrap: wrap; }
.welcome .me { width: 132px; height: 132px; border-radius: 50%; background: rgba(255,255,255,.9); padding: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.18); }
.welcome h1 { font-size: 2.2rem; margin: 0; color: var(--sky-ink); }
.welcome p { margin: 4px 0 0; font-size: 1.1rem; color: var(--sky-ink); }
.until { display: inline-flex; gap: 6px; align-items: center; background: color-mix(in srgb, var(--sky-ink) 14%, transparent); color: var(--sky-ink); border-radius: 10px; padding: 6px 14px; font-weight: 700; margin-top: 10px; }
.stage-name { display: block; font-weight: 700; font-size: .95rem; letter-spacing: .04em; text-transform: uppercase; color: var(--sky-ink); opacity: .85; margin-bottom: 4px; }
html.hg-s-contrast-on .until { border: 2px solid #000; }

.signout-warning { display: none; position: sticky; top: 0; z-index: 5; background: var(--warn-bg); color: var(--warn-ink); padding: 12px 16px; font-weight: 700; text-align: center; border-bottom: 2px solid #e6c65a; }
.signout-warning.show { display: block; }

/* ---- the cards ---- */
.cards-head { display: flex; align-items: baseline; gap: 12px; margin: 26px 0 12px; flex-wrap: wrap; }
.cards-head h2 { margin: 0; font-size: 1.6rem; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 22px; padding-bottom: 40px; }
.card {
  background: var(--card); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
  display: flex; flex-direction: column; border: 1px solid var(--line); transition: transform .15s;
}
.card:hover { transform: translateY(-3px); }
.card img { display: block; width: 100%; aspect-ratio: 400 / 220; object-fit: cover; }
.card .body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.card h3 { margin: 0; font-size: 1.35rem; }
.card p { margin: 0; color: var(--ink-soft); }
.card .row { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 8px; flex-wrap: wrap; }
/* A locked app: greyed out, a lock over the picture, nothing to click. */
.card.is-locked { cursor: default; }
.card.is-locked:hover { transform: none; }
.card.is-locked .art { position: relative; display: block; }
.card.is-locked .art img { filter: grayscale(1) opacity(.55); }
.card.is-locked h3, .card.is-locked p { color: var(--ink-soft); }
.card .lock-badge { position: absolute; inset: 0; display: grid; place-items: center; }
.card .lock-badge svg { width: 56px; height: 56px; padding: 12px; border-radius: 50%; background: rgba(255,255,255,.92);
  fill: none; stroke: #2b3330; stroke-width: 2.2; stroke-linecap: round; box-shadow: 0 2px 10px rgba(0,0,0,.2); }
.card .btn.is-off { background: transparent; color: var(--ink-soft); border: 2px dashed currentColor; box-shadow: none; cursor: default; text-align: center; }
.status { display: inline-flex; align-items: center; gap: 6px; font-size: .9rem; font-weight: 600; color: var(--ink-soft); }
.status::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--quiet); box-shadow: 0 0 0 3px rgba(0,0,0,.06); }
.status.up::before { background: var(--good); box-shadow: 0 0 0 3px rgba(31,157,85,.2); }
.tag { font-size: .8rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: #eef2ff; color: #2b3a8c; }
html.hg-s-contrast-on .tag { border: 2px solid #000; background: #fff; color: #000; }

/* ---- floating helpers ---- */
.helpers { position: fixed; right: 16px; bottom: 16px; display: flex; gap: 10px; z-index: 6; }
.helpers .btn { box-shadow: var(--shadow); }
.round { width: 58px; height: 58px; padding: 0; border-radius: 50%; font-size: 1.3rem; }

/* ---- dialogs ---- */
dialog { border: 0; border-radius: var(--radius); padding: 0; width: min(560px, calc(100vw - 32px)); box-shadow: 0 20px 60px rgba(0,0,0,.35); color: var(--ink); background: var(--card); }
dialog::backdrop { background: rgba(20, 24, 50, .55); }
.dlg { padding: 24px; }
.dlg h2 { margin: 0 0 8px; }
.dlg .actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; margin-top: 18px; }
.opt-group { border-top: 1px solid var(--line); padding: 14px 0; }
.opt-group h3 { margin: 0 0 8px; font-size: 1.05rem; }
.seg { display: flex; gap: 8px; flex-wrap: wrap; }
.seg button { flex: 1; min-height: 46px; border-radius: 14px; border: 2px solid var(--line); background: #fff; font: 600 1rem var(--reading); color: var(--ink); cursor: pointer; }
.seg button[aria-pressed="true"] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, #fff); }
html.hg-s-contrast-on .seg button[aria-pressed="true"] { background: #000; color: #fff; }
.plainly { font-weight: 700; border-left: 6px solid var(--grain); padding: 8px 12px; background: #fff7e0; border-radius: 8px; }
html.hg-s-contrast-on .plainly { background: #fff; border-left-color: #000; }
/* "If it is serious": its own box, every time the message box opens. */
.tell-serious { border-left: 6px solid #2f6db3; padding: 8px 12px; background: #eaf2fb; border-radius: 8px; color: var(--ink); }
html.hg-s-contrast-on .tell-serious { background: #fff; border-left-color: #000; }

.guide { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 10px; }
.guide figure { margin: 0; background: #f5f2ff; border-radius: 16px; padding: 10px; text-align: center; }
.guide svg { width: 100%; height: 96px; }
.guide figcaption { font-size: .92rem; font-weight: 600; margin-top: 6px; }
.guide-list { display: grid; gap: 10px; }
.guide-list button { text-align: left; }

.tour { text-align: center; }
.tour svg { width: 160px; height: 120px; }
.dots { display: flex; justify-content: center; gap: 6px; margin: 10px 0; }
.dots span { width: 10px; height: 10px; border-radius: 50%; background: var(--line); }
.dots span.on { background: var(--accent); }

/* ---- teacher view ---- */
.t-shell { background: #f4f6fb; min-height: 100vh; }
html.hg-s-contrast-on .t-shell { background: #fff; }
.t-top { background: linear-gradient(90deg, #2c4fa8, #6d3fd1); color: #fff; }
.t-top .brand { font-size: 1.25rem; }
.tabs { display: flex; gap: 6px; flex-wrap: wrap; padding-bottom: 10px; }
.tabs button { background: rgba(255,255,255,.15); color: #fff; border: 0; border-radius: 12px; padding: 10px 16px; font: 700 .98rem var(--heading); cursor: pointer; position: relative; }
.tabs button[aria-selected="true"] { background: #fff; color: #2c2c6c; }
html.hg-s-contrast-on .tabs button { background: #fff; color: #000; border: 2px solid #000; }
html.hg-s-contrast-on .tabs button[aria-selected="true"] { background: #000; color: #fff; }
.badge { display: inline-block; min-width: 22px; padding: 1px 7px; border-radius: 999px; background: #ff4f5e; color: #fff; font-size: .8rem; margin-left: 6px; }
.t-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin: 18px 0; }
.stat { background: #fff; border-radius: 16px; padding: 16px; border: 1px solid var(--line); }
.stat .n { font: 800 2.1rem/1 var(--heading); }
.stat .k { color: var(--ink-soft); font-weight: 600; margin-top: 6px; }
table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 14px; overflow: hidden; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
th { background: #eef1f8; font-size: .9rem; }
html.hg-s-contrast-on th { background: #fff; border-bottom: 3px solid #000; }
.who { display: flex; align-items: center; gap: 10px; font-weight: 700; }
.who svg { width: 34px; height: 34px; flex: none; }
.dot-on { color: var(--good); font-weight: 700; }
.muted { color: var(--ink-soft); }
.week { display: flex; gap: 4px; }
.week span { width: 22px; height: 22px; border-radius: 6px; background: #e6e9f2; font-size: .7rem; display: grid; place-items: center; color: #6b7190; }
.week span.in { background: #63c27a; color: #fff; }
html.hg-s-contrast-on .week span { border: 2px solid #000; background: #fff; color: #000; }
html.hg-s-contrast-on .week span.in { background: #000; color: #fff; }
.flag { display: flex; gap: 12px; align-items: center; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; }
.flag .fact { font-weight: 600; }
.section-title { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 26px 0 10px; }
.section-title h2 { margin: 0; }
.rules { font-size: .92rem; color: var(--ink-soft); }
.msg { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 14px; display: grid; gap: 8px; }
.msg.unread { border-left: 6px solid #ff4f5e; }
.log td:first-child { white-space: nowrap; }
.bars { display: grid; gap: 8px; }
.bar { display: grid; grid-template-columns: 150px 1fr 40px; gap: 10px; align-items: center; }
.bar .track { height: 18px; background: #e6e9f2; border-radius: 9px; overflow: hidden; }
.bar .fill { height: 100%; border-radius: 9px; }
.chart svg { width: 100%; height: auto; }
.myweek { background: linear-gradient(160deg, #fff7e0, #ffe9f3); border-radius: 26px; padding: 22px; border: 3px dashed #ffb02e; }
html.hg-s-contrast-on .myweek { background: #fff; border: 3px solid #000; }
.stamps { display: flex; gap: 10px; flex-wrap: wrap; margin: 10px 0 16px; }
.stamp { width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center; font: 800 .95rem var(--heading); border: 3px solid #d8d2c2; color: #a59f8f; background: #fff; }
.stamp.got { border-color: #1f9d55; color: #1f9d55; transform: rotate(-8deg); }
html.hg-s-contrast-on .stamp.got { border-color: #000; color: #000; background: #ddd; }

@media (max-width: 760px) {
  .arrive { grid-template-columns: 1fr; }
  .arrive h1 { font-size: 1.9rem; }
  .guide { grid-template-columns: 1fr; }
  .bar { grid-template-columns: 110px 1fr 34px; }
  .welcome .me { width: 96px; height: 96px; }
  .welcome h1 { font-size: 1.7rem; }
}
@media print {
  .no-print, .helpers, .tabs, .t-top, .topbar { display: none !important; }
  .t-shell { background: #fff; }
}
@media (prefers-reduced-motion: reduce) { .card { transition: none; } }

/* ============================================================
   NIGHT: a dark look any student can choose ("Aa", Your look: Night).
   A deep night sky with faint points of light; cards and text light on
   dark. Every pair is checked by tools/check_contrast.mjs.
   ============================================================ */
html.hg-s-look-night {
  --sky-top: #0e1726; --sky-mid: #14223a; --sunrise: #1b2c48; --dawn: #1b2c48;
  --sky-ink: #eef2f8; --hill-back: #1a2840; --hill-mid: #15223a;
  --paper: #0f1828; --card: #172338; --ink: #eef2f8; --ink-soft: #b6c0d3; --line: #2a3a57;
  --accent: #f2a541; --accent-ink: #1a1206; --quiet: #6f7c96; --focus: #7fd3ff;
  --warn-bg: #3a2c0c; --warn-ink: #ffe3a3;
  --heading: "Atkinson Hyperlegible", system-ui, sans-serif;
  --radius: 12px; --shadow: 0 6px 18px rgba(0, 0, 0, .35);
}
/* ============================================================
   LEDGER and PLAIN: two more looks a student can choose (Aa, Your look).
   Ledger is a field-notebook look (paper, ink, one teal accent, serif
   headings, a contour map for growth). Plain is white and black with no
   pictures. Their colours are here so tools/check_contrast.mjs checks
   them; the rest of Ledger is in css/look-ledger.css, loaded only while
   the "ledger" switch in content/effects.js is on.
   ============================================================ */
html.feat-studio.hg-s-look-ledger {
  --sky-top: #F4EFE4; --sky-mid: #F4EFE4; --sunrise: #F4EFE4; --dawn: #F4EFE4;
  --sky-ink: #1F2A30; --hill-back: #F4EFE4; --hill-mid: #F4EFE4;
  --paper: #F4EFE4; --card: #FBF8F1; --ink: #1F2A30; --ink-soft: #4D5A62; --line: #CFC5B1;
  --accent: #1F6F6B; --accent-ink: #FFFFFF; --quiet: #6B767C; --focus: #1F6F6B;
  --warn-bg: #FBEFC9; --warn-ink: #4A3A07;
  --heading: Georgia, "Iowan Old Style", Charter, "Times New Roman", serif;
  --radius: 8px; --shadow: none;
}
html.feat-studio.hg-s-look-plain {
  --sky-top: #FFFFFF; --sky-mid: #FFFFFF; --sunrise: #FFFFFF; --dawn: #FFFFFF;
  --sky-ink: #111111; --hill-back: #FFFFFF; --hill-mid: #FFFFFF;
  --paper: #FFFFFF; --card: #FFFFFF; --ink: #111111; --ink-soft: #444444; --line: #BBBBBB;
  --accent: #1A4FB8; --accent-ink: #FFFFFF; --quiet: #666666; --focus: #1A4FB8;
  --warn-bg: #FFF4CC; --warn-ink: #3F3200;
  --heading: system-ui, -apple-system, "Segoe UI", sans-serif;
  --radius: 6px; --shadow: none;
}
html.feat-studio.hg-s-look-plain .sky-hills, html.feat-studio.hg-s-look-plain .sky-light, html.feat-studio.hg-s-look-plain .wc-fx, html.feat-studio.hg-s-look-plain .amb-bees, html.feat-studio.hg-s-look-plain .wc-plot, html.feat-studio.hg-s-look-plain #field, html.feat-studio.hg-s-look-plain .year-fade { display: none; }
html.feat-studio.hg-s-look-plain .sky { background: #fff; border-bottom: 1px solid var(--line); }
html.feat-studio.hg-s-look-plain .card:hover { transform: none; }

/* A neutral night sky of faint points of light: no subject owns it. */
html.hg-s-look-night body { background:
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cg fill='%23ffffff' fill-opacity='.07'%3E%3Ccircle cx='37' cy='52' r='1.6'/%3E%3Ccircle cx='140' cy='18' r='1'/%3E%3Ccircle cx='222' cy='96' r='1'/%3E%3Ccircle cx='310' cy='40' r='1.6'/%3E%3Ccircle cx='402' cy='130' r='1'/%3E%3Ccircle cx='520' cy='64' r='1'/%3E%3Ccircle cx='588' cy='170' r='1.6'/%3E%3Ccircle cx='64' cy='210' r='1'/%3E%3Ccircle cx='180' cy='250' r='1'/%3E%3Ccircle cx='260' cy='190' r='1.6'/%3E%3Ccircle cx='350' cy='280' r='1'/%3E%3Ccircle cx='470' cy='236' r='1'/%3E%3Ccircle cx='560' cy='330' r='1.6'/%3E%3Ccircle cx='30' cy='360' r='1'/%3E%3Ccircle cx='120' cy='420' r='1'/%3E%3Ccircle cx='240' cy='380' r='1.6'/%3E%3Ccircle cx='330' cy='470' r='1'/%3E%3Ccircle cx='440' cy='400' r='1'/%3E%3Ccircle cx='540' cy='500' r='1.6'/%3E%3Ccircle cx='80' cy='540' r='1'/%3E%3Ccircle cx='200' cy='560' r='1'/%3E%3Ccircle cx='380' cy='560' r='1.6'/%3E%3Ccircle cx='500' cy='590' r='1'/%3E%3C/g%3E%3C/svg%3E") var(--paper); }
html.hg-s-look-night .sky { background: transparent; border-bottom: 1px solid var(--line); }
html.hg-s-look-night .sky-hills { display: none; }
html.hg-s-look-night h1, html.hg-s-look-night h2, html.hg-s-look-night h3, html.hg-s-look-night .brand { letter-spacing: -.01em; }
html.hg-s-look-night .brand { color: var(--ink); }
html.hg-s-look-night .btn { border-radius: 10px; }
html.hg-s-look-night .btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
html.hg-s-look-night .btn.light { background: #22314d; color: var(--ink); border-color: var(--line); }
html.hg-s-look-night .chip, html.hg-s-look-night .seg button, html.hg-s-look-night input, html.hg-s-look-night select, html.hg-s-look-night textarea { background: #0f1828; color: var(--ink); border-color: var(--line); border-radius: 10px; }
html.hg-s-look-night .chip[aria-pressed="true"], html.hg-s-look-night .seg button[aria-pressed="true"] { background: #3a2a0d; border-color: var(--accent); }
html.hg-s-look-night .doors span { border-radius: 6px; box-shadow: none; border-width: 2px; opacity: .9; }
html.hg-s-look-night .welcome .me { background: transparent; box-shadow: none; padding: 0; }
html.hg-s-look-night .until { background: #22314d; }
html.hg-s-look-night .tag { background: #22314d; color: var(--ink-soft); }
html.hg-s-look-night .card { border-color: var(--line); }
html.hg-s-look-night .card:hover { transform: none; border-color: var(--accent); }
html.hg-s-look-night .plainly { background: #2a2210; color: var(--ink); }
html.hg-s-look-night .tell-serious { background: #142235; color: var(--ink); }
html.hg-s-look-night .notice.locked { background: #3d1418; color: #ffd0d4; }
html.hg-s-look-night dialog { border: 1px solid var(--line); }
html.hg-s-look-night .guide figure { background: #22314d; }
html.hg-s-look-night .t-shell { background: var(--paper); }
html.hg-s-look-night .t-top { background: #0b1220; border-bottom: 1px solid var(--line); }
html.hg-s-look-night .tabs button { background: transparent; color: var(--ink-soft); }
html.hg-s-look-night .tabs button[aria-selected="true"] { background: #22314d; color: var(--ink); }
html.hg-s-look-night .stat, html.hg-s-look-night .flag, html.hg-s-look-night .msg, html.hg-s-look-night table { background: var(--card); }
html.hg-s-look-night th { background: #1d2a43; }
html.hg-s-look-night .week span { background: #22314d; color: var(--ink-soft); }
html.hg-s-look-night .week span.in { background: #2f9e5c; color: #fff; }
html.hg-s-look-night .myweek { background: var(--card); border: 1px solid var(--line); }
html.hg-s-look-night .stamp { border-radius: 10px; transform: none; background: #0f1828; border-color: var(--line); color: var(--ink-soft); }
html.hg-s-look-night .stamp.got { transform: none; background: #2f9e5c; border-color: #2f9e5c; color: #fff; }
html.hg-s-look-night .chart text { fill: var(--ink); }
/* High contrast still wins over either look. */
html.hg-s-look-night.hc { --paper: #fff; --card: #fff; --ink: #000; --ink-soft: #000; --line: #000; --accent: #000; --accent-ink: #fff; }
html.hg-s-look-night.hc body { background: #fff; }

/* The letter options come last, so they win over either look. */
/* "Plainer letters": a wide, simple face every laptop already has. */
html.hg-s-font-plain { --reading: Verdana, Tahoma, "DejaVu Sans", sans-serif; --heading: Verdana, Tahoma, sans-serif; }
/* "Dyslexia-friendly": OpenDyslexic, from the hub's own folder. */
html.hg-s-font-dys {
  --reading: "OpenDyslexic", Verdana, Tahoma, sans-serif;
  --heading: "OpenDyslexic", Verdana, Tahoma, sans-serif;
  word-spacing: .08em;   /* OpenDyslexic is already wide: no extra letter spacing */
}
html.hg-s-font-dys p, html.hg-s-font-dys li { line-height: 1.75; }

/* ============================================================
   The growing mark (js/mark.js). Seeds, then stalk, then head, then
   the grains ripen from green to gold. Once, not looping.
   ============================================================ */
.m-stalk, .m-leaf { fill: none; stroke: #7bc96f; stroke-linecap: round; }
.m-stalk { stroke-width: 3; }
.m-leaf { stroke-width: 2.5; }
.m-grain { fill: #f2c94c; }
.grow .m-seed  { animation: m-drop .45s ease-out both; }
.grow .m-stalk { stroke-dasharray: 1; animation: m-draw .8s .45s ease-out both; }
.grow .m-leaf  { stroke-dasharray: 1; animation: m-draw .5s 1s ease-out both; }
.grow .m-grain { transform-box: fill-box; transform-origin: 50% 100%;
                 animation: m-sprout .35s ease-out both, m-ripen .9s ease-in both; }
@keyframes m-drop   { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes m-draw   { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes m-sprout { from { scale: 0; } to { scale: 1; } }
@keyframes m-ripen  { from { fill: #9bd46a; } to { fill: #f2c94c; } }
@media (prefers-reduced-motion: reduce) {
  .grow .m-seed, .grow .m-stalk, .grow .m-leaf, .grow .m-grain { animation: none; }
}
/* The big one on the sign-in screen, in place of the doors. */
.hero-mark { display: block; width: 120px; height: 120px; margin-top: 10px; cursor: default; }
.hero-mark svg, .brand [data-mark] svg { width: 100%; height: 100%; }
.brand [data-mark] { width: 38px; height: 38px; display: inline-block; }
html.hg-s-look-night .m-stalk, html.hg-s-look-night .m-leaf { stroke: #8fd47f; }
html.hg-s-contrast-on .m-stalk, html.hg-s-contrast-on .m-leaf { stroke: #000; }
html.hg-s-contrast-on .m-grain { fill: #000; }

/* ============================================================
   THE YEAR LOOKS. Scatter grows with the student (Mark 4:28):
     7 Seed · 8 Shoot · 9 Stalk · 10 Head · 11 Ripening · 12 Full grain
   Only the header band, its text colour and the accent change. The page
   and cards stay cream and white with dark text in every year, because
   dark text on a light, warm background reads best (polarity research;
   Rello & Bigham 2017). Every header pair is checked for contrast:
   light headers (7, 8) carry dark text, deeper ones (9 to 12) white.
   "Night" (a student's own choice) is the dark look, and wins over these.
   ============================================================ */
/* One continuous palette: the crop maturing from soil to harvest.
   --sky-* is the header band, top to bottom; --sky-ink its text;
   --hill-* the field's back and middle rows; --accent the buttons. */
html[data-year="7"]:not(.hg-s-look-night)  { --sky-top: #fbe0bf; --sky-mid: #f4c79c; --sunrise: #e2a679; --dawn: #b98058;
  --sky-ink: #2b1709; --hill-back: #c9946a; --hill-mid: #a8754f; --accent: #8a4b1f; --accent-ink: #fff; }   /* Seed: warm soil, dawn */
html[data-year="8"]:not(.hg-s-look-night)  { --sky-top: #e6f5cf; --sky-mid: #c9eaa8; --sunrise: #a9d888; --dawn: #86c26b;
  --sky-ink: #12300d; --hill-back: #9fd07f; --hill-mid: #7fb963; --accent: #2f7a2a; --accent-ink: #fff; }   /* Shoot: fresh spring green */
html[data-year="9"]:not(.hg-s-look-night)  { --sky-top: #d3e8bf; --sky-mid: #a9cf8e; --sunrise: #7fb26a; --dawn: #5c934f;
  --sky-ink: #0f2a0c; --hill-back: #77a862; --hill-mid: #5a8c4a; --accent: #2b6528; --accent-ink: #fff; }   /* Stalk: deeper green */
html[data-year="10"]:not(.hg-s-look-night) { --sky-top: #eef0c2; --sky-mid: #dfe09a; --sunrise: #c7c66f; --dawn: #a3a84f;
  --sky-ink: #23240a; --hill-back: #bdbb63; --hill-mid: #9c9f48; --accent: #5f6113; --accent-ink: #fff; }   /* Head: green-gold */
html[data-year="11"]:not(.hg-s-look-night) { --sky-top: #fbe7b0; --sky-mid: #f5d283; --sunrise: #e9b65a; --dawn: #c99036;
  --sky-ink: #2e1d04; --hill-back: #deaa4e; --hill-mid: #c18b33; --accent: #8a5a12; --accent-ink: #fff; }   /* Ripening: warm gold */
html[data-year="12"]:not(.hg-s-look-night) { --sky-top: #3d2016; --sky-mid: #5e2f19; --sunrise: #8c4a1f; --dawn: #c07a2c;
  --sky-ink: #fff3e2; --hill-back: #a5612a; --hill-mid: #8a4e22; --accent: #9a5416; --accent-ink: #fff; }   /* Full grain: deep amber, harvest dusk */
/* The header's plain backdrop (no cartoon hills): the field of plants at
   the student's stage stands along its bottom edge. */
.sky { background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 45%, var(--sunrise) 80%, var(--dawn) 100%); }
.field-strip { display: block; width: 100%; height: 150px; }
/* parallax: back row moves least, front row most */
.field-strip .row { transition: transform .35s ease-out; }
.field-strip .row-back  { transform: translate(calc(var(--px, 0) * -6px),  calc(var(--sy, 0) * 4px)); }
.field-strip .row-mid   { transform: translate(calc(var(--px, 0) * -12px), calc(var(--sy, 0) * 8px)); }
.field-strip .row-front { transform: translate(calc(var(--px, 0) * -20px), calc(var(--sy, 0) * 12px)); }
html.rm .field-strip .row { transform: none; transition: none; }
[data-field] { display: block; line-height: 0; }
html.hg-s-contrast-on .field-strip { display: none; }
.m-grain.green { fill: #9bd46a; }
.grow .m-grain.green { animation: m-sprout .35s ease-out both; }
.welcome .me { background: transparent; box-shadow: none; padding: 0; }
html.hg-s-look-night .stage-name { color: var(--ink-soft); }

/* ============================================================
   MOTION (HUB_PLAN.md section 2b). Only transform and opacity move,
   so ordinary school laptops can keep up. <html class="rm"> (reduce
   motion, from the laptop or the "Aa" panel) swaps movement for fades.
   ============================================================ */
@keyframes fade-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-up   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Cards land like scattered seeds: from just above, a soft bounce. */
@keyframes land      { 0% { opacity: 0; transform: translateY(-28px) scale(.96); } 70% { opacity: 1; transform: translateY(3px) scale(1); } 100% { opacity: 1; transform: none; } }
@keyframes drift     { from { transform: translateX(-6vw); } to { transform: translateX(106vw); } }
@keyframes bob       { 0%, 100% { translate: 0 0; } 50% { translate: 0 10px; } }
@keyframes sweep     { from { transform: translateX(-60%); opacity: 0; } 20% { opacity: 1; } to { transform: translateX(160%); opacity: 0; } }
@keyframes rise      { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes open-avatar { from { opacity: 0; transform: scale(.55); } 70% { opacity: 1; transform: scale(1.04); } to { opacity: 1; transform: none; } }

/* ---- the sign-in field: a few faint seeds drifting across ---- */
.sky { isolation: isolate; }
.drift { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 2; }  /* above the field, so seeds rest among the plants */
/* Seeds that drift in and settle into the field (js/signin.js): no
   looping; every seed is at rest within about ten seconds. */
.drift i {
  position: absolute; left: 0; top: 0; width: 7px; height: 7px; border-radius: 50% 50% 50% 0; background: #c98a2e; opacity: 0;
}
html.rm .drift i { opacity: .85; }

/* the seed that falls into the soil when "Sign in" is pressed (js/signin.js) */
.falling-seed { position: fixed; z-index: 50; width: 12px; height: 12px; border-radius: 50% 50% 50% 0; background: #f2a541;
  box-shadow: 0 0 12px rgba(242, 165, 65, .8); pointer-events: none; }

/* ---- light across the field, and the time of day ---- */
.sky-light { position: absolute; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.sky-light .sweep { position: absolute; top: 0; bottom: 0; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent); opacity: 0; }
.sky-light .sweep.go { animation: sweep 1.1s ease-out .55s both; }
html.rm .sky-light .sweep.go { animation: none; }
/* The sky shifts with the school day (from the bell times). A light layer
   over the year's colours, never replacing them; 2 s crossfade. */
.sky-light .daylight { position: absolute; inset: 0; opacity: 0; transition: opacity 2s ease; }
html[data-daypart="morning"]   .sky-light .daylight { opacity: 1; background: linear-gradient(180deg, rgba(255, 196, 150, .30), transparent 60%); }
html[data-daypart="midday"]    .sky-light .daylight { opacity: 1; background: linear-gradient(180deg, rgba(255, 255, 255, .18), transparent 70%); }
html[data-daypart="afternoon"] .sky-light .daylight { opacity: 1; background: linear-gradient(0deg, rgba(255, 170, 60, .32), transparent 65%); }
/* Dusk: the five-minute warning dims the field; signing out darkens it. */
.sky-light .dusk { position: absolute; inset: 0; background: linear-gradient(180deg, #1b1236, #2b1d4a); opacity: 0; transition: opacity 2s ease; }
.sky.dusk-warning .sky-light .dusk { opacity: .32; }
.sky.dusk-out .sky-light .dusk { opacity: .78; transition-duration: .6s; }
html.rm .sky-light .daylight, html.rm .sky-light .dusk { transition: none; }
.sky .wrap, .sky [data-field] { position: relative; z-index: 1; }
.signout-warning.show { animation: fade-up .25s ease-out both; }

/* ---- the welcome: sprout, then avatar, then the words ---- */
.welcome .me { position: relative; }
.welcome .me .sprout { position: absolute; inset: 0; display: grid; place-items: end center; }
.welcome .me .sprout svg { width: 100%; height: 100%; }
.welcome.full .me .avatar { animation: open-avatar .45s cubic-bezier(.34, 1.56, .64, 1) 1s both; }
.welcome.full .me .sprout { animation: fade-in .25s ease reverse 1s both; }
.welcome.full .hello { animation: fade-up .35s ease-out 1.15s both; }
.welcome.quick .me .avatar, .welcome.quick .hello { animation: fade-up .3s ease-out both; }
.welcome.quick .me .sprout { display: none; }
html.rm .welcome.full .me .avatar, html.rm .welcome.full .hello, html.rm .welcome.quick .me .avatar, html.rm .welcome.quick .hello { animation: fade-in .2s ease both; }
html.rm .welcome .me .sprout { display: none; }

/* ---- cards: land, lift, step in ---- */
.card.land { animation: land .42s cubic-bezier(.34, 1.56, .64, 1) calc(var(--i, 0) * 60ms + var(--after, 0ms)) both; }
html.rm .card.land { animation: fade-in .2s ease calc(var(--i, 0) * 40ms) both; }
.card { transition: transform .2s ease, box-shadow .2s ease; }
.card:hover { transform: translateY(-5px); box-shadow: 0 18px 40px rgba(29, 35, 64, .24); }
.card .art { overflow: hidden; display: block; }
.card .art img { transition: transform .2s ease-out; transform: translate(var(--px, 0), var(--py, 0)) scale(1.06); }
html.rm .card:hover { transform: none; }
html.rm .card .art img { transform: none; transition: none; }
/* Stepping into a world: the card's picture fills the screen (a view
   transition where the browser has one), then the app opens. */
.world-open { position: fixed; inset: 0; z-index: 60; display: grid; grid-template-rows: 1fr auto; background: var(--paper); }
.world-open img { width: 100%; height: 100%; object-fit: cover; view-transition-name: world-art; }
.world-open .bar { padding: 18px 24px; display: flex; gap: 14px; align-items: center; justify-content: space-between; flex-wrap: wrap; background: var(--card); }
.world-open .bar h2 { margin: 0; }
::view-transition-group(world-art) { animation-duration: .38s; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }

/* ---- growth on each card: blade, head, grain ---- */
.growth { display: inline-flex; align-items: center; gap: 6px; font-size: .88rem; font-weight: 700; color: var(--ink-soft); }
.growth svg { width: 26px; height: 26px; }
.growth .g-blade { transform-box: fill-box; transform-origin: 50% 100%; }
.growth.grew .g-new { animation: rise .5s cubic-bezier(.34, 1.56, .64, 1) .9s both; transform-box: fill-box; transform-origin: 50% 100%; }
html.rm .growth.grew .g-new { animation: fade-in .2s ease .5s both; }

/* ---- teacher view: grow, count, fade ---- */
.fade-in-seq > * { animation: fade-up .25s ease-out calc(var(--i, 0) * 60ms) both; }
html.rm .fade-in-seq > * { animation: fade-in .2s ease both; }
.chart .bar { transform-box: fill-box; transform-origin: 50% 100%; animation: rise .4s cubic-bezier(.2, .8, .2, 1) calc(var(--i, 0) * 50ms) both; }
html.rm .chart .bar { animation: fade-in .2s ease both; }
.bars .fill { transform-origin: 0 50%; animation: grow-x .5s cubic-bezier(.2, .8, .2, 1) .2s both; }
@keyframes grow-x { from { transform: scaleX(0); } to { transform: none; } }
html.rm .bars .fill { animation: none; }
.welcome .me .avatar, .welcome .me .avatar svg { display: block; width: 100%; height: 100%; }
.growth-card { display: flex; gap: 14px; align-items: center; margin: 0 0 14px; }
.growth-card svg { width: 64px; height: 64px; transform-origin: 50% 100%; animation: rise .5s cubic-bezier(.34, 1.56, .64, 1) .2s both; }
html.rm .growth-card svg { animation: fade-in .2s ease both; }

/* "Tell my teacher": the same calm colour in every year look, never red. */
.btn.calm { background: var(--calm); color: var(--calm-ink); border-color: transparent; }
/* "I'm stuck" while the hand is up: outlined, so it reads as switched on. */
.btn.calm.is-up { outline: 3px solid var(--calm-ink); outline-offset: 2px; }
/* Help and Tell my teacher never float over content: they live in the
   top bar, and in this row under the cards. */
.need-hand { display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap;
  margin: 8px 0 48px; padding: 18px 20px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); }
.need-hand p { margin: 0; color: var(--ink-soft); max-width: 60ch; }
.need-hand strong { color: var(--ink); }
.helpers { display: none; }

/* The header's right half: the student's own plant at their stage, on a
   small hill in the year's colours, with a soft glow behind it. */
.welcome { position: relative; }
.hero-plant { margin-left: auto; width: 280px; height: 230px; position: relative; flex: none; }
.hero-plant svg { position: absolute; inset: 0; width: 100%; height: 100%; }
@media (max-width: 860px) { .hero-plant { display: none; } }

/* ============================================================
   THE YEAR COLOUR BELOW THE HEADER: small touches only.
   Colour lives in the header; content sits on cream, so text stays
   easy to read and each app's artwork stands out. Below the header
   the year shows only in: the fade from the field, focus rings, the
   growth icons, progress bars, the card hover glow, and small labels.
   ============================================================ */
:root { --ground: color-mix(in srgb, var(--hill-mid) 16%, var(--paper)); }
html[data-year]:not(.hc) { --focus: var(--accent); }
.year-fade { height: 56px; margin-bottom: -56px; position: relative; z-index: 0; pointer-events: none;
  background: linear-gradient(180deg, var(--ground), var(--paper)); }
html.hg-s-contrast-on .year-fade { display: none; }
.cards-head h2 { color: var(--accent); }
.card:hover { box-shadow: 0 18px 40px rgba(29, 35, 64, .18), 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
html.rm .card:hover { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
.growth { background: color-mix(in srgb, var(--accent) 12%, var(--card)); color: var(--accent); padding: 2px 10px 2px 4px; border-radius: 10px; }
.bars .fill, .bar .fill { background: var(--accent) !important; }
html.hg-s-look-night .growth { background: #22314d; color: var(--ink-soft); }
/* the page content always sits above the fade */
main.wrap { position: relative; z-index: 1; }

/* ---- choosing an avatar (first sign-in): twelve elements, eight colours ---- */
.av-pick { display: grid; grid-template-columns: 140px 1fr; gap: 16px; align-items: start; }
.av-preview #preview { width: 120px; height: 120px; }
.av-preview #preview svg { width: 100%; height: 100%; }
.av-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.av-grid button { aspect-ratio: 1; padding: 6px; border-radius: 12px; border: 2px solid var(--line); background: #fff; cursor: pointer; }
.av-grid button svg { width: 100%; height: 100%; display: block; }
.av-grid button[aria-pressed="true"], .av-swatches button[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }
.av-swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.av-swatches button { width: 30px; height: 30px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 0 0 1px var(--line); cursor: pointer; }
@media (max-width: 520px) { .av-pick { grid-template-columns: 1fr; } .av-grid { grid-template-columns: repeat(4, 1fr); } }
/* Avatars in a coloured header sit on a soft light disc, so any colour stands out. */
/* The disc is the card colour, so the avatar contrast checked against the
   card (tools/check_contrast.mjs) is the contrast students see. */
.av-disc { border-radius: 50%; background: radial-gradient(circle, var(--disc, rgba(255, 255, 255, .85)) 0 60%, transparent 72%); }
html[data-year="12"]:not(.hg-s-look-night) { --disc: #fffaf0; }
html.hg-s-look-night { --disc: var(--card); }

/* ============================================================
   AVATAR COLOURS BY YEAR. A student chooses one of eight colours; the
   shade drawn suits their year's look. Every shade reaches 3 to 1
   against the light disc and cards it sits on (WCAG non-text contrast;
   tools/check_contrast.mjs tests every look).
   ============================================================ */
.av-c-teal { color: var(--av-teal); }   .av-c-sky { color: var(--av-sky); }
.av-c-gold { color: var(--av-gold); }   .av-c-coral { color: var(--av-coral); }
.av-c-plum { color: var(--av-plum); }   .av-c-moss { color: var(--av-moss); }
.av-c-slate { color: var(--av-slate); } .av-c-earth { color: var(--av-earth); }
.av-swatches button[class^="av-c-"] { background: currentColor; }
/* Base (sign-in, teacher view): clear, even shades. */
:root { --av-teal: #16857d; --av-sky: #2f73b8; --av-gold: #9a6f12; --av-coral: #c2492f;
        --av-plum: #7c3fae; --av-moss: #4f7a22; --av-slate: #4d5b75; --av-earth: #835631; }
/* Year 7 Seed: earthy, dawn-warm. */
html[data-year="7"]:not(.hg-s-look-night)  { --av-teal: #2c7a72; --av-sky: #3f6e9c; --av-gold: #9a6a14; --av-coral: #b8502f;
  --av-plum: #8a4a76; --av-moss: #5a7428; --av-slate: #5a5f6e; --av-earth: #8a5532; }
/* Year 8 Shoot: fresh, blossom-bright. */
html[data-year="8"]:not(.hg-s-look-night)  { --av-teal: #12807a; --av-sky: #2a72b5; --av-gold: #977112; --av-coral: #c8454f;
  --av-plum: #8a44a8; --av-moss: #3a7a2a; --av-slate: #4a6478; --av-earth: #7a5634; }
/* Year 9 Stalk: deeper, forest tones. */
html[data-year="9"]:not(.hg-s-look-night)  { --av-teal: #13716a; --av-sky: #276596; --av-gold: #8c6a12; --av-coral: #b0443a;
  --av-plum: #743c86; --av-moss: #2f6a2a; --av-slate: #44576a; --av-earth: #6d4d2e; }
/* Year 10 Head: olive and mustard. */
html[data-year="10"]:not(.hg-s-look-night) { --av-teal: #1b7266; --av-sky: #356a88; --av-gold: #846f0e; --av-coral: #ab5229;
  --av-plum: #744672; --av-moss: #556c1a; --av-slate: #4e5d55; --av-earth: #765627; }
/* Year 11 Ripening: honey, rust and amber. */
html[data-year="11"]:not(.hg-s-look-night) { --av-teal: #196a64; --av-sky: #335f88; --av-gold: #93600f; --av-coral: #a84228;
  --av-plum: #7a385b; --av-moss: #4d6620; --av-slate: #4d5265; --av-earth: #744622; }
/* Year 12 Full grain: bronze, burgundy and dusk. */
html[data-year="12"]:not(.hg-s-look-night) { --av-teal: #217a71; --av-sky: #3a6c9a; --av-gold: #93680f; --av-coral: #ad4630;
  --av-plum: #7d3660; --av-moss: #5a6c22; --av-slate: #5a5e70; --av-earth: #84562f; }
/* Night: lighter shades, so avatars show on dark cards. */
html.hg-s-look-night { --av-teal: #5fd3c7; --av-sky: #7fb6ee; --av-gold: #f0c35a; --av-coral: #ff8f7a;
  --av-plum: #c79bf0; --av-moss: #a6d36a; --av-slate: #b3bfd6; --av-earth: #d9a476; }
/* High contrast: one strong colour. */
html.hg-s-contrast-on { --av-teal: #000; --av-sky: #000; --av-gold: #000; --av-coral: #000; --av-plum: #000; --av-moss: #000; --av-slate: #000; --av-earth: #000; }

/* ---- phones: a compact top bar (the name on one row, the buttons on the next) ---- */
@media (max-width: 600px) {
  .topbar { gap: 8px; }
  .topbar .spacer { flex-basis: 100%; height: 0; }
  .topbar .btn { min-height: 40px; padding: 6px 12px; font-size: .9rem; }
  .brand { font-size: 1.3rem; }
  .wc-season { font-size: .85rem; padding: 4px 10px; }
}
/* Small dark details on some avatars (an eye, a head, a body) turn light in
   Night, so they still show against its dark disc. */
:root { --av-detail: #1d2340; }
html.hg-s-look-night { --av-detail: #e8edf6; }
.av-detail { fill: var(--av-detail); }
.av-detail-line { stroke: var(--av-detail); fill: none; }

/* ---- the real pages: a few things the mockups did inline ---- */
.actions-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; align-items: center; }
.footnote { text-align: center; padding: 10px 16px 40px; }
.subject { margin: 22px 0 10px; font-size: 1.15rem; color: var(--accent); }
.need-hand-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
.moveup-mark { width: 140px; height: 140px; margin: 0 auto; }
.moveup-mark svg { width: 100%; height: 100%; }
.verse cite { font-style: normal; }
dialog .verse { color: var(--ink-soft); }

/* ---- parents.html: one plain page for parents and carers ---- */
.parents { max-width: 760px; padding-top: 24px; padding-bottom: 48px; }
.parents h2 { margin-top: 28px; }
.parents li { margin: 6px 0; }
.parents-head { background: #24543d; color: #fff; padding: 16px 0 24px; }
.parents-head h1, .parents-head .lead, .parents-head .brand { color: #fff; }

/* ---------- The living field (Luke, 6 October 2026) ----------
   The plants sway in a breeze, a gust running left to right (js/mark.js
   gives each plant its delay), and two bees drift over the field
   (js/ambient.js). Still when Aa "No movement" or "Fewer distractions" is
   on, or the device asks for reduced motion (html.rm); paused while the
   student types and while the tab is hidden. */
.field-strip .sway {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: field-sway 6s ease-in-out infinite;
}
@keyframes field-sway {
  0%, 100% { transform: rotate(0deg); }
  30%      { transform: rotate(4deg); }
  55%      { transform: rotate(-1.5deg); }
  75%      { transform: rotate(2deg); }
}
.amb-bees { position: absolute; left: 0; right: 0; bottom: 20px; height: 110px; pointer-events: none; overflow: hidden; z-index: 1; }
.amb-bee { position: absolute; left: 0; top: 40px; width: 16px; height: 12px; animation: bee-cross 38s linear infinite; }
.amb-bee.b2 { top: 70px; animation-duration: 52s; animation-delay: -21s; }
.amb-bee svg { display: block; animation: bee-bob 0.9s ease-in-out infinite alternate; }
.amb-bee .wing { animation: bee-wing 0.12s linear infinite alternate; transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes bee-cross {
  0%   { transform: translate(-30px, 0); }
  25%  { transform: translate(25vw, -26px); }
  50%  { transform: translate(52vw, 8px); }
  75%  { transform: translate(78vw, -18px); }
  100% { transform: translate(calc(100vw + 30px), 4px); }
}
@keyframes bee-bob  { from { transform: translateY(-3px); } to { transform: translateY(3px); } }
@keyframes bee-wing { from { transform: scaleY(1); } to { transform: scaleY(0.35); } }
html.hg-s-calm-on .field-strip .sway, html.rm .field-strip .sway { animation: none; }
html.hg-s-calm-on .amb-bees, html.rm .amb-bees { display: none; }
html.amb-paused .field-strip .sway, html.amb-paused .amb-bees * { animation-play-state: paused; }

/* "Where you left off" (js/left-off.js): one card above "Your worlds". */
.left-off { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px;
  margin: 18px 0 4px; padding: 14px 16px; border-radius: var(--radius, 18px); background: var(--card, #fff);
  border: 2px solid var(--accent, #2d6a4f); }
.left-off h2 { margin: 0 0 2px; font-size: 1.05rem; }
.left-off p { margin: 0; }

/* A card dips a little when pressed (content/effects.js, "press"). Not under reduced motion or Reduce motion. */
@media (prefers-reduced-motion: no-preference) {
  html.fx-press:not(.hg-s-calm-on) .card { transition: transform .08s ease-out; }
  html.fx-press:not(.hg-s-calm-on) .card:active { transform: scale(.98); }
}

/* A short ease-out settle (content/effects.js, "settle"), and the home sky's very slow drift ("sky").
   transform and opacity only. Both stop under reduced motion and Reduce motion. */
@keyframes fx-settle { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fx-drift  { from { transform: translateX(-12%); } to { transform: translateX(12%); } }
@media (prefers-reduced-motion: no-preference) {
  html.fx-sky:not(.hg-s-calm-on) .sky-light::after {
    content: ""; position: absolute; top: -20%; bottom: -20%; left: -20%; width: 140%; pointer-events: none;
    background: radial-gradient(ellipse 40% 60% at 50% 40%, rgba(255, 255, 255, .20), transparent 70%);
    animation: fx-drift 90s ease-in-out infinite alternate; will-change: transform;
  }
}

/* "Talk to my teacher": five answers, big enough to tap, no typing. */
.talk-needs { border: 0; padding: 0; margin: 10px 0; display: grid; gap: 8px; }
.talk-needs legend { font-weight: 700; margin-bottom: 6px; }
.talk-need { display: flex; gap: 10px; align-items: center; min-height: 48px; padding: 8px 12px; border: 2px solid var(--line); border-radius: 12px; background: #fff; cursor: pointer; }
.talk-need input { width: 22px; height: 22px; min-height: 0; flex: none; margin: 0; }
.talk-need:has(input:checked) { border-color: #2f6db3; background: #eaf2fb; }
html.hg-s-look-night .talk-need { background: var(--card); }

/* A teacher's preview of an extra: a plain strip along the bottom of that tab, so nobody forgets it is a preview. */
.preview-banner { position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; display: flex; gap: 12px; align-items: center; justify-content: center;
  flex-wrap: wrap; padding: 10px 16px; background: var(--warn-bg); color: var(--warn-ink); border-top: 2px solid var(--warn-ink); font-weight: 600; }

/* Avatars are a little 3D (js/elements.js): the lighting filter is switched off with "No movement" / Fewer distractions, for a plainer picture. */
html.hg-s-calm-on .av-3d { filter: none; }

/* ---------- spin your avatar (js/spin.js) ---------- */
.wc-avatar.sp-ready { cursor: pointer; }
.wc-avatar.sp-ready:focus-visible { outline: 3px solid var(--accent, #2d6a4f); outline-offset: 4px; }
.wc-avatar.sp-ready::after { content: "Spin"; position: absolute; right: -6px; bottom: 2px; background: var(--card, #fff); color: var(--ink, #1d2340); border: 2px solid var(--line, #ddd); border-radius: 999px; padding: 1px 9px; font-size: .78rem; font-weight: 800; box-shadow: 0 2px 6px rgba(0, 0, 0, .18); pointer-events: none; }
.sp-stage { width: 220px; height: 220px; margin: 8px auto 6px; perspective: 700px; touch-action: pan-y; cursor: grab; border-radius: 50%; background: radial-gradient(circle, rgba(255, 255, 255, .9) 0 58%, transparent 72%); }
.sp-stage.sp-grab { cursor: grabbing; }
.sp-obj { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; }
.sp-l { position: absolute; inset: 0; pointer-events: none; }
.sp-l svg { width: 100%; height: 100%; display: block; overflow: visible; }
.sp-buttons { display: flex; gap: 8px; justify-content: center; margin-top: 8px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* ---- The Daily's main card: wide, bright, one big button. Same card inside, so it opens signed in like every other app. */
.card.hero-daily { grid-column: 1 / -1; flex-direction: row; margin-bottom: 22px; border: 3px solid var(--ink, #14121a); box-shadow: 6px 6px 0 var(--ink, #14121a); background: var(--card); }
.card.hero-daily .art { flex: 0 0 42%; display: block; }
.card.hero-daily .art { background: #d9f3ee; display: flex; align-items: center; }
.card.hero-daily .art img { height: auto; aspect-ratio: 400 / 240; object-fit: contain; }
.card.hero-daily .body { justify-content: center; gap: 10px; padding: 22px 26px; }
.card.hero-daily h3 { font-size: 2.1rem; line-height: 1.05; }
.card.hero-daily .hero-line { font-size: 1.2rem; font-weight: 700; color: var(--ink); }
.card.hero-daily .hero-flag { align-self: flex-start; background: #ffd23f; color: #14121a; font-weight: 800; font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; padding: 4px 10px; border-radius: 999px; border: 2px solid #14121a; }
.card.hero-daily .hero-btn { align-self: flex-start; font-size: 1.15rem; padding: 12px 22px; margin-top: 6px; }
.card.hero-daily .hero-btn:hover { transform: translateY(-2px); }
@media (max-width: 760px) { .card.hero-daily { flex-direction: column; } .card.hero-daily .art { flex-basis: auto; } .card.hero-daily .art img { min-height: 0; aspect-ratio: 400 / 220; } .card.hero-daily h3 { font-size: 1.7rem; } }
@media (prefers-reduced-motion: reduce) { .card.hero-daily .hero-btn:hover { transform: none; } }
