@import url("/static/fonts.css");

/* All About Autism brand palette, from the Brand Kit.
   #491A73 deep purple · #773FAD mid · #BE99F1 light · #F5F1FF tint
   #242121 ink · #FFFFFF white
   Type: Sniglet for headings, Poppins for everything else. (Rousing is the display
   face in the brand kit but it's a licensed font, so it's only used in the logo art.) */

:root {
  --deep: #491A73;
  --mid: #773FAD;
  --light: #BE99F1;
  --tint: #F5F1FF;
  --ink: #242121;
  --bg: #FAF7FF;
  --card: #ffffff;
  --muted: #6f6480;
  --line: #e4dcf2;

  /* Attendance states stay green / amber / red. They're safety-critical information,
     not brand decoration — a roll has to be readable at a glance and at arm's length,
     so they're deliberately outside the purple palette. Shades are pulled toward the
     brand's warmth so they still sit together. */
  --present: #2e7d55;
  --present-soft: #e3f3ea;
  --late: #a86412;
  --late-soft: #fdf0dc;
  --absent: #b23a4e;
  --absent-soft: #fce8ec;

  --radius: 14px;
  --font: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --display: "Sniglet", "Poppins", -apple-system, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 var(--font);
  -webkit-text-size-adjust: 100%;
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 1rem 1rem 5rem;
}

/* ---------------------------------------------------------------- top bar */

.topbar {
  background: var(--deep);
  color: #fff;
  padding: 0.7rem 1rem;
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar .brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #fff;
  text-decoration: none;
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  line-height: 1.1;
}
.topbar .brand img { height: 30px; width: auto; display: block; }
.topbar nav {
  display: flex;
  gap: 0.25rem 1.1rem;
  flex-wrap: wrap;
  margin-top: 0.4rem;
}
.topbar nav a {
  color: #fff;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
}
.topbar nav a:hover { color: var(--light); }
.topbar nav a.quiet { margin-left: auto; opacity: 0.75; }

/* ------------------------------------------------------------------ type */

h1 {
  font-family: var(--display);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--deep);
  margin: 1rem 0 0.25rem;
  line-height: 1.2;
}
h2 {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--mid);
  margin: 1.75rem 0 0.5rem;
}
h3 {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 400;
  color: var(--mid);
  margin: 0;
}
p { margin: 0.4rem 0; }
.sub { color: var(--muted); font-size: 0.9rem; margin-bottom: 1rem; }
.muted { color: var(--muted); }
small { font-size: 0.82rem; }

