/* ⚠ Tokens live in system.css, which must load FIRST. Every size, space and
 * radius below is a token: 22 ad-hoc font sizes and 22 spacing values were
 * snapped onto a seven-step scale and an eight-step spacing unit on
 * 8 Oct 2026. A new raw value here is a bug, not a style choice. */
/* Mobile-first. A parent checks this standing in a kitchen, one-handed. */
/* ----------------------------------------------------------------------------
 * ParentChill palette.
 *
 * Deliberately NOT school blue. ParentPay, Arbor, Satchel and SIMS are all
 * blue, and a parent app that looks like one more school system is a parent app
 * that feels like homework. Green reads as "done, nothing owing", which is the
 * thing the product is actually selling.
 *
 * Backgrounds are warm rather than cold grey, so it reads as the parent's own
 * app rather than an institutional one.
 *
 * Everything is a token. The urgency tints used to be hardcoded blues, so
 * changing the brand meant changing them too, and tokenising made the dark
 * theme almost free.
 * -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  --ink:    #1b2420;
  --ink-2:  #4d5852;
  --ink-3:  #6b736d;            /* 4.9:1 on white, so small print stays readable */
  --line:   #e7e2da;
  --bg:     #faf8f5;
  --card:   #ffffff;

  --brand:          #1c7a5b;    /* white on this is 5.3:1 */
  --brand-ink:      #125b43;    /* green text on a light tint */
  --brand-soft:     #e6f2ec;
  --brand-line:     #c3ddd1;
  --on-brand:       #ffffff;
  --on-light-brand: #125b43;    /* never flips: for surfaces that stay white */

  --overdue:      #b3261e;
  --overdue-bg:   #fceceb;
  --overdue-line: #f2c7c4;
  --week:         #8a4f12;
  --week-bg:      #fdf2e3;
  --week-line:    #ecd4ab;
  --soon:         #1c7a5b;
  --soon-bg:      #e6f2ec;
  --later:        #5a6560;
  --later-bg:     #f1efea;

  --note-bg:   #fff9e8;
  --note-line: #efe0b5;
  --note-ink:  #6a5412;
  --ok-bg:     #e6f3ea;
  --ok-ink:    #1b6b3f;

  --radius: 14px;
  --shadow: 0 1px 2px rgba(27,36,32,.05), 0 6px 16px rgba(27,36,32,.05);
}

/*
 * Evenings exist, and this is a phone app a parent opens at 10pm. The tokens do
 * all the work, so nothing below this point has to know which theme is running.
 * --brand itself does NOT flip: white on it already passes on either backdrop.
 * --brand-ink does, because the tint it sits on flips with it.
 */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --ink:   #e8eae7;
    --ink-2: #aab3ad;
    --ink-3: #8d958f;
    --line:  #2d3337;
    --bg:    #14181a;
    --card:  #1c2124;

    --brand-ink:  #7fd6ae;
    --brand-soft: #16302a;
    --brand-line: #27493f;

    --overdue:      #ff9c92;
    --overdue-bg:   #341a18;
    --overdue-line: #4e2522;
    --week:         #f0b571;
    --week-bg:      #33240f;
    --week-line:    #4a3618;
    --soon:         #7fd6ae;
    --soon-bg:      #16302a;
    --later:        #a3aba6;
    --later-bg:     #23282a;

    --note-bg:   #2b2714;
    --note-line: #463f21;
    --note-ink:  #e8d49a;
    --ok-bg:     #16302a;
    --ok-ink:    #7fd6ae;

    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 6px 16px rgba(0,0,0,.25);
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* Links.
   There was no rule for these at all, so they rendered in the browser's own blue
   next to an otherwise entirely green palette. Brand colour, and underlined only
   on hover, except inside running prose where the underline is what tells you it
   is a link at all. */
a {
  color: var(--brand-ink);
  text-decoration-color: var(--brand-line);
  text-underline-offset: 2px;
}
a:hover { text-decoration-color: currentColor; }
a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--r-sm); }

