/* ============================================================
   Tilli Measures — shared design system
   Bright brand identity (per image 1): Montserrat + Quicksand,
   green / pink / cyan / yellow rail, flower band.
   ============================================================ */

:root {
  /* Brand core */
  --green-500: #56C02B;
  --green-600: #49A524;
  --green-700: #348C11;
  --lime-400: #9BDE1D;
  --pink-400: #E866B0;
  --pink-600: #E91E8C;
  --cyan-500: #26BDE2;
  --cyan-700: #1B7F99;
  --yellow-500: #FCC30B;
  --orange-500: #F99B1C;

  /* Ink */
  --ink-900: #141414;
  --ink-700: #474747;
  --ink-600: #545454;
  --ink-450: #5B6170;
  --ink-300: #9AA3AF;

  /* Surfaces & lines */
  --white: #FFFFFF;
  --line-200: #ECEEF2;
  --surface-100: #F8F9FB;

  /* Washes */
  --wash-yellow: #FFF6A8;
  --wash-cyan: #D9F5FF;
  --wash-green: #F1FFEC;
  --wash-pink: #FFF6FB;

  --radius-card: 24px;
  --radius-pill: 999px;
  --ease: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: #fff;
  font-family: 'Montserrat', system-ui, sans-serif;
  color: var(--ink-900);
}

a { color: var(--cyan-500); }
a:hover { color: var(--cyan-700); }

/* Headings use Quicksand; body + supporting text use Montserrat (set on body above) */
h1, h2, h3, h4, h5, h6 { font-family: 'Quicksand', sans-serif; }

/* ---- Brand vertical rail (left edge) ---- */
.brand-rail {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: clamp(8px, 1vw, 19px);
  display: flex;
  flex-direction: column;
  z-index: 40;
}
.brand-rail span:first-child { flex: 1; background: var(--green-500); }
.brand-rail .seg { height: 64px; }
.brand-rail .seg.pink { background: var(--pink-400); }
.brand-rail .seg.cyan { background: var(--cyan-500); }
.brand-rail .seg.yellow { background: var(--yellow-500); }

/* ---- Wordmark lockup ---- */
.lockup { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.lockup img { height: clamp(22px, 2.4vw, 30px); width: auto; display: block; }
.lockup .divider { width: 1px; height: 20px; background: var(--line-200); }
.lockup .measures {
  font-weight: 700;
  font-size: clamp(11px, 1.1vw, 13px);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--cyan-500);
}

/* ---- Buttons ---- */
.btn {
  border: none;
  cursor: pointer;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  border-radius: var(--radius-pill);
  transition: transform .2s var(--ease), background .2s, border-color .2s, color .2s;
}
.btn:active { transform: scale(.98); }
.btn-primary {
  color: #fff;
  background: var(--green-500);
  font-size: clamp(15px, 1.7vw, 19px);
  padding: 16px 44px;
}
.btn-primary:hover { background: var(--green-600); }
.btn-primary.block { width: 100%; padding: 15px; font-size: 16px; }
.btn-primary:disabled { background: #DDE3DB; cursor: not-allowed; }

.btn-ghost {
  background: #fff;
  border: 1px solid var(--line-200);
  color: var(--ink-600);
  border-radius: var(--radius-pill);
  padding: 8px 14px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color .2s, color .2s;
}
.btn-ghost:hover { border-color: var(--cyan-500); color: var(--cyan-500); }

/* ---- Focus ring ---- */
.focus:focus-visible { outline: 3px solid var(--cyan-500); outline-offset: 3px; }

/* ---- Form fields ---- */
.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 12.5px;
  color: var(--ink-700);
}
.input, .select {
  border: 1px solid var(--line-200);
  background: #fff;
  outline: none;
  font-family: 'Montserrat', sans-serif;
  font-weight: 600;
  font-size: 15px;
  color: var(--ink-900);
  padding: 13px 15px;
  border-radius: 8px;
  width: 100%;
}
.input:focus, .select:focus { border-color: var(--cyan-500); }
.input.err { border-color: var(--orange-500); }
.select { padding-right: 36px; appearance: none; cursor: pointer; }
.select-wrap { position: relative; display: block; }
.select-wrap::after {
  content: '\25BE';
  position: absolute; right: 14px; top: 50%;
  transform: translateY(-50%);
  color: var(--ink-300); font-size: 12px; pointer-events: none;
}