a { color: var(--mid); }

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

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin: 0 0 1rem;
  overflow: hidden;
}
.card-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 0.9rem;
  border-bottom: 1px solid var(--mid);
  background: var(--mid);
}
/* White on #773FAD is 6.8:1 — comfortably readable at arm's length. */
.card-head h3 { color: #fff; }
.card-head .count {
  margin-left: auto;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
}
.card-head .count.done { color: #C9F2DC; font-weight: 600; }
.card-body { padding: 0.5rem 0.9rem 0.9rem; }

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

.kid {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.kid:last-child { border-bottom: none; }
/* Basis is deliberately small: on a 375px phone the name and all three buttons have to
   stay on one line, or you halve how many children fit on screen. Long names wrap
   inside the name cell instead. */
.kid .name { flex: 1 1 5.5rem; font-weight: 500; min-width: 0; font-size: 0.95rem; }
.kid .name a { color: inherit; text-decoration: none; }
.kid .name .flag {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--late);
}
/* Counselling children come at their own time, so the slot leads the row. Shown on its
   own line: "08:30–09:15" plus a name won't fit beside three buttons on a phone. */
.kid .name .slot {
  display: block;
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--mid);
}

.states { display: flex; gap: 0.28rem; flex: 0 0 auto; }
.states button {
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  min-width: 3rem;
  min-height: 2.7rem;
  padding: 0 0.4rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.states button:active { transform: scale(0.97); }
.states button:focus-visible { outline: 3px solid var(--light); outline-offset: 1px; }
/* The three states use the brand palette rather than green/amber/red. They're separated
   by lightness — deep, mid, pale — because at arm's length that difference reads faster
   than hue does, and it survives being photocopied or seen by a colour-blind eye.
   Only ever one button is filled per child, so its position carries the rest. */
.kid[data-state="present"] .states button[value="present"] {
  background: var(--deep); border-color: var(--deep); color: #fff;
}
.kid[data-state="late"] .states button[value="late"] {
  background: var(--light); border-color: var(--mid); color: var(--deep);
}
.kid[data-state="absent"] .states button[value="absent"] {
  background: var(--mid); border-color: var(--mid); color: #fff;
}

.reason {
  flex: 1 1 100%;
  display: none;
  gap: 0.4rem;
  padding: 0.15rem 0 0.4rem;
}
.kid[data-state="absent"] .reason { display: flex; flex-wrap: wrap; }
/* input[type="text"] rather than a bare input: the generic form rule further down has the
   same specificity as `.reason input`, so it was winning on source order and resetting the
   note back to 16px while the dropdown next to it stayed at 13.6px. */
.reason select, .reason input[type="text"] {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #fff;
  min-height: 2.4rem;
}
.reason select { flex: 0 0 auto; }
.reason input { flex: 1 1 6rem; min-width: 0; }

/* --------------------------------------------------------------- controls */

/* The date and the day arrows share a line. If a long weekday ("Wednesday, 16 September")
   won't fit beside them on a narrow phone, the nav wraps underneath rather than squashing. */
.dayhead {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin: 1rem 0 0.25rem;
}
.dayhead h1 { margin: 0; flex: 1 1 auto; min-width: 0; }
.dayhead .daynav { margin: 0; flex: 0 0 auto; }
/* Styled like the outline buttons rather than a plain form field, so it reads as part of
   the interface instead of something you have to fill in. */
.dayhead .search {
  flex: 0 1 15rem;
  width: auto;
  min-width: 0;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--mid);
  border-radius: 10px;
  color: var(--mid);
}
.dayhead .search::placeholder { color: var(--mid); opacity: 0.75; font-weight: 600; }

.daynav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  margin: 0.5rem 0 1rem;
}
/* Arrow-only buttons don't need the full pill padding, and trimming them buys the room
   that keeps the date on the same line. */
.daynav a[aria-label] { padding: 0.5rem 0.7rem; }
.daynav a, .btn {
  display: inline-block;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 550;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--deep);
  text-decoration: none;
  cursor: pointer;
}
/* The whole group sits right, "Today" included. An auto margin here would absorb the
   free space and drag everything back to the left. */
