/* =============================================================================
   app-backdrop.css -- the bookshelf backdrop, site-wide
   public/assets/css/app-backdrop.css

   2026-09-16 (Joe: "I recently added a background image to the landing page.
   I would like now to implement it site wide, the same image").

   The same image and the same technique as landing_v2.css:115-146, kept in a
   file of its own rather than copied into each shell's stylesheet. Four shells
   load it today; if the treatment ever changes, it changes once.

   LOADED BY (link it LAST, after the shell's own stylesheet -- see WHY below):
     public/student/partials/header.php    student shell
     public/teacher/mobile.php             teacher shell
     public/institution/mobile.php         school-admin shell
     public/admin/dashboard.php            platform-admin shell  (live)
     public/admin/dashboard2.php           platform-admin shell  (local variant)

   DELIBERATELY NOT LOADED BY public/activities/ -- the 21 activity runners.
   Those are work surfaces: a student reading a gap-fill, matching IPA symbols,
   or listening and typing. A photograph behind exercise text is where
   legibility complaints come from, and a runner fills the screen anyway, so
   there is nothing to see for the cost. If that is ever revisited, revisit it
   as a deliberate decision rather than by adding a link tag.

   TO REVERT: remove the <link> tags. Nothing else in the app depends on this
   file, and every shell's own background is left intact underneath (see below).

   -----------------------------------------------------------------------------
   THE WHOLE TRICK: CLEAR `html`, AND ONLY `html`
   -----------------------------------------------------------------------------
   Every app shell paints an opaque page background on BOTH elements:

     student_shell.css:82   html,body{ ... background:#080d18; ... }
     mobile.css:1005        html, body { background: var(--bg); }        (teacher + institution)
     dashboard.css:80       html, body { background: var(--theme-bg); }  (admin)
     admin.css:8            body.admin-dashboard { background: linear-gradient(...) }

   Left alone, the backdrop is completely invisible. It took an isolated test
   to find out why, and the obvious explanation is the wrong one.

   It is NOT that a background on `html` outranks a negative z-index. Tested
   directly, 2026-09-16, two iframes side by side, a red `body::before{z-index:-2}`
   against a green background: the red won in BOTH cases -- whether the green
   was on `html` or on `body`. A -2 layer paints above either background.

   What actually hides it is root background PROPAGATION:

     * `html` has a background  -> that becomes the canvas, and `body`'s own
       background then paints as an ORDINARY BOX BACKGROUND, which sits at a
       later step than negative z-index. Body's colour covers the photo.

     * `html` has NO background -> `body`'s background is propagated to the
       canvas instead, painted below everything, and body's box paints nothing.
       The photo shows.

   So the fix is one declaration, on `html`. `body` is deliberately left alone,
   and that is a feature rather than an omission: each shell's own colour lands
   on the canvas and becomes the fallback the photo sits on -- correct while
   the image loads, correct if it ever 404s, and correct per shell without this
   file needing to know that admin's is a gradient and the student one is flat
   #080d18.

   This also explains the landing page, which was visible from the start and
   misread as a curiosity: landing_v2.css never gives `html` a background.

   The <link> must still come AFTER the shell's own stylesheet -- same
   specificity (one element selector), so source order is what decides.
   ============================================================================= */

:root {
  /* Scrim over the photo. Deliberately HEAVIER than the landing page's
     0.46-0.62 pair: the landing page is a few short marketing blocks, whereas
     these shells carry dense running text, tables, IPA and student work. Tune
     these two values rather than editing the gradient below. */
  --app-backdrop-scrim-top: rgba(11,14,26,0.74);
  --app-backdrop-scrim-bottom: rgba(11,14,26,0.86);
}

/* The one declaration that matters. See the note above for why `body` is
   deliberately NOT touched. */
html { background: transparent; }

body::before,
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
}

body::before {
  z-index: -2;
  /* No background-color here on purpose: the shell's own body colour is now on
     the canvas underneath (see the header note), so it already serves as the
     loading/404 fallback. A colour here would cover it and throw that away. */
  /* Plain url() FIRST as the fallback -- browsers without image-set()/type()
     support (Safari < 17, older Chromium) fail to parse the next declaration
     and keep this one. Do not reorder these two lines.
     '../images/' because this file lives in assets/css/, one level down from
     the landing page's copy which resolves from public/. */
  background-image: url('../images/bookshelf-bg-1920.jpg');
  background-image: image-set(
    url('../images/bookshelf-bg-1920.webp') type('image/webp'),
    url('../images/bookshelf-bg-1920.jpg')  type('image/jpeg'));
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}

body::after {
  z-index: -1;
  background: linear-gradient(180deg,
    var(--app-backdrop-scrim-top) 0%,
    var(--app-backdrop-scrim-bottom) 100%);
}

/* -----------------------------------------------------------------------------
   LIGHT THEME: no backdrop.
   -----------------------------------------------------------------------------
   The image is a dark, warm photograph. Under [data-theme="light"] the page is
   #eef2f7 -> #e4eaf4 with translucent near-white panels, and a dark photo
   behind those drops text contrast to somewhere it has no business being in an
   app used by children. Contrast is not a taste question.

   `display:none` rather than a lighter scrim: a light wash over a dark photo
   reads as muddy, and it would still be a contrast risk. Better to not have it.

   THERE ARE TWO THEME MECHANISMS IN THIS CODEBASE and both must be matched:

     data-theme="light"  attribute  -- tokens.css:268, defines --body-bg.
                                       Set on <body> per tokens.css:4, and on
                                       <html> too by the inline boot script in
                                       includes/header.php, before first paint.
     body.theme-light    CLASS      -- dashboard.css:61, defines --theme-bg.
                                       The admin shell themes this way and does
                                       NOT use the attribute at all.

   Matching only one leaves the photo showing on whichever shell uses the
   other. dashboard.css contains zero `data-theme` selectors; student_shell.css
   and mobile.css contain zero theme rules of any kind, so those three shells
   are dark-only today regardless.

   NOTHING NEEDS RESTORING. Hiding the two layers is the entire light-theme
   handling, because `body`'s background was never touched -- it simply
   propagates to the canvas, exactly as it did before this file existed. The
   page returns to its previous appearance with no value restated anywhere.

   An earlier draft tried `background: revert` to put `html`'s colour back.
   That is wrong twice over: `revert` rolls back to the USER-AGENT origin, not
   to an earlier author rule, so it yields transparent rather than the shell's
   gradient (verified -- computed html background came back `none`); and
   restoring html is unnecessary anyway, since a transparent html with a
   painted body gives an identical canvas.
   -------------------------------------------------------------------------- */
html[data-theme="light"] body::before,
html[data-theme="light"] body::after,
body[data-theme="light"]::before,
body[data-theme="light"]::after,
body.theme-light::before,
body.theme-light::after { display: none; }

/* -----------------------------------------------------------------------------
   Phones: the 1280 asset. 133 KB rather than 242 KB, and this is exactly where
   that saving matters. Same breakpoint and the same fallback ordering as
   landing_v2.css:1336-1341.
   -------------------------------------------------------------------------- */
@media (max-width: 780px) {
  body::before {
    background-image: url('../images/bookshelf-bg-1280.jpg');
    background-image: image-set(
      url('../images/bookshelf-bg-1280.webp') type('image/webp'),
      url('../images/bookshelf-bg-1280.jpg')  type('image/jpeg'));
  }
}

/* Never print the backdrop: it wastes ink, and certificates and reports are
   the things people print here. */
@media print {
  body::before,
  body::after { display: none; }
  html, body { background: #fff; }
}
