/* ============================================================================
   Howzit Buddy, platform design system
   The app wears the home page's colours (assets/landing.css): the petrol-blue
   wall from the mascot artwork, the logo's lighter blues as the accent, and
   its letter colours (coral O, green w, amber z) for highlights. The
   wellbeing domains keep their own colours. Used by the sign-in pages, the
   learner app and both dashboards; the staff pages calm it down a notch in
   fx-pro.css (a quieter wall, firmer cards), the learner app keeps it bright.

   Contrast (WCAG AA, 4.5:1 for text) was checked on every surface the tokens
   below meet: the lit wall at its brightest, a card's thinnest layer over
   it, the nav, inputs. The lowest pairs: a green or coral pill on a learner
   card 4.7:1, muted text on the brightest point of the wall 4.8:1, ink on
   the coral count 4.8:1, white on the coral button 4.7:1. Green (--mint) and
   link blue (--sky) text belong on cards and the nav; on the bare wall they
   pass from its middle down (4.7:1 and 5.2:1) but not in the light itself.
   ========================================================================== */

:root {
  /* The characters' world, the same four values as the home page. */
  --wall:      #014f76;
  --wall-glow: #0a6a98;
  --wall-edge: #013f60;
  --deep:      #072a41;

  /* The logo. Its blues are the accent: where you are, what is a link, what
     is picked. #0692f9 is "buddy.co.za", #018afe the smile, #0167fe the H. */
  --blue:   #0692f9;
  --arc:    #018afe;
  --logo-h: #0167fe;
  --sky:    #9ccbff;   /* the logo blue lifted to read as text on petrol (5.2:1 on the wall) */
  --red:    #fc5338;   /* the O, as a fill */
  --green:  #53bc96;   /* the w, as a fill */
  --yellow: #fda002;   /* the z: the main button, as on the home page */
  --orange: #F5883B;
  --teal:   #014f76;
  --ink:    #0a2536;   /* text on the light fills: 7.7:1 on amber, 4.8:1 on coral */
  --cream:  #FFFDF7;

  /* Wellbeing app palette (from the original prototype) */
  --E: #4fc3f7;      /* Engagement */
  --P: #81c784;      /* Perseverance */
  --O: #ffb74d;      /* Optimism */
  --C: #f48fb1;      /* Connectedness */
  --H: #ce93d8;      /* Happiness */
  --mint:  #62d2a9;  /* the logo's green w, a shade lighter so it reads on petrol */
  --coral: #ff8a70;  /* the logo's coral O, likewise (the fill is --red) */
  --sun:   #ffd366;

  --text:   #FFFDF7;
  --muted:  #c2dbe9;                    /* solid, not see-through: it must pass on the lit wall too */
  --border: rgba(255, 255, 255, 0.14);

  /* Surfaces: dark glass on the lit wall, like the panels on the home page's
     stage. The staff pages make them firmer (fx-pro.css). */
  --card:    rgba(3, 29, 47, 0.5);      /* flat tiles and stat cards */
  --card-hi: rgba(4, 33, 53, 0.62);     /* a card's top edge... */
  --card-lo: rgba(3, 29, 47, 0.54);     /* ...and its foot */
  --field:   #05304b;                   /* inputs */
  --field-line: rgba(156, 203, 255, 0.5);
  --nav-bg:  rgba(5, 40, 62, 0.95);
  --wall-light: rgba(10, 106, 152, 0.6);   /* the light behind the characters */

  --sidebar-w: 232px;   /* desktop nav rail */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { -webkit-font-smoothing: antialiased; }

body {
  font-family: 'Nunito', system-ui, sans-serif;
  color: var(--text);
  /* The home page's stage: the wall lit from behind at the top, a little of
     the smile's blue in a far corner, falling to the art's deep corner. */
  background:
    radial-gradient(130% 60% at 50% -14%, var(--wall-light) 0%, rgba(10, 106, 152, 0) 72%),
    radial-gradient(90% 55% at 100% 100%, rgba(1, 138, 254, 0.13) 0%, rgba(1, 138, 254, 0) 70%),
    linear-gradient(180deg, var(--wall) 0%, var(--wall-edge) 58%, var(--deep) 100%);
  background-color: var(--deep);
  background-attachment: fixed;
  min-height: 100vh;
  line-height: 1.5;
}

/* The wall in the artwork is textured plaster, and so is the home page's: a
   faint grain keeps this one from looking like a flat gradient beside it.
   One painted tile, nothing animated, no blend mode (cheap on old laptops). */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.07;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.app-shell, .wide-shell, .reg-shell, .nav-bar, .topbar { position: relative; z-index: 1; }

.font-display, h1, h2, h3 { font-family: 'Fredoka', system-ui, sans-serif; font-weight: 600; }

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

/* ---------- Layout shells ---------- */

.app-shell {                 /* learner app: phone-first column */
  max-width: 480px;
  margin: 0 auto;
  padding: 16px 16px 96px;   /* room for bottom nav */
  min-height: 100vh;
}

.wide-shell {                /* teacher/admin: desktop dashboard */
  max-width: 1150px;
  margin: 0 auto;
  padding: 20px 20px 60px;
}

/* ---------- Cards ---------- */

.card {
  background: linear-gradient(180deg, var(--card-hi), var(--card-lo));
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 20px 18px;
  margin-bottom: 14px;
  backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 20px 44px -26px rgba(0, 12, 22, 0.85);
}
.sj-card { box-shadow: 0 16px 34px -26px rgba(0, 12, 22, 0.85); }

.section-tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  padding: 5px 12px;
  border-radius: 50px;
  margin-bottom: 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid currentColor;
  color: var(--muted);
}
.tag-mood   { background: rgba(252, 83, 56, 0.14);   color: var(--coral); }
.tag-sleep  { background: rgba(79, 195, 247, 0.14);  color: var(--E); }
.tag-social { background: rgba(98, 210, 169, 0.14);  color: var(--mint); }