/* ---- School / grade pill ---- */
.pill-info {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--wash-cyan);
  border-radius: var(--radius-pill);
  padding: 7px 14px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700; font-size: 12.5px;
  color: var(--cyan-700);
}

/* ---- Animations ---- */
@keyframes swayA { from { transform: rotate(-2.2deg); } to { transform: rotate(2.6deg); } }
@keyframes swayB { from { transform: rotate(2.4deg); } to { transform: rotate(-2deg); } }
@keyframes swayC { from { transform: rotate(-1.4deg); } to { transform: rotate(1.6deg); } }
@keyframes tmRise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes tmSpin { to { transform: rotate(360deg); } }
@keyframes tmShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); } 40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); } 80% { transform: translateX(3px); }
}
/* .tm-rise entrance fade is intentionally a no-op — fade-in animations were
   removed site-wide (they replayed on re-render). The class + @keyframes
   tmRise are kept so a fade can be opted back in per-screen when asked. */
.tm-rise { animation: none; }
.tm-shake { animation: tmShake .4s ease; }
.tm-sway { transform-box: fill-box; transform-origin: 50% 100%; }
@media (prefers-reduced-motion: reduce) {
  .tm-sway, .tm-rise { animation: none !important; }
}

/* ---- Screen transitions (View Transitions API) ----
   Both dashboards swap a screen by rewriting innerHTML; startViewTransition()
   (in teacher-dashboard.js render() and parent.html render()) cross-fades the
   old screen into the new one. Persistent chrome — the side rail, header chips,
   bottom nav, and the parent top bar — carry their own view-transition-name so
   they hold still while only the main content fades + gently zooms. */
.dash-side      { view-transition-name: dash-side; }
.dash-header    { view-transition-name: dash-header; }
.dash-bottomnav { view-transition-name: dash-bottomnav; }

@keyframes tmVtIn  { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: scale(1); } }
@keyframes tmVtOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(1.012); } }

/* The main content lives in the default "root" group (always viewport-sized,
   so it never distorts). Old fades out quickly, new fades + zooms up into place. */
::view-transition-old(root) { animation: tmVtOut .18s var(--ease) both; }
::view-transition-new(root) { animation: tmVtIn  .34s var(--ease) both; }

/* Pinned chrome: hold in place (or gently morph if it changed) — never fade. */
::view-transition-group(dash-side),
::view-transition-group(dash-header),
::view-transition-group(dash-bottomnav),
::view-transition-group(parent-top) { animation-duration: .28s; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ---- Ask Tilli "thinking" bubble ---- */
.ask-typing { display: inline-flex; align-items: center; gap: 5px; }
.ask-typing span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--green-500, #56C02B);
  opacity: .35; animation: tmTypingDot 1s var(--ease) infinite;
}
.ask-typing span:nth-child(2) { animation-delay: .16s; }
.ask-typing span:nth-child(3) { animation-delay: .32s; }
@keyframes tmTypingDot {
  0%, 60%, 100% { opacity: .3; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* ---- Skeleton shimmer (reusable) ---- */
.skeleton {
  position: relative; overflow: hidden;
  background: var(--surface-100, #f1f1f0); border-radius: 10px;
}
.skeleton::after {
  content: ''; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.6), transparent);
  animation: tmShimmer 1.2s infinite;
}
@keyframes tmShimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .ask-typing span, .skeleton::after { animation: none !important; }
}

/* ---- Spinner ---- */
.spinner {
  width: 44px; height: 44px; border-radius: 50%;
  border: 4px solid var(--line-200); border-top-color: var(--cyan-500);
  animation: tmSpin .8s linear infinite;
}