body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
        "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-size-adjust: 100%;
}
.wrap { max-width: 720px; margin: 0 auto; padding: 0 var(--s-4); }

.topbar { background: var(--card); border-bottom: 1px solid var(--line); }
.topbar .wrap { padding-top: var(--s-3); padding-bottom: var(--s-3); }
.brand { display: flex; gap: var(--s-3); align-items: center; }
.mark { width: 34px; height: 34px; flex: 0 0 34px; display: block; }
h1 { font-size: var(--t-base); margin: 0; letter-spacing: -0.01em; }
.sub { margin: 1px 0 0; font-size: var(--t-xs); color: var(--ink-3); }

.childbar { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-3); }
.chip {
  border: 1px solid var(--line); background: var(--card); color: var(--ink-2);
  padding: var(--s-2) var(--s-3); border-radius: var(--r-full); font-size: var(--t-sm); cursor: pointer;
  font-weight: 500; min-height: 36px;
}
.chip.is-active { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.chip.add { border-style: dashed; color: var(--ink-3); }

/*
 * Seven tabs do not fit a phone. They used to scroll sideways with no scrollbar
 * and no fade, so Connect and Coverage were simply invisible to anyone who did
 * not think to swipe a row that gave no sign it could move. On a narrow screen
 * they wrap onto two rows instead: nothing hidden, nothing to discover.
 */
.tabs {
  display: flex; gap: 2px; margin-top: var(--s-3);
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

@media (max-width: 560px) {
  .tabs { flex-wrap: wrap; overflow-x: visible; gap: 0 var(--s-1); }
  .tab { padding: var(--s-2) var(--s-2); }
}
.tab {
  border: 0; background: none; padding: var(--s-2) var(--s-3); font-size: var(--t-sm); font-weight: 600;
  color: var(--ink-3); cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap;
}
.tab.is-active { color: var(--brand-ink); border-bottom-color: var(--brand); }

main { padding-bottom: var(--s-6); padding-top: var(--s-1); }
.loading { color: var(--ink-3); padding: var(--s-5) 0; }

/* Required on a UK limited company's website: registered number, registered
   office, where registered, and that it is limited. Quiet, but present. */
.legal { font-size: var(--t-xs); color: var(--ink-3); margin: var(--s-2) 0 0; }

.group { margin-top: var(--s-5); }
.group > h2 {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); margin: 0 0 var(--s-2); font-weight: 700;
}
.count { color: var(--ink-3); font-weight: 600; }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s-3); margin-bottom: var(--s-2); box-shadow: var(--shadow);
}
.card.overdue { border-left: 3px solid var(--overdue); }
.card.this-week { border-left: 3px solid var(--week); }

.when {
  display: inline-block; font-size: var(--t-xs); font-weight: 700; padding: var(--s-1) var(--s-2);
  border-radius: var(--r-sm); margin-bottom: var(--s-2); letter-spacing: .01em;
}
.when.overdue { background: var(--overdue-bg); color: var(--overdue); }
.when.this-week { background: var(--week-bg); color: var(--week); }
.when.soon { background: var(--soon-bg); color: var(--soon); }
.when.later { background: var(--later-bg); color: var(--later); }

.card h3 { margin: 0 0 var(--s-1); font-size: var(--t-base); line-height: 1.35; }
.card .do { margin: 0; color: var(--ink-2); font-size: var(--t-sm); }
.card .meta { margin: var(--s-2) 0 0; font-size: var(--t-xs); color: var(--ink-3); }
.years { font-size: var(--t-xs); color: var(--ink-3); font-weight: 600; }