.btn.primary { background: var(--deep); border-color: var(--deep); color: #fff; }
.btn.primary:hover { background: var(--mid); border-color: var(--mid); }
/* Matches the group card header it sits under. It's still an outline button, and it still
   asks for confirmation, since it writes off a whole session's billing. */
.btn.danger { background: #fff; border-color: var(--mid); color: var(--mid); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn:focus-visible, a:focus-visible { outline: 3px solid var(--light); outline-offset: 2px; }

.tabs { display: flex; gap: 0.4rem; margin: 1.25rem 0 0.75rem; }
.tabs button {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--muted);
  cursor: pointer;
}
.tabs button[aria-selected="true"] {
  background: var(--deep);
  border-color: var(--deep);
  color: #fff;
}
.tabs button:disabled { opacity: 0.45; cursor: not-allowed; }
@media (max-width: 420px) {
  .tabs { gap: 0.3rem; }
  .tabs button { padding: 0.45rem 0.6rem; font-size: 0.82rem; }
}

.flash {
  padding: 0.6rem 0.8rem;
  border-radius: 10px;
  margin: 0.75rem 0;
  font-size: 0.92rem;
}
.flash.ok { background: var(--present-soft); color: var(--present); }
.flash.error { background: var(--absent-soft); color: var(--absent); }

.banner {
  background: #fff;
  border: 1px solid var(--light);
  border-left: 4px solid var(--mid);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  margin: 0 0 1rem;
  font-size: 0.92rem;
}
.banner.warn { background: var(--late-soft); border-color: #e8cf9f; border-left-color: var(--late); }

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

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th, td { text-align: left; padding: 0.5rem; border-bottom: 1px solid var(--line); }
th {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--mid);
  font-weight: 600;
}
.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.pill {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
}
/* Attendance pills mirror the roll buttons so the two screens speak the same language. */
.pill.present { background: var(--deep); color: #fff; }
.pill.late { background: var(--light); color: var(--deep); }
.pill.absent { background: var(--mid); color: #fff; }
.pill.closed { background: var(--tint); color: var(--mid); }
/* "Needs a decision" stays amber. It's a warning on Lizzie's approval screen, not an
   attendance state, and it should not blend into the brand colours around it. */
.pill.review { background: var(--late-soft); color: var(--late); }

/* --------------------------------------------------------------- contacts */

.contact {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--line);
}
.contact:last-of-type { border-bottom: none; }
.contact-who { flex: 1 1 9rem; min-width: 0; }
.contact-name { font-weight: 600; display: block; }
.contact-rel, .contact-note {
  display: block;
  font-size: 0.83rem;
  color: var(--muted);
}
.pill.emergency { background: var(--absent-soft); color: var(--absent); }

/* Deliberately large: this gets tapped one-handed, at the door, in a hurry. */
.btn.call {
  background: var(--deep);
  border-color: var(--deep);
  color: #fff;
  font-weight: 600;
  padding: 0.6rem 0.9rem;
  min-height: 2.8rem;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.btn.call:hover { background: var(--mid); border-color: var(--mid); }

.contact-edit { flex: 0 0 auto; }
.contact-edit summary,
details > summary.btn {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--mid);
  list-style: none;
}
.contact-edit summary::-webkit-details-marker,
details > summary.btn::-webkit-details-marker { display: none; }
.contact-edit[open] { flex: 1 1 100%; }
.contact-form { margin-top: 0.6rem; }

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

form.stack { display: grid; gap: 0.6rem; max-width: 24rem; }
label { font-size: 0.85rem; font-weight: 600; display: block; margin-bottom: 0.2rem; }
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=tel], select, textarea {
  font: inherit;
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--light);
  outline-offset: 1px;
  border-color: var(--mid);
}

/* ------------------------------------------------------------------ login */

.login { max-width: 23rem; margin: 2.5rem auto; }
.login-hero {
  background: var(--deep);
  border-radius: var(--radius);
  padding: 1.75rem 1.5rem;
  text-align: center;
  margin-bottom: 1.5rem;
}
.login-hero img { max-width: 190px; width: 70%; height: auto; }
.login-hero .wordmark {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.5rem;
  color: #fff;
  line-height: 1.2;
  margin: 0;
}
.login-hero .tagline {
  color: var(--light);
  font-size: 0.9rem;
  margin-top: 0.35rem;
}

/* ------------------------------------------------------------------ print */