.card h2 { font-size: 18px; margin-bottom: 12px; line-height: 1.35; }

/* ---------- Buttons ---------- */

.btn {
  display: block;
  width: 100%;
  padding: 14px;
  border: none;
  border-radius: 50px;
  font-family: 'Nunito', sans-serif;
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  color: var(--text);
  margin-bottom: 10px;
  transition: transform 0.12s ease, filter 0.15s ease;
}
.btn:hover  { filter: brightness(1.08); }
.btn:active { transform: translateY(2px); }

/* Chunky like the home page's buttons and the logo's balloon letters: a
   darker lip along the bottom edge. Text is dark on the light fills (the
   white used to sit at under 3:1 on the mint), white only on the deep coral. */
.btn-mint   { background: linear-gradient(135deg, #6fd8b1, #3fb58a); color: var(--ink);
              box-shadow: inset 0 -3px 0 rgba(0, 70, 45, 0.22), 0 8px 22px -8px rgba(83, 188, 150, 0.55); }
.btn-yellow { background: linear-gradient(180deg, #ffb42e, var(--yellow)); color: var(--ink);
              box-shadow: inset 0 -3px 0 rgba(120, 60, 0, 0.28), 0 10px 24px -10px rgba(253, 160, 2, 0.6); }
.btn-coral  { background: linear-gradient(135deg, #d33f26, #b5301a); color: #fff;
              box-shadow: inset 0 -3px 0 rgba(80, 10, 0, 0.25); }
/* As on the home page: white words in a white outline, the wall showing through. */
.btn-ghost  { background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.34); color: var(--text); }
.btn-ghost:hover { background: rgba(255, 255, 255, 0.09); border-color: rgba(255, 255, 255, 0.6); }
.btn-sm     { width: auto; display: inline-block; padding: 8px 16px; font-size: 13px; margin-bottom: 0; }

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--sun);
  outline-offset: 2px;
}

/* ---------- Forms ---------- */