.actions { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-3); }
.btn {
  display: inline-flex; align-items: center; gap: var(--s-2); text-decoration: none;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  padding: var(--s-2) var(--s-3); border-radius: var(--r-sm); font-size: var(--t-sm); font-weight: 600;
  cursor: pointer; min-height: 40px;
}
.btn-primary { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.btn-quiet { background: var(--card); color: var(--ink-2); }
.btn:active { transform: translateY(1px); }

/* Honesty notice. Deliberately visible: this product must never imply certainty
   it does not have. */
.caveat {
  margin: var(--s-2) 0 0; padding: var(--s-2) var(--s-2); background: var(--note-bg); border: 1px solid var(--note-line);
  border-radius: var(--r-sm); font-size: var(--t-xs); color: var(--note-ink);
}
.caveat strong { font-weight: 700; }

.note {
  background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--brand-ink);
  padding: var(--s-3) var(--s-3); border-radius: var(--radius); font-size: var(--t-sm); margin: var(--s-4) 0;
}
.note h2 { margin: 0 0 var(--s-1); font-size: var(--t-sm); }
.note ul { margin: var(--s-1) 0 0; padding-left: var(--s-4); }
.note li { margin: var(--s-1) 0; }

.empty { color: var(--ink-3); padding: var(--s-5) var(--s-1); text-align: center; }

.app { display: flex; gap: var(--s-3); align-items: flex-start; }
.app .body { flex: 1 1 auto; min-width: 0; }
.app h3 { margin: 0 0 2px; }
.badge {
  font-size: var(--t-xs); font-weight: 700; padding: 2px var(--s-2); border-radius: var(--r-sm);
  text-transform: uppercase; letter-spacing: .04em; white-space: nowrap;
}
.badge.confirmed { background: var(--ok-bg); color: var(--ok-ink); }
.badge.reported { background: var(--week-bg); color: var(--week); }
.badge.inferred { background: var(--later-bg); color: var(--later); }

.day { display: flex; gap: var(--s-3); padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.day:last-child { border-bottom: 0; }
.day .date { flex: 0 0 76px; font-size: var(--t-xs); font-weight: 700; color: var(--ink-2); }
.day .what { flex: 1 1 auto; min-width: 0; }
.day .what p { margin: 0; font-size: var(--t-sm); }
.day .what small { color: var(--ink-3); font-size: var(--t-xs); }

dialog {
  border: 0; border-radius: var(--r-md); padding: var(--s-4); max-width: 360px; width: calc(100% - 32px);
  box-shadow: 0 10px 40px rgba(22,32,43,.22);
}
dialog::backdrop { background: rgba(22,32,43,.45); }
dialog h2 { margin: 0 0 var(--s-3); font-size: var(--t-base); }
dialog label { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--ink-2); margin-bottom: var(--s-3); }
dialog input, dialog select {
  width: 100%; margin-top: var(--s-1); padding: var(--s-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); font-size: var(--t-base); font-family: inherit;
}
dialog .hint { font-size: var(--t-xs); color: var(--ink-3); margin: 0 0 var(--s-3); }
dialog menu { display: flex; gap: var(--s-2); justify-content: flex-end; margin: 0; padding: 0; }

.foot { color: var(--ink-3); font-size: var(--t-xs); border-top: 1px solid var(--line); padding-top: var(--s-3); margin-top: var(--s-2); }
.foot p { margin: 0 0 var(--s-4); }

@media (min-width: 600px) {
  h1 { font-size: var(--t-lg); }
  .card { padding: var(--s-4); }
}

/* --- Month calendar --------------------------------------------------- */
.cal { margin-top: var(--s-4); }
.cal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--s-2);
}
.cal-head h2 { margin: 0; font-size: var(--t-base); font-weight: 700; }
.cal-nav {
  border: 1px solid var(--line); background: var(--card); color: var(--ink-2);
  width: 40px; height: 40px; border-radius: var(--r-sm); font-size: var(--t-lg); line-height: 1;
  cursor: pointer;
}
.cal-nav:active { background: var(--bg); }

