/* ── Translucent iOS status bar: app-wide consequences ───────────
   The shells now carry `viewport-fit=cover` and
   `apple-mobile-web-app-status-bar-style: black-translucent`, so the web
   view extends *under* the status bar and the page owns those pixels.
   This is the only mechanism on iOS that puts page content up there:
   manifest `theme_color` and <meta name="theme-color"> were both tried on
   a device and moved nothing, and the legacy status-bar-style meta offers
   only white, black or translucent — no arbitrary colour.

   Two costs come with it and are paid for here.

   1. In-flow content would start under the notch. #page-container is the
      shell's wrapper around #root (`margin: 0 auto; width: 100%` and
      nothing else), so padding it once puts every ordinary screen back
      where it was.

   2. black-translucent forces the status bar glyphs to WHITE on every
      screen. On this app's white surfaces they would be invisible, so the
      strip gets painted. #c94e13 rather than the lighter #e85913 because
      white measures 4.58:1 on it — over the 4.5 line — where the lighter
      orange is only 3.58:1.

   Anything position:fixed is deliberately NOT moved by the padding:
   modals, backdrops, #page-loader and .block-mode-fullscreen are meant to
   cover the whole screen, status bar included. Only the two fixed things
   that carry content at the very top are inset, at the bottom. */

:root {
  --safe-top: env(safe-area-inset-top, 0px);
}

/* NOT on the auth screen. This padding makes the document taller than the
   viewport by the inset (933 vs 874 on a 16 Pro), which is fine for the
   ordinary screens — they scroll anyway, and the content genuinely starts
   lower. But the auth screen never scrolled: .auth-brand-page is
   position:fixed over the whole viewport, so the extra height gave iOS a
   59px scroll it had nowhere to put. The fixed page rode up with the
   layout viewport and left the body background showing as a band under
   the footer artwork — "everything came up".

   The auth screen does not need it either way: being fixed, it is exempt
   from container padding, and it paints its own inset with the hero and
   the blur band. */
body:not(:has(.auth-brand-page)) #page-container {
  padding-top: var(--safe-top);
}

/* ── The strip: a flat colour per screen, matched to what is below ──
   No blur and no darkening. The darkening filter that was here adapted to
   every screen automatically, but `brightness(.45)` on an app whose every
   top surface is light (white, #f0f0f5, #f4f4f4, #f8f9fa, #fff5ef,
   #ddf3ff) produced a heavy slate band on all of them — worse than the
   flat orange it replaced. Matching each screen by hand, the way the auth
   screen is matched, is the only thing that actually disappears.

   The strip has to be opaque on any screen whose top chrome is not fixed.
   Under `viewport-fit=cover` the page scrolls *through* y=0..inset, so
   without something covering that band the content passes behind the
   clock as you scroll. Screens with the shared `.fixed` header are
   already covered by its own white (see below); the rest need this.

   NOTE ON LEGIBILITY: `black-translucent` renders the status bar glyphs
   white. On these light fills they will only be readable if iOS adapts
   the glyph colour to the content. If it does not, the clock disappears
   on every screen here and the only fix is dropping black-translucent
   app-wide, which also drops the photograph behind the bar on login.
   This cannot be tested without a device. */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--safe-top);
  z-index: 99999;
  pointer-events: none;
  /* Default: the white of the shared header and of most screens. */
  background: #fff;
}

/* Start screen — the top of its hero, `BG.jpg`, is near-flat #f4dab7
   (spread 6-9 across the first 15% of rows), so a flat fill matches it
   exactly. `alt="Hero"` is unique to FirstScreen, and that screen has no
   fixed header, so without this its hero scrolls behind the glyphs. */
body:has(img[alt="Hero"])::before {
  background: #f4dab7;
}

/* Home — the header band's own colour. `homeV1headerBG.avif` is a single
   flat #ddf3ff, and the header is in-flow, so it scrolls away and the
   strip has to keep holding the colour on its own. */
body:has(div[style*="homeV1headerBG"])::before {
  background: #ddf3ff;
}

/* The auth screen paints that band itself — the photograph runs up behind
   the glyphs with its own blur and scrim — so the flat fill must get out
   of the way, or it would cover the photo with a white slab. Only while
   the hero is actually there: with the keyboard open the hero is clipped
   to zero height and the cream form is at the top, so the fill is wanted
   again (and .auth-brand-page.keyboard-open takes its own padding-top).
   .auth-brand-page is position:fixed, so it is already exempt from the
   #page-container inset above. */
body:has(.auth-brand-page:not(.keyboard-open))::before {
  display: none;
}

/* The two fixed elements that carry content at the very top rather than
   simply covering the screen. */
#sidebar {
  padding-top: var(--safe-top);
}
.close-modal-header {
  top: var(--safe-top);
}

/* Insurance. If any sliver of the document canvas is ever exposed on the
   auth screen — a rubber-band overscroll, a keyboard transition — it
   should be the auth surface rather than the app's #f8f9fa grey, which is
   what made the band above read as broken rather than as blank space. */
body:has(.auth-brand-page) {
  background-color: #fff5ef;
}

/* ── Let the home header's own colour run under the strip ────────
   The strip darkens whatever is beneath it, so what is beneath it
   decides whether it reads as part of the screen. On the home page the
   container padding was putting the body's white there, so the strip came
   out grey above a light blue header — better than a flat orange slab,
   but still a band of its own.

   HomeV1 paints that header with `homeV1headerBG.avif` as an inline
   background-image, and the asset is a single flat colour — #ddf3ff,
   780x342 with zero variation on any row — so there is nothing to
   misalign by moving it. Pull the box up by the inset and give the same
   amount back as padding: the background now paints from y=0 while the
   logo, address row, pills and search box stay exactly where they were,
   and the document height is unchanged (the negative margin and the
   padding cancel).

   Darkened, #ddf3ff lands near luminance 0.148 — white glyphs measure
   about 5.3:1, comfortably over 4.5, and the strip is a deeper shade of
   the header rather than a separate colour.

   The attribute selector is the stable hook: the div carries no class,
   and the background-image is set inline only when the categories have
   loaded. While they are still loading it is `none`, the selector does
   not match, and the strip falls back to darkening whatever is there —
   which is correct, because there is no header colour to continue yet.
   `!important` is needed because the inline style also sets paddingTop. */
div[style*="homeV1headerBG"] {
  margin-top: calc(-1 * var(--safe-top, 0px));
  padding-top: calc(10px + var(--safe-top, 0px)) !important;
}

/* ── The shared page header must clear the notch ─────────────────
   `BackWithSearch` is the app's standard header — back button, title,
   search — and it is rendered by 56 components. Its root is
   `col-12 p-0 fixed`, and `.fixed` resolves to `position: fixed; top: 0`
   (`position` from custom.css, `top` from main.css), so under
   `viewport-fit=cover` it sits *under* the status bar on every one of
   those screens: on /categories the back arrow and "Shop By Category"
   were measured at y=0..53, entirely inside a 59px inset.

   The padding goes on `.fixed > .block`, not on `.fixed` itself. The
   root is transparent — the white belongs to the `.block` child — so
   padding the root would open a transparent gap that the page's own
   content scrolls through underneath, directly behind the glyphs.
   Padding the white child extends the header's own surface up instead,
   which both clears the glyphs and masks whatever is scrolling past.

   `.fixed > .block` is 0,2,0 so it beats `.block`'s own rules without
   `!important`; `p-0` sits on a grandchild and is not in the way. */
.fixed > .block {
  padding-top: var(--safe-top);
}
