/* ═══════════════════════════════════════════════════════════════════════════
   LIQUID-TOKENS.CSS - the numbers behind the polish layer (liquid.css and
   liquid.js), and the only place any of them is declared.

   What the layer is, in one line: the same Aluma, finished. Floating things
   (menus, popovers, toasts, the sheet behind a dialog, the family bar with
   the page scrolling under it) are frosted glass with a fine rim of light;
   buttons, chips and tabs give under a finger and spring back; menus, sheets
   and toasts arrive softly. Nothing else changes: no colour, no surface, no
   card, no page ground, no type, no spacing, no size and no corner. The
   owner's brief was "refine and add to it", after a louder pass (moving
   blobs, ASCII art, glass cards) was reverted, so every value here was tuned
   against before/after screenshots until the pairs read as the same app.

   Shared by all three apps: index.html (student), parents.html (/family) and
   educators.html (/educators). Every name is --lq-*, so nothing here collides
   with redesign.css (the radius ladder, --press-*, --glass-*), the family
   app's --f-* or the educator app's --e-*. Those are spent, never restated:
   in particular this file declares NO radius (tests/test_one_radius_ladder.py
   keeps one ladder, in redesign.css).

   Load order:
     index.html      BEFORE redesign.css. tests/test_beta_redesign.py forbids
                     any sheet loaded after redesign.css from declaring tokens
                     on the document root; a sheet before it may, and none of
                     these names exist in redesign.css to be overridden.
     parents.html    the first sheet after fonts.css.
     educators.html  the first sheet after fonts.css.

   Two rules keep "reduce motion" honest (the bug class
   tests/test_less_motion_means_less_motion.py was written for):
     1. Motion tokens live on the plain document root ONLY. A theme block
        (html/body[data-theme="dark"]) is MORE specific than the root, so a
        motion token re-declared there would out-rank the zeroing below.
     2. The reduced-motion block is the LAST block in the file, so it wins
        every equal-specificity declaration above it by order.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── motion: curves ─────────────────────────────────────────────────── */
  /* Going down is mechanical and immediate; coming back is elastic. The
     same rule feel.css follows for the student app's press. */
  --lq-ease-press:  cubic-bezier(0.3, 0, 0.2, 1);      /* the finger lands         */
  --lq-ease-spring: cubic-bezier(0.34, 1.36, 0.64, 1); /* one small overshoot back  */
  --lq-ease-out:    cubic-bezier(0.16, 1, 0.3, 1);     /* arrivals: fast, then calm */

  /* ── motion: durations ──────────────────────────────────────────────── */
  --lq-d-press:   110ms;    /* down: at most 120ms, so it is there when the finger is */
  --lq-d-release: 420ms;    /* back up: about four times the press, on the spring     */
  --lq-d-pop:     220ms;    /* a menu or popover opening                              */
  --lq-d-sheet:   340ms;    /* a dialog or bottom sheet arriving                      */
  --lq-d-toast:   380ms;    /* a toast arriving                                       */
  --lq-d-check:   420ms;    /* the "done" check pop and its ring                      */

  /* ── motion: amplitudes ─────────────────────────────────────────────── */
  --lq-press:      0.97;    /* how far a control gives (the student's --press-scale)  */
  --lq-pop-scale:  0.96;    /* a menu starts this size and opens to 1                 */
  --lq-sheet-scale: 0.975;  /* a dialog starts this size                              */
  --lq-rise:       10px;    /* how far a sheet or toast travels in                    */
  --lq-drop:       -6px;    /* a menu drops this far from its button                  */
  --lq-check:      1.22;    /* the check glyph's pop                                  */
  --lq-ring:       1.9;     /* how far the done ring spreads                          */

  /* ── glass (light; the family and educator apps are light-only) ─────── */
  /* backdrop-filter: blur(--lq-blur) saturate(--lq-sat) brightness(--lq-bright).

     The owner's rule is that contrast stays at or above today's on every
     surface, and glass under a word can only ever darken (or, on the dark
     theme, lighten) what is behind that word. So the layer never thins a
     surface that text sits on below what it already was:
       - a surface that was ALREADY glass (the student palette, menus and
         toasts at 76%, the family bar at 86%) keeps its fill exactly, and
         its backdrop is lifted toward the fill before the fill goes on
         (brightness above 1 on light, below 1 on dark, and no extra
         saturation on dark, where saturating a bright accent behind light
         ink measured as a drop), so it can only gain contrast;
       - a surface that was OPAQUE and carries text (family and educator
         menus and toasts) stays opaque under its content and frosts only
         its padding: a bezel of glass around a solid face, the way a
         visionOS panel catches colour at its edge. Every word keeps the
         exact ground it had;
       - an opaque surface whose glass would sit right under its words
         (the educator bar) stays as it is: educators.css made it solid
         because "a see-through bar ghosted the status and the tiles".
     Every one of those was measured when this layer was built: each run of
     text on a frosted surface, its ink against the pixels actually under
     it, before and after, across all three apps and both student themes. */
  --lq-blur:   24px;
  /* The student surfaces that were already glass keep their own radius: a
     wider blur spreads a bright button further under the words on top. */
  --lq-blur-palette: 28px;   /* styles.css: #palette-backdrop .palette */
  --lq-blur-toast:   16px;   /* styles.css: #toast-wrap .toast         */
  --lq-sat:    1.2;     /* the palette's own saturate(1.2), now everywhere */
  --lq-sat-bar: 1.4;    /* the family bar's own saturate(1.4), kept        */
  --lq-bright: 1.06;
  --lq-blur-scrim: 8px;   /* the dimmed page behind a family/educator dialog */
  /* The bezel of a family/educator menu or toast: their own white
     (--f-surface / --e-surface, #fff) at 86%, the family bar's alpha. Its
     face, inside the padding, stays solid --*-surface. */
  --lq-fill-pop:     rgb(255 255 255 / 0.86);
  /* The family bar keeps parents.css's 86% of --f-bg (#f6f8f2). */
  --lq-fill-bar-fam: rgb(246 248 242 / 0.86);
  /* The rim: a lit top edge and a fine inner hairline, drawn as inset
     shadows so no border (and no box) changes. On an opaque white surface it
     is invisible by design; it appears exactly where the glass is tinted. */
  --lq-rim: inset 0 1px 0 rgb(255 255 255 / 0.9), inset 0 0 0 1px rgb(255 255 255 / 0.45);
  --lq-done-ink: rgb(28 106 91 / 0.38);  /* the done ring: the student accent, quiet */
}