.cal-days {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--s-1);
  margin-bottom: var(--s-1);
}
.cal-days span {
  text-align: center; font-size: var(--t-xs); font-weight: 700; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .04em;
}

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--s-1); }
.cal-cell {
  position: relative; aspect-ratio: 1 / 1; border: 1px solid var(--line);
  background: var(--card); border-radius: var(--r-sm); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--s-1); padding: 0; font: inherit; color: var(--ink);
  /* A phone tap target must not be smaller than this. */
  min-height: 42px;
}
.cal-cell.is-empty { border: 0; background: none; cursor: default; }
.cal-cell.has-items { background: var(--card); border-color: var(--brand-line); }
.cal-cell.is-today { border-color: var(--brand); border-width: 2px; }
.cal-cell.is-selected { background: var(--brand); border-color: var(--brand); }
.cal-cell.is-selected .cal-num { color: var(--on-brand); }
.cal-cell.is-selected .cal-dot { background: var(--on-brand); }
.cal-num { font-size: var(--t-sm); font-weight: 600; }
.cal-cell.is-today .cal-num { color: var(--brand-ink); font-weight: 800; }

.cal-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--soon);
  display: inline-block;
}
.cal-dot.is-action { background: var(--week); }

.cal-key {
  display: flex; gap: var(--s-4); justify-content: center; margin-top: var(--s-3);
  font-size: var(--t-xs); color: var(--ink-3);
}
.cal-key span { display: inline-flex; align-items: center; gap: var(--s-1); }
.cal-key i { width: 6px; height: 6px; border-radius: 50%; display: inline-block; background: var(--soon); }
.cal-key i.is-action { background: var(--week); }

/* --- App picker & accounts -------------------------------------------- */
.warn {
  background: var(--week-bg); border: 1px solid var(--week-line); color: var(--week);
  padding: var(--s-3) var(--s-3); border-radius: var(--radius); margin: var(--s-4) 0; font-size: var(--t-sm);
}
.warn h3 { margin: 0 0 var(--s-1); font-size: var(--t-sm); }
.warn p { margin: 0 0 var(--s-1); }
.warn p:last-child { margin-bottom: 0; }

.search {
  width: 100%; padding: var(--s-3) var(--s-3); border: 1px solid var(--line);
  border-radius: var(--r-sm); font-size: var(--t-base); font-family: inherit; background: var(--card);
  margin-bottom: var(--s-3); -webkit-appearance: none;
}
.search:focus { outline: 2px solid var(--brand); outline-offset: -1px; border-color: var(--brand); }

.card-flush { padding: 0; overflow: hidden; }

.pick-head {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 700; margin: var(--s-4) 0 var(--s-1);
}