.input, select.input, textarea.input {
  width: 100%;
  background: var(--field);
  border: 1.5px solid var(--field-line);   /* 3.5:1 against the card: the box is easy to find */
  border-radius: 14px;
  padding: 12px 16px;
  font-family: 'Nunito', sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  outline: none;
  margin-bottom: 10px;
  display: block;
}
.input::placeholder { color: rgba(214, 230, 240, 0.62); }   /* 5:1 on the field */
.input:focus { border-color: #4fb3ff; }                      /* the logo's arc blue, lifted */
select.input option { background: var(--field); color: #fff; }
.input-pin { text-align: center; font-size: 20px; letter-spacing: 8px; font-weight: 800; }

label.check {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: #d6e8f2;
  line-height: 1.6;
}
label.check input { width: 20px; height: 20px; min-width: 20px; margin-top: 2px; accent-color: var(--mint); cursor: pointer; }

.form-err {
  color: var(--coral);
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  margin-top: 8px;
  min-height: 1.2em;
}
.form-ok { color: var(--mint); }

/* (The old .tabs strip is gone: the learner app, the school dashboard and the
   admin dashboard all navigate with .nav-bar below.) */

/* ---------- Emoji answer rows & chips ---------- */

.emoji-row { display: flex; gap: 6px; justify-content: space-between; }
.em-btn {
  flex: 1;
  background: rgba(255, 255, 255, 0.05);
  border: 1.5px solid var(--border);
  border-radius: 14px;
  padding: 12px 4px 8px;
  font-size: 26px;
  cursor: pointer;
  text-align: center;
  transition: transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s, border-color 0.2s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.em-btn:hover { transform: translateY(-3px); }
.em-btn.sel   { background: rgba(98, 210, 169, 0.18); border-color: var(--mint); transform: translateY(-3px) scale(1.05); }
.em-lbl { font-size: 10px; font-weight: 800; color: var(--muted); font-family: 'Nunito', sans-serif; }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  background: rgba(255, 255, 255, 0.05);
  border: 1.5px solid var(--border);
  border-radius: 50px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
}
.chip:hover { border-color: rgba(255, 255, 255, 0.35); }
.chip.sel   { background: rgba(98, 210, 169, 0.16); border-color: var(--mint); color: var(--mint); }

/* ---------- Sliders ---------- */

input[type="range"] {
  width: 100%;
  accent-color: var(--mint);
  height: 34px;
  cursor: pointer;
}
.slider-labels {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
}
.slider-labels span:nth-child(2) { color: var(--mint); font-size: 13px; }

/* ---------- Progress dots / bars ---------- */

.pdots { display: flex; gap: 8px; justify-content: center; padding: 8px 0 16px; }
.pdot  { width: 34px; height: 6px; border-radius: 6px; background: rgba(255, 255, 255, 0.12); }
.pdot.active { background: var(--mint); }
.pdot.done   { background: rgba(98, 210, 169, 0.45); }

.epoch-progress { display: flex; align-items: center; gap: 12px; padding: 10px 0 18px; }
.epoch-bar-bg   { flex: 1; height: 8px; border-radius: 8px; background: rgba(255, 255, 255, 0.1); overflow: hidden; }
.epoch-bar-fill { height: 100%; border-radius: 8px; background: linear-gradient(90deg, var(--mint), var(--E)); transition: width 0.35s ease; }
.epoch-prog-text { font-size: 12px; font-weight: 800; color: var(--muted); white-space: nowrap; }

/* ---------- EPOCH rating buttons ---------- */

.rating-row { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.rating-btn {
  background: rgba(255, 255, 255, 0.05);
  border: 1.5px solid var(--border);
  border-radius: 14px;
  padding: 13px 16px;
  font-family: 'Nunito', sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: all 0.15s;
  white-space: pre-line;
}
.rating-btn:hover { border-color: rgba(255, 255, 255, 0.4); }
.rating-btn.sel-E { background: rgba(79,195,247,0.18);  border-color: var(--E); }
.rating-btn.sel-P { background: rgba(129,199,132,0.18); border-color: var(--P); }
.rating-btn.sel-O { background: rgba(255,183,77,0.18);  border-color: var(--O); }
.rating-btn.sel-C { background: rgba(244,143,177,0.18); border-color: var(--C); }
.rating-btn.sel-H { background: rgba(206,147,216,0.18); border-color: var(--H); }

/* ---------- Domain bars & score ring ---------- */

.domain-bar-row { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.db-label { width: 128px; min-width: 128px; }
.db-name  { font-size: 12px; font-weight: 800; }
.db-score { font-size: 18px; font-weight: 900; font-family: 'Fredoka', sans-serif; }
.db-band  { font-size: 10px; font-weight: 800; text-transform: uppercase; opacity: 0.8; }
.db-bar-bg   { flex: 1; height: 10px; background: rgba(255, 255, 255, 0.08); border-radius: 10px; overflow: hidden; }
.db-bar-fill { height: 100%; border-radius: 10px; transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1); }

.epoch-overall { text-align: center; padding: 18px 0 8px; }
.overall-score-ring { position: relative; width: 130px; height: 130px; margin: 0 auto 10px; }
.overall-score-ring svg { transform: rotate(-90deg); }
.score-inner {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.overall-big { font-family: 'Fredoka', sans-serif; font-size: 34px; font-weight: 700; }
.overall-lbl { font-size: 10px; font-weight: 800; text-transform: uppercase; color: var(--muted); }

/* ---------- Insight / exercise blocks ---------- */

.insight-block { border-radius: 14px; padding: 14px 16px; margin-bottom: 10px; border: 1px solid var(--border); }
.insight-block.strength  { background: rgba(98, 210, 169, 0.08); border-color: rgba(98, 210, 169, 0.28); }
.insight-block.attention { background: rgba(255, 183, 77, 0.08); border-color: rgba(255, 183, 77, 0.28); }
.insight-block.low-block { background: rgba(252, 83, 56, 0.09);  border-color: rgba(252, 83, 56, 0.32); }
.ib-tag   { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 4px; }
.ib-title { font-size: 15px; font-weight: 800; margin-bottom: 4px; }
.ib-text  { font-size: 13px; font-weight: 600; color: #d6e8f2; line-height: 1.7; }

.ex-card  { background: rgba(255, 255, 255, 0.045); border-radius: 14px; padding: 14px 16px; margin-bottom: 10px; }
.ex-title { font-size: 15px; font-weight: 800; margin-bottom: 6px; }
.ex-body  { font-size: 13px; font-weight: 600; color: #d0e3ee; line-height: 1.7; margin-bottom: 8px; }
.ex-tag   { display: inline-block; font-size: 11px; font-weight: 800; padding: 4px 10px; border-radius: 50px; }

/* ---------- Streak / score displays ---------- */

.streak-row {
  display: flex; align-items: center; gap: 14px;
  background: linear-gradient(135deg, rgba(255, 211, 102, 0.1), rgba(240, 180, 41, 0.05));
  border: 1px solid rgba(255, 211, 102, 0.25);
  border-radius: 16px;
  padding: 14px 18px;
  margin-bottom: 14px;
}
.streak-fire { font-size: 30px; }
.streak-val  { font-family: 'Fredoka', sans-serif; font-size: 19px; font-weight: 700; color: var(--sun); }
.streak-lbl  { font-size: 12px; font-weight: 700; color: var(--muted); }

.score-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.sc-item { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 14px 8px; text-align: center; }
.sc-emoji { font-size: 22px; }
.sc-val   { font-family: 'Fredoka', sans-serif; font-size: 22px; font-weight: 700; }
.sc-lbl   { font-size: 10px; font-weight: 800; color: var(--muted); text-transform: uppercase; }

/* ---------- Mode cards (home) ---------- */

.mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mode-card {
  background: rgba(255, 255, 255, 0.05);
  border: 1.5px solid var(--border);
  border-radius: 18px;
  padding: 18px 14px;
  text-align: center;
  cursor: pointer;
  transition: all 0.15s;
}
/* The two big choices wear the logo: the smile's blue, and the w's green. */
.mode-card:nth-child(1) {
  background: linear-gradient(160deg, rgba(1, 138, 254, 0.26), rgba(1, 138, 254, 0.08));
  border-color: rgba(79, 170, 255, 0.55);
}
.mode-card:nth-child(2) {
  background: linear-gradient(160deg, rgba(83, 188, 150, 0.26), rgba(83, 188, 150, 0.08));
  border-color: rgba(98, 210, 169, 0.55);
}
.mode-card:hover { transform: translateY(-3px); }
.mode-card:nth-child(1):hover { border-color: #4fb3ff; }
.mode-card:nth-child(2):hover { border-color: var(--mint); }
.mc-emoji { font-size: 32px; display: block; margin-bottom: 8px; }
.mc-title { font-size: 14px; font-weight: 800; margin-bottom: 3px; }
.mc-sub   { font-size: 11px; font-weight: 600; color: var(--muted); }

/* ---------- Bottom navigation (learner app) ---------- */

.nav-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  display: flex;
  justify-content: center;
  gap: 2px;
  background: var(--nav-bg);
  backdrop-filter: blur(14px);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
  z-index: 50;
}
.nav-btn {
  flex: 1;
  max-width: 88px;
  background: none;
  border: none;
  color: var(--muted);
  font-family: 'Nunito', sans-serif;
  cursor: pointer;
  padding: 6px 2px;
  border-radius: 12px;
  text-align: center;
  text-decoration: none;
}
/* Where you are: the logo's blue (the label 6.8:1 on its tint). */
.nav-btn.active { color: var(--sky); background: rgba(6, 146, 249, 0.2); }
.nav-icon { display: block; font-size: 20px; }
.nav-lbl  { font-size: 10px; font-weight: 800; }
.nav-sos  { color: var(--coral); }

/* A tab whose name is too long for a narrow phone can carry a one-word
   version. Everything wider, including the desktop rail, shows the full name. */
.nav-lbl-short { display: none; }
@media (max-width: 370px) {
  .nav-lbl-long  { display: none; }
  .nav-lbl-short { display: inline; }
}

/* Brand block, only shown when the nav becomes a desktop sidebar */
.nav-brand { display: none; }

/* ---------- The same nav on the dashboards (teacher & admin) ----------
   Staff and admin used to get a row of tab buttons that ran off the side of a
   phone, and looked nothing like the learner app. They now use this nav as
   well: a bottom bar on a phone, the sidebar rail on a laptop. Two things the
   learner app never needed: a count on an item (open alerts, new schools), and
   sign out, which sits at the foot of the rail and stays in the top bar on a
   phone, where there is no room for a sixth item. */
.nav-badge {
  display: inline-block;
  min-width: 17px;
  padding: 0 5px;
  margin-left: 3px;
  border-radius: 50px;
  background: var(--red);      /* the logo's coral, dark figures: 4.8:1 (white was 2.8:1) */
  color: var(--ink);
  font-size: 10px;
  font-weight: 900;
  line-height: 17px;
  text-align: center;
  vertical-align: middle;
}
.nav-badge-quiet { background: var(--sky); color: var(--ink); }
.nav-quit { display: none; }
/* On the phone bar a count sits on the icon's corner, the way an app icon
   carries one. Inline, it pushed a label onto a second line once the admin bar
   grew to seven items. The rail on a laptop keeps it inline. */
@media (max-width: 1023px) {
  .nav-btn { position: relative; }
  .nav-btn .nav-badge { position: absolute; top: 1px; left: 50%; margin-left: 5px;
                        min-width: 16px; padding: 0 4px; line-height: 16px; font-size: 9.5px; }
}

/* Room for the bottom bar, the dashboards' own shell does not allow for it */
body.has-sidebar .wide-shell { padding-bottom: 104px; }

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

.home-hero { text-align: center; padding: 18px 0 12px; }
.home-hero img { width: 130px; border-radius: 18px; box-shadow: 0 14px 34px rgba(0, 20, 35, 0.45); }
.home-hero h1 { font-size: 22px; margin-top: 12px; }

/* ---------- Progress: stat tiles, meters, themes, badges ---------- */

.tile-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-bottom: 14px;
}
.tile {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px 12px;
  text-align: center;
}
.tile-ico { font-size: 20px; line-height: 1; }
.tile-num { font-family: 'Fredoka', sans-serif; font-size: 24px; font-weight: 700; line-height: 1.15; }
.tile-lbl { font-size: 9.5px; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; }

/* Average meters (mood / sleep / social / energy) */
.meter { margin-bottom: 12px; }
.meter:last-child { margin-bottom: 0; }
.meter-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
.meter-name { font-size: 13px; font-weight: 800; }
.meter-val  { font-family: 'Fredoka', sans-serif; font-size: 15px; font-weight: 700; }
.meter-bar  { height: 8px; background: rgba(255, 255, 255, .08); border-radius: 8px; overflow: hidden; }
.meter-fill { height: 100%; border-radius: 8px; width: 0; transition: width .9s cubic-bezier(.22, 1, .36, 1); }

/* Theme chips ("what's been on your mind") */
.theme-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--border);
  border-radius: 50px;
  padding: 7px 12px;
  font-size: 12.5px; font-weight: 700;
  margin: 0 6px 6px 0;
}
.theme-count {
  background: rgba(98, 210, 169, .18);
  color: var(--mint);
  border-radius: 50px;
  padding: 1px 7px;
  font-size: 11px; font-weight: 800;
}

/* Badge tiles */
.badge-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.badge-tile {
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px 6px;
  text-align: center;
}
.badge-tile.got { border-color: rgba(255, 211, 102, .45); background: rgba(255, 211, 102, .08); }
.badge-tile.locked { opacity: .42; filter: grayscale(.8); }
.badge-emoji { font-size: 22px; }
.badge-name  { font-size: 9.5px; font-weight: 800; margin-top: 3px; line-height: 1.3; }

/* ---------- Calendar ---------- */

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-cell {
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.04);
}
.cal-cell.done  { background: rgba(98, 210, 169, 0.2); color: var(--mint); border: 1px solid rgba(98, 210, 169, 0.45); }
.cal-cell.today { border: 1.5px solid var(--yellow); color: var(--yellow); }
.cal-cell.empty { background: none; }
.cal-dow { font-size: 10px; text-transform: uppercase; opacity: 0.6; background: none; aspect-ratio: auto; padding: 4px 0; }

/* ---------- Weekly mood bars ---------- */

.bar-chart { display: flex; align-items: stretch; gap: 8px; height: 140px; padding-top: 8px; }
.bar-col   { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; }
/* The track soaks up the spare height so bars scale with the card instead of
   being stranded at the bottom of a tall column. */
.bar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; }
.bar-fill  { width: 100%; border-radius: 8px 8px 4px 4px; min-height: 4px; transition: height 0.6s ease; }
.bar-emoji { font-size: 15px; line-height: 1; }
.bar-lbl   { font-size: 10px; font-weight: 800; color: var(--muted); }

/* ---------- Breathing circle ---------- */

.breathe-wrap { text-align: center; padding: 10px 0; }
.breathe-circle {
  width: 130px; height: 130px;
  margin: 14px auto;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(98, 210, 169, 0.25), rgba(98, 210, 169, 0.08));
  border: 2px solid var(--mint);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 800; color: var(--mint);
  cursor: pointer;
  transition: transform 4s ease-in-out;
}
.breathe-circle.inh { transform: scale(1.35); }
.breathe-circle.exh { transform: scale(0.85); }
.breathe-inst { font-size: 16px; font-weight: 800; min-height: 1.4em; }
.breathe-sub  { font-size: 12px; color: var(--muted); font-weight: 600; min-height: 1.3em; }