/* The student app's dark theme (the only app with one). Colour and glass
   only; NO motion token may appear in this block. */
html[data-theme="dark"],
body[data-theme="dark"] {
  /* On dark glass the guard runs the other way: the backdrop is DIMMED
     before the fill, so light ink on it keeps today's contrast. */
  --lq-bright: 0.86;
  --lq-sat: 1;
  /* The lit top edge only. A light hairline all the way round also ran
     under the last row of the palette where it scrolls out of view, and
     lifted the ground under that half-hidden light ink (measured: 17.7:1
     to 16.3:1). On the dark theme the top edge is the rim. */
  --lq-rim: inset 0 1px 0 rgb(255 255 255 / 0.09);
  --lq-done-ink: rgb(120 216 192 / 0.4);
}

/* A phone gets thinner blur: every px of radius is GPU time per frame, and
   a sheet or bar sits over a page that scrolls under it. */
@media (max-width: 767px) {
  :root { --lq-blur: 16px; --lq-blur-scrim: 6px; }
}

/* LAST, so it wins every root declaration above by order. liquid.css also
   answers reduced motion rule by rule, and liquid.js checks the query live. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --lq-d-press: 0s;  --lq-d-release: 0s;  --lq-d-pop: 0s;
    --lq-d-sheet: 0s;  --lq-d-toast: 0s;    --lq-d-check: 0s;
    --lq-press: 1;     --lq-pop-scale: 1;   --lq-sheet-scale: 1;
    --lq-check: 1;     --lq-ring: 1;
    --lq-rise: 0px;    --lq-drop: 0px;
  }
}