/* A whole row is the tap target. Small buttons on a phone get missed. */
.pick {
  display: flex; align-items: center; gap: var(--s-3); width: 100%;
  padding: var(--s-3); border: 0; border-bottom: 1px solid var(--line);
  background: var(--card); text-align: left; font: inherit; color: var(--ink);
  cursor: pointer; min-height: 60px;
}
.pick:last-child { border-bottom: 0; }
.pick:active { background: var(--bg); }
.pick.is-saved { cursor: default; }
.pick-body { flex: 1 1 auto; min-width: 0; }
.pick-name { margin: 0 0 2px; font-weight: 600; font-size: var(--t-base); }
.pick-body small {
  color: var(--ink-3); font-size: var(--t-xs); display: block;
  /* Wrap, do not clamp to one line.
     This was "white-space: nowrap" with an ellipsis, which on a 375px phone cut
     every description mid-word: "Short revision videos mapped to the ex...".
     The longest description in the whole catalogue is 69 characters, so there
     was never anything to truncate: two lines holds all of them. The clamp is
     kept only as a backstop if a future entry runs long. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.pick-actions { display: flex; gap: var(--s-2); flex: 0 0 auto; }
.pick-add {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  background: var(--soon-bg); color: var(--brand-ink); font-size: var(--t-lg); font-weight: 600;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.btn-sm { padding: var(--s-1) var(--s-3); font-size: var(--t-xs); min-height: 34px; }

dialog .hint#credentialFor { font-weight: 600; color: var(--ink-2); margin-bottom: var(--s-3); }

/* Form fields inside a card, not just inside a dialog. */
.card label {
  display: block; font-size: var(--t-xs); font-weight: 600;
  color: var(--ink-2); margin-bottom: var(--s-3);
}
.card label input, .card label select {
  display: block; width: 100%; margin-top: var(--s-1); padding: var(--s-3);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: var(--t-base); font-family: inherit; -webkit-appearance: none;
}
.card label input:focus {
  outline: 2px solid var(--brand); outline-offset: -1px; border-color: var(--brand);
}

/* The hidden attribute must win.
   `display: block` on a label beats the browser's default [hidden] rule, so
   fields meant to be hidden were showing. This is the fix, and it has to stay
   after the rules that set display. */
[hidden] { display: none !important; }


/* --- sign in / first run ----------------------------------------------- */
.auth { padding: var(--s-5) 0 var(--s-6); }
.auth h2 { font-size: var(--t-xl); letter-spacing: -0.02em; margin: 0 0 var(--s-2); font-weight: 800; }
.auth-lede { color: var(--ink-2); margin: 0 0 var(--s-4); line-height: 1.55; max-width: 34em; }
.auth .card { margin-bottom: 0; }
.auth-switch { margin: var(--s-4) 0 0; font-size: var(--t-sm); color: var(--ink-2); }
.linkish {
  background: none; border: 0; padding: 0; font: inherit; color: var(--brand);
  font-weight: 600; text-decoration: underline; cursor: pointer;
}
.authError {
  background: var(--overdue-bg); border: 1px solid var(--overdue-line); color: var(--overdue);
  padding: var(--s-3) var(--s-3); border-radius: var(--r-sm); font-size: var(--t-sm); margin: 0 0 var(--s-4);
}

/* --- mailbox setup ------------------------------------------------------ */
.copyrow {
  display: flex; gap: var(--s-2); align-items: stretch;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--s-2);
}
.copyrow code {
  flex: 1 1 auto; min-width: 0; font-size: var(--t-xs); line-height: 1.45;
  word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--ink);
}
.copyrow .btn { flex: 0 0 auto; align-self: flex-start; }
.senders { margin: var(--s-2) 0 0; padding-left: var(--s-4); color: var(--ink-2); font-size: var(--t-sm); }
.senders li { margin: var(--s-1) 0; }
.senders strong { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--t-sm); }
.steps-list { margin: var(--s-3) 0 0; padding-left: var(--s-4); color: var(--ink-2); }

/* The forwarding address is one long unbroken word, and step 5 tells the parent
   to type it. On a phone it ran off the right edge and was cut mid-address:
   "...@parentchill.co.u". They cannot type what they cannot see. */
.steps-list li { overflow-wrap: anywhere; }

.steps-list li { margin: var(--s-2) 0; line-height: 1.5; }
/* Wraps, because it has to.
   This was a non-wrapping flex row. With two choices it was fine; with five it
   pushed the last one off the right edge of a phone with nothing to show it was
   there, which is the same fault the tab row below already had fixed. Whatever
   is in this row must be visible without swiping. */
.tabrow { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-3); }

/* Sender lists and filters copy as written. Without this the newlines collapse
   and Outlook receives one long run of domains it cannot parse. */
.copyrow code { white-space: pre-line; }

/* The Set up menu.
   Three daily tabs stay on the row; the one-off screens fold away behind this.
   A <details> rather than a scripted dropdown, so it opens with no JavaScript
   and closes on Escape for free. */
.setup { position: relative; display: inline-block; }
.setup > summary { list-style: none; cursor: pointer; }
.setup > summary::-webkit-details-marker { display: none; }
.setup > summary::after { content: " \25be"; font-size: var(--t-xs); }
.setup[open] > summary { color: var(--ink); border-bottom-color: var(--brand); }
.setup-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 20;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: 0 8px 24px rgb(0 0 0 / .10); padding: var(--s-1); min-width: 232px;
}
.setup-menu .tab {
  display: block; width: 100%; text-align: left; border-bottom: 0;
  padding: var(--s-2) var(--s-3); border-radius: var(--r-sm); white-space: normal;
}
.setup-menu .tab:hover { background: var(--bg); }
.setup-menu .tab.is-active { background: var(--brand-soft); color: var(--brand-ink); }