/* ---------- Toasts / overlays ---------- */

.toast {
  position: fixed;
  bottom: 100px; left: 50%;
  transform: translateX(-50%);
  background: linear-gradient(135deg, rgba(255, 211, 102, 0.97), rgba(253, 170, 20, 0.97));
  color: var(--ink);
  padding: 10px 22px;
  border-radius: 50px;
  font-size: 13px; font-weight: 800;
  z-index: 999;
  white-space: nowrap;
  box-shadow: 0 4px 20px rgba(253, 160, 2, 0.4);
  transition: all 0.4s;
}
.toast.mint { background: linear-gradient(135deg, rgba(111, 216, 177, 0.97), rgba(63, 181, 138, 0.97)); color: var(--ink); }

.overlay {
  position: fixed; inset: 0;
  background: rgba(2, 18, 30, 0.86);
  z-index: 900;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.overlay-box {
  background: linear-gradient(180deg, #0a4566, #06324d);
  border: 1.5px solid var(--border);
  border-radius: 24px;
  padding: 28px;
  max-width: 360px;
  width: 100%;
  text-align: center;
}

/* ---------- Loading spinner ---------- */

.loading { text-align: center; padding: 80px 0; }
.spin {
  width: 42px; height: 42px;
  margin: 0 auto 18px;
  border: 4px solid rgba(255, 255, 255, 0.12);
  border-top-color: var(--mint);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Screens (SPA) ---------- */

.screen { display: none; animation: fadein 0.3s ease; }
.screen.active { display: block; }
@keyframes fadein { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- Dashboard (teacher/admin) ---------- */

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.stat-card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 18px; text-align: center; }
.stat-num  { font-family: 'Fredoka', sans-serif; font-size: 32px; font-weight: 700; }
.stat-lbl  { font-size: 10px; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: 1px; margin-top: 4px; }

.table-wrap { overflow-x: auto; }
table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.data th {
  text-align: left;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--muted);
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: rgba(156, 203, 255, 0.07);
}
table.data td { padding: 12px; border-bottom: 1px solid rgba(255, 255, 255, 0.07); font-weight: 600; }
table.data tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.025); }
table.data tr:hover td { background: rgba(156, 203, 255, 0.06); }

.pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 50px;
  font-size: 11px;
  font-weight: 800;
  white-space: nowrap;
}
.pill-green  { background: rgba(98, 210, 169, 0.15);  color: var(--mint); }
.pill-amber  { background: rgba(255, 183, 77, 0.15);  color: var(--O); }
.pill-red    { background: rgba(252, 83, 56, 0.16);   color: var(--coral); }
.pill-grey   { background: rgba(255, 255, 255, 0.08); color: var(--muted); }
.pill-blue   { background: rgba(6, 146, 249, 0.2);    color: var(--sky); }

.avatar {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: linear-gradient(135deg, #6fd8b1, #3fb58a);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 900; color: var(--ink);
  flex-shrink: 0;
}

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding: 6px 0 18px;
}
.topbar .brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text); }
.brand-badge {
  width: 40px; height: 40px;
  border-radius: 12px;
  background: var(--blue);
  display: grid; place-items: center;
  box-shadow: 0 8px 18px rgba(0, 20, 35, 0.4);
}
.brand-name { font-family: 'Fredoka', sans-serif; font-size: 19px; font-weight: 600; }

/* The wordmark itself, where the name used to be written out: in a phone's
   top bar and at the head of the laptop rail. Always its own proportions
   (the width sets the size, the height follows), a soft shadow like the
   home page's, and the school name or "Platform admin" under or beside it. */