@media print {
  .topbar, .daynav, .noprint { display: none !important; }
  body { background: #fff; }
  main { max-width: none; padding: 0; }
  h1, h2, h3 { color: #000; }
  table { font-size: 10px; }
  th, td { padding: 2px 4px; border: 1px solid #bbb; }
}

/* On a phone the logo is the anchor: centred and large, nav underneath it. On desktop
   there's room for the logo and nav to sit on one line. */
@media (max-width: 639px) {
  /* Sized so the worst case — "Wednesday, 16 September" with the Today button showing —
     still shares one line with the arrows on a 375px phone. The full date is repeated
     underneath, so the heading can afford to be compact. */
  .dayhead h1 { font-size: 1.05rem; }
  .dayhead { gap: 0.4rem; }
  .dayhead .daynav { gap: 0.35rem; }
  .dayhead .daynav a { padding: 0.45rem 0.6rem; font-size: 0.85rem; }
  .topbar .brand { justify-content: center; }
  .topbar .brand img { height: 44px; }
  .topbar nav { justify-content: center; margin-top: 0.65rem; }
  .topbar nav a.quiet { margin-left: 0; }
}

@media (min-width: 640px) {
  .topbar { display: flex; align-items: center; gap: 1.5rem; }
  .topbar nav { margin-top: 0; flex: 1; }
  .topbar .brand img { height: 36px; }
}

/* A child in more than one programme bills on more than one invoice — worth seeing. */
.both {
  color: var(--deep);
  font-weight: 600;
}

/* A temporary password is read aloud or typed off the screen once, so it needs to be
   unambiguous: monospace so 1/l and 0/O are distinguishable, and large enough to read
   from arm's length without squinting at a phone. */
.temp-password {
  display: inline-block;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 1.35rem;
  letter-spacing: 0.06em;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.4rem 0.7rem;
  user-select: all;
}

/* ------------------------------------------------- the family portal's own bits */

/* A child's regular week: a plain list, not a table. Parents read this on a phone. */
ul.plain { list-style: none; margin: 0 0 0.6rem; padding: 0; }
ul.plain li { padding: 0.35rem 0; border-bottom: 1px solid var(--line); }
ul.plain li:last-child { border-bottom: 0; }

/* One upcoming session. Stacks on a phone so the "tell us they'll be away" control
   never gets squeezed against the date. */
.session-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  align-items: flex-start;
  justify-content: space-between;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--line);
}
.session-row:last-child { border-bottom: 0; }
.session-when { display: flex; flex-direction: column; gap: 0.15rem; }
.session-when .muted { font-size: 0.85rem; }
.session-state { display: flex; flex-direction: column; gap: 0.45rem; align-items: flex-start; }
.session-state details { width: 100%; }

/* The per-contact edit form sits under its contact rather than beside it — there isn't
   room for both on a phone, and editing is the rarer action. */
.contact-edit { margin: -0.2rem 0 0.5rem; }
.contact-edit > summary { font-size: 0.82rem; padding: 0.3rem 0.6rem; }

@media (max-width: 480px) {
  .session-row { flex-direction: column; }
  .session-state { width: 100%; }
}

/* On a family's first visit the sessions list is folded away behind this, so the one
   thing we actually need from them — checking who can collect their child — isn't
   competing with anything. */
details.later { margin: 1.25rem 0 0; }
details.later > summary { width: 100%; text-align: center; }
details.later[open] > summary { margin-bottom: 0.3rem; }

/* ------------------------------------------------------------- the groups page */

.group-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.9rem;
  margin-bottom: 1.4rem;
}
.member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--line);
}
.member-row:last-child { border-bottom: 0; }
.member-row a { color: var(--ink); text-decoration: none; font-weight: 600; }
.member-row a:hover { color: var(--mid); }
.move-form select { font-size: 0.8rem; padding: 0.25rem 0.4rem; max-width: 11rem; }

/* Group tick-boxes on the child page: a wrapped row of labelled pills. */
.group-ticks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.25rem 0.9rem;
}
.group-ticks .tick {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  font-weight: 500;
  padding: 0.25rem 0;
}

/* ------------------------------------------------ contact badges & the day sheet */

/* Emergency stays red-tinted (safety), collection gets the brand purple, parent the
   soft tint — three distinct answers to "who is this person to the child". */
.pill.parent  { background: var(--tint); color: var(--deep); }
.pill.collect { background: var(--light); color: var(--deep); }

/* The family link row: an input so the URL never wraps or half-selects, with Open and
   Copy beside it. */
.copy-link { display: flex; gap: 0.4rem; margin-top: 0.5rem; }
.copy-link input {
  flex: 1;
  min-width: 0;
  font-size: 0.8rem;
  color: var(--muted);
  padding: 0.45rem 0.6rem;
}

/* One child on the day sheet. */
.sheet-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.6rem;
  align-items: baseline;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--line);
}
.sheet-row:last-of-type { border-bottom: 0; }
.sheet-medical { font-size: 0.9rem; }

/* The date jumper on the roll: sized to sit in the daynav row. */
.daynav input[type="date"] {
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--card);
}

/* A yes/no question and its two radios on one line, wrapping on phones. */
.yn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.9rem;
  align-items: center;
  padding: 0.15rem 0;
}
.yn-row > span { flex: 1 1 14rem; }