/* ---- Overlay / dialog ---- */
.overlay {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(20, 20, 20, .42);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.dialog {
  position: relative;
  width: 100%; max-width: 440px;
  max-height: calc(100svh - 40px); overflow-y: auto;
  background: #fff;
  border: 2px solid var(--cyan-500);
  border-radius: var(--radius-card);
  padding: 32px 30px;
}
/* Dialog step transitions — the backdrop stays put while cards slide.
   Forward: old exits left, new enters from the right. Back: reversed. */
@keyframes tmSlideInRight  { from { transform: translateX(120%);  } to { transform: translateX(0); } }
@keyframes tmSlideOutLeft  { from { transform: translateX(0);     } to { transform: translateX(-120%); } }
@keyframes tmSlideInLeft   { from { transform: translateX(-120%); } to { transform: translateX(0); } }
@keyframes tmSlideOutRight { from { transform: translateX(0);     } to { transform: translateX(120%); } }
.dlg-in-right  { animation: tmSlideInRight  .30s var(--ease) both; }
.dlg-out-left  { animation: tmSlideOutLeft  .30s var(--ease) both; }
.dlg-in-left   { animation: tmSlideInLeft   .30s var(--ease) both; }
.dlg-out-right { animation: tmSlideOutRight  .30s var(--ease) both; }
@media (prefers-reduced-motion: reduce) {
  .dlg-in-right, .dlg-out-left, .dlg-in-left, .dlg-out-right { animation-duration: .01ms; }
}
.sheet {
  position: fixed; inset: 0; z-index: 50;
  background: #fff; overflow-y: auto;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(24px, 5vh, 48px) clamp(24px, 5vw, 48px);
}
.dialog-close {
  position: absolute; top: 12px; right: 16px;
  background: none; border: none; color: var(--ink-300);
  font-size: 24px; line-height: 1; cursor: pointer;
}

/* ---- Add-child "getting the notepad" loading screen ----
   All positions/sizes are driven by CSS custom properties set inline on
   .pencil-load-wrap (defaults below are the fallbacks). Tune them live via
   the on-screen panel. */
.pencil-load-wrap {
  --pencil-size: 165px;
  --pencil-gap: 47px;
  --pencil-x: 0px;
  --pencil-y: 200px;
  --bob-altitude: 31px;
  --bob-speed: .66s;
  --msg-size: 20px;
  --msg-gap: 36px;
  --msg-x: 0px;
  --msg-y: 200px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
.pencil-loader {
  display: flex; align-items: flex-end;
  gap: var(--pencil-gap);
  height: calc(var(--pencil-size) + var(--bob-altitude));
  transform: translate(var(--pencil-x), var(--pencil-y));
}
.pencil-loader .pencil {
  height: var(--pencil-size); width: auto; display: block;
  user-select: none; -webkit-user-drag: none;
  will-change: transform;
  animation: pencilBob var(--bob-speed) infinite both;
}
/* Staggered starts make a lively travelling bob rather than one flat sine. */
.pencil-loader .pencil-1 { animation-delay: calc(var(--bob-speed) * -0.00); }
.pencil-loader .pencil-2 { animation-delay: calc(var(--bob-speed) * -0.16); }
.pencil-loader .pencil-3 { animation-delay: calc(var(--bob-speed) * -0.32); }
/* Ease-out up, ease-in down = a gravity-like hop, not a smooth sinusoid. */
@keyframes pencilBob {
  0%   { transform: translateY(0);                                 animation-timing-function: cubic-bezier(.3,.7,.2,1); }
  42%  { transform: translateY(calc(-1 * var(--bob-altitude)));    animation-timing-function: cubic-bezier(.7,0,.7,.3); }
  84%  { transform: translateY(0); }
  100% { transform: translateY(0); }
}
.pencil-load-msg {
  font-family: 'Montserrat', sans-serif; font-weight: 600;
  font-size: var(--msg-size); color: var(--ink-600);
  margin: var(--msg-gap) 0 0; max-width: 30ch; line-height: 1.5;
  transform: translate(var(--msg-x), var(--msg-y));
}
@media (prefers-reduced-motion: reduce) {
  .pencil-loader .pencil { animation: none; }
}
.dialog-back {
  position: absolute; top: 16px; left: 16px;
}

.hidden { display: none !important; }

/* ============================================================
   Mobile-first refinements — portrait phones (≤ 640px)
   Base styles above are fluid and already scale down; these
   tighten spacing, enlarge tap targets, and slim overlays so
   the phone view feels designed, not just shrunk. Desktop is
   untouched.
   ============================================================ */
@media (max-width: 640px) {
  .btn-primary { padding: 14px 30px; font-size: 16px; }

  .overlay { padding: 14px; }
  .dialog { padding: 26px 20px; border-radius: 20px; }
  .sheet { padding: 28px 20px; align-items: flex-start; }

  .lockup { gap: 10px; }
  .lockup .divider { height: 18px; }

  /* Hide the decorative brand rail on mobile across all screens */
  .brand-rail { display: none; }
}