.brand-logo {
  display: block;
  width: 110px;
  max-width: 100%;
  height: auto;
  aspect-ratio: 200 / 83;
  object-fit: contain;
  flex: none;
  filter: drop-shadow(0 6px 12px rgba(0, 20, 35, 0.35));
}
.topbar .brand:has(.brand-logo) { gap: 12px; }
.topbar .brand .brand-logo { width: 110px; }
@media (min-width: 700px) { .topbar .brand .brand-logo { width: 140px; } }

/* ---------- Utility ---------- */

.muted   { color: var(--muted); }
.small   { font-size: 12px; }
.center  { text-align: center; }
.mt      { margin-top: 14px; }
.mb0     { margin-bottom: 0; }
.flex    { display: flex; align-items: center; gap: 10px; }
.grow    { flex: 1; }
.hidden  { display: none !important; }

/* ============================================================================
   RESPONSIVE, the learner app is phone-first, but must not look like a phone
   emulator on a laptop. Tablet widens the column; desktop turns the bottom nav
   into a sidebar rail and lays cards out in columns.
   ========================================================================== */

/* ---------- Tablet ---------- */
@media (min-width: 700px) {
  .app-shell { max-width: 640px; padding: 22px 22px 104px; }
  .home-hero img { width: 150px; }
  .home-hero h1 { font-size: 25px; }
  .tile-row { grid-template-columns: repeat(4, 1fr); }
}

/* ---------- Desktop ---------- */
@media (min-width: 1024px) {

  /* Every signed-in area opts in: the learner app, and both dashboards. */
  body.has-sidebar { padding-left: var(--sidebar-w); }
  body.has-sidebar .wide-shell { padding-bottom: 60px; }

  /* The rail carries the brand, so the top bar keeps only who you are and what
     you can do from here. */
  body.has-sidebar .topbar { justify-content: flex-end; }
  body.has-sidebar .topbar .brand { display: none; }
  body.has-sidebar .nav-quit { display: flex; margin-top: auto; }

  /* Bottom nav → left sidebar rail */
  body.has-sidebar .nav-bar {
    top: 0;
    bottom: 0;
    right: auto;
    width: var(--sidebar-w);
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 4px;
    padding: 22px 14px 22px;
    border-top: none;
    border-right: 1px solid rgba(255, 255, 255, 0.09);
  }
  body.has-sidebar .nav-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 10px 20px;
    text-decoration: none;
    color: var(--text);
  }
  /* With the wordmark, the rail's head stacks: the logo across the rail
     (156px of its 204), and the school name or "Platform admin" under it. */
  body.has-sidebar .nav-brand:has(.brand-logo) {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 0 8px 18px;
  }
  body.has-sidebar .nav-brand .brand-logo { width: 156px; margin-left: -4px; }
  body.has-sidebar .nav-btn {
    flex: 0 0 auto;          /* stop the mobile flex:1 stretching the rail */
    max-width: none;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    text-align: left;
    padding: 11px 14px;
  }
  body.has-sidebar .nav-btn:hover { background: rgba(255, 255, 255, 0.06); }
  body.has-sidebar .nav-btn.active:hover { background: rgba(6, 146, 249, 0.24); }
  body.has-sidebar .nav-icon { font-size: 18px; width: 22px; text-align: center; }
  body.has-sidebar .nav-lbl  { font-size: 14px; }
  body.has-sidebar .nav-sos  { margin-top: auto; border: 1px solid rgba(252, 83, 56, 0.4); background: rgba(252, 83, 56, 0.1); }
  body.has-sidebar .nav-sos:hover { background: rgba(252, 83, 56, 0.18); }
  /* A rail item wraps its own count to the right, rather than trailing the label */
  body.has-sidebar .nav-lbl { flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 8px; }

  /* Content area gets real room */
  .app-shell { max-width: 1080px; padding: 26px 34px 48px; }

  /* Focused, one-thing-at-a-time flows keep a comfortable reading column */
  .focus-col { max-width: 720px; margin-left: auto; margin-right: auto; }

  /* Home hero becomes a horizontal banner */
  .home-hero {
    display: flex;
    align-items: center;
    gap: 24px;
    text-align: left;
    padding: 6px 0 22px;
  }
  .home-hero img { width: 112px; }
  .home-hero h1 { font-size: 30px; margin-top: 0; }

  /* Two-column card grid (explicit ordering) */
  .d-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    align-items: start;
  }
  .d-grid > .card { margin-bottom: 0; }
  .d-grid > .span-2 { grid-column: 1 / -1; }

  /* Real grid instead of ragged masonry columns. `column-count` left one column
     with a single card and a huge void beneath it; a grid keeps rows aligned and
     lets a card claim more width when it deserves it. */
  .d-cols {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    align-items: stretch;    /* equal-height rows: no ragged bottoms or voids */
    grid-auto-flow: dense;   /* small cards backfill beside a spanning one */
  }
  .d-cols > * { margin-bottom: 0; min-width: 0; }

  /* Cards fill their grid cell so every row lines up top AND bottom. */
  .d-cols > .card {
    margin-bottom: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  /* Some grid children are JS-rendered wrappers holding a single card. */
  .d-cols > div:not(.card) > .card {
    margin-bottom: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  .d-cols > .wide { grid-column: span 2; }

  /* Content that should soak up the spare height rather than leave a void */
  .d-cols .bar-chart { flex: 1; min-height: 130px; }
  .d-cols .cal-grid  { align-content: start; }
  /* Trailing helper lines sit at the bottom of a stretched card */
  .d-cols .card-foot { margin-top: auto; padding-top: 12px; }

  /* ---------- Results hero band ----------
     The score ring used to float alone in a sea of empty space. On desktop it
     becomes a proper banner: ring on the left, headline and stats beside it. */
  .result-hero {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 30px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 24px;
    padding: 26px 32px;
    margin-bottom: 16px;
  }
  .result-hero .epoch-overall { padding: 0; text-align: left; }
  .result-hero .overall-score-ring { margin: 0; width: 168px; height: 168px; }
  .result-hero .overall-score-ring svg { width: 168px; height: 168px; }
  .result-hero .overall-big { font-size: 46px; }
  .result-hero .overall-lbl { font-size: 11px; }
  .result-hero-copy h2 { font-size: 27px; margin-bottom: 6px; }

  /* The five domain bars have room to breathe on a wide screen */
  .d-cols .domain-bar-row { margin-bottom: 18px; }
  .d-cols .db-label { width: 150px; min-width: 150px; }
  .d-cols .db-score { font-size: 21px; }

  /* Stop the calendar dictating a very tall row, square cells in a wide column
     get big fast, which is what pushed every other card's content apart. */
  .d-cols .cal-grid { max-width: 360px; }
  .d-cols .cal-cell { font-size: 13px; }
  .result-hero-stats {
    display: flex;
    gap: 10px;
    margin-top: 14px;
    flex-wrap: wrap;
  }
  .result-hero-stats .sc-item { flex: 1; min-width: 108px; margin: 0; }

  /* Bigger, calmer typography in the wide layout */
  .card h2 { font-size: 19px; }
  .mode-card { padding: 24px 18px; }
  .mc-emoji { font-size: 38px; }
}

/* ---------- Large desktop ---------- */
@media (min-width: 1360px) {
  .app-shell { max-width: 1320px; }
  .d-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .d-cols > .wide { grid-column: span 2; }
  .tile-row { grid-template-columns: repeat(4, 1fr); }
  .result-hero { padding: 30px 38px; gap: 38px; }
  .result-hero-copy h2 { font-size: 30px; }
  /* Home: modes stay full-width, wallet + resource share the row below */
  #s-home .d-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #s-home .d-grid > .span-2 { grid-column: 1 / -1; }
  #s-home .d-grid > .card:not(.span-2) { grid-column: span 1; }
  #s-home .d-grid > .card:not(.span-2):first-of-type { grid-column: span 2; }
}

@media (min-width: 1700px) {
  .app-shell { max-width: 1480px; }
}

/* ---------- Sign out: never let it collide with the card above ---------- */
.sign-out-wrap {
  margin-top: 22px;
  padding-top: 4px;
  display: flex;
  justify-content: center;
}
.sign-out-wrap .btn { max-width: 240px; margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Numbered "how it works" steps, shared by the school sign-up and the roster
   upload, so the two onboarding pages read as one flow. */
.step-row { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.step-num {
  width: 30px; height: 30px; min-width: 30px; border-radius: 50%;
  background: rgba(98, 210, 169, .16); border: 1px solid var(--mint); color: var(--mint);
  display: grid; place-items: center; font-weight: 800; font-size: 14px;
}

/* Learner sign-in codes wherever they are shown to staff */
code {
  font-family: 'Fredoka', ui-monospace, monospace;
  font-weight: 700; letter-spacing: 1px;
  background: rgba(98, 210, 169, .13); color: var(--mint);
  padding: 2px 7px; border-radius: 7px; white-space: nowrap;
}
