/* =============================================================================
   login.css — [P5-L3] the login entry's own sheet. GENERATED; do not hand-edit.
   =============================================================================
   WHAT IS NOT HERE, and why that is the point. Every class the drawn markup uses
   (rg-field, rg-field__label, rg-input, rg-button--primary, rg-mono) is already
   defined in /design/export/components.css, which this entry links. The drawn
   frames' own geometry is INLINE in the extracted markup. So this sheet carries
   only what nothing else provides: the entry's page chrome, the host that turns
   a drawn artboard into a page, and the viewport switch between the two drawn
   compositions.

   THE FORBIDDEN OVERRIDE KEYWORD DOES NOT APPEAR IN THIS FILE, and that is not a
   near miss - it is the one rule a surface like this cannot satisfy by layering,
   because @layer never reaches an element-attached declaration. Two measurements
   are what make it hold rather than hope:
     · a sheet that tried to RESIZE a drawn root (inline "height: 780px") WOULD
       need one. This does not try - the host centres each composition at its
       drawn size, which is also what the 1440 artboard draws (width: 100%).
     · the viewport switch sets `display`, and NEITHER drawn root carries an
       inline `display` (measured: both roots' inline declarations are position,
       width, height, background, border, border-radius, overflow). So the rule
       is UNCONTESTED and needs nothing to out-specify.
   css-ratchet reads 0 for this file: no id selectors (selector-max-id: 0), nothing
   above 0,2,0 (selector-max-specificity), no hex, no named colour, no disallowed
   colour function - every value is a var() the design export defines.
   (This paragraph names the keyword obliquely on purpose. Spelling it made the
   contract test's own probe match its explanation - PB-00027, the instrument
   inside its own population. Reword, never loosen the probe.)
   ============================================================================= */
@layer surfaces {
  .glyph-login {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    background: var(--color-page);
    color: var(--color-text);
  }

  /* Each drawn root is full-bleed horizontally, which is what the 1440 artboard
     draws too (width: 100%, a band). Each keeps its drawn height. */
  .glyph-login > [data-glyph-login] {
    width: 100%;
    max-width: 100%;
  }

  /* THE VIEWPORT SWITCH. 768px is the estate's breakpoint, not a new one: it is
     what 6 of the 7 media queries across public/css/surfaces/*.css already use. */
  .glyph-login > [data-glyph-login="mobile"] { display: none; }
  @media (max-width: 768px) {
    .glyph-login > [data-glyph-login="desktop"] { display: none; }
    .glyph-login > [data-glyph-login="mobile"] { display: block; }

    /* =====================================================================
       [MOBILE-VIEWPORT-FIT] The login is LOCKED to the device viewport.
       =====================================================================
       Owner feedback, 2026-08-28, PREVIEW ONLY. The animation is untouched:
       every rule here is box geometry.

       🔴 THE DEFECT, MEASURED BEFORE ANY OF THIS WAS WRITTEN. The drawn root
       carries `height: 760px` INLINE (extracted geometry, R17.1) and the host
       only asked for `min-height: 100dvh`, so on any viewport shorter than
       760px the page SCROLLED and the form ran off the bottom. At 390x664 — a
       real iPhone with its address bar showing — the document measured 760px
       against a 664px viewport: **96px of overflow, and the Sign in button and
       Forgot-password link were BELOW THE FOLD** (card bottom 727 vs viewport
       664). 390x844 happened to fit, which is exactly why this survived: the
       one size everybody tests is the one size that worked.

       WHY `dvh` AND NOT `svh` IS THE PRIMARY. `svh` is the SMALLEST viewport
       (chrome showing) and never changes, so it cannot shrink when the software
       keyboard opens — the form would sit behind the keyboard. `dvh` tracks the
       CURRENT viewport, so with `interactive-widget=resizes-content` on the meta
       the box shrinks with the keyboard and the fields stay on screen. `overflow`
       is hidden and the drawn root is clamped to this box, so the growth/shrink
       of `dvh` as the address bar hides can never produce a scrollbar — which is
       the usual reason people reach for `svh`. All three are declared: the last
       one an engine understands wins.

       ⚠️ `viewport-fit=cover` ON THE META IS PART OF THIS RULE, not decoration.
       Without it iOS letterboxes the page and every `env(safe-area-inset-*)`
       resolves to 0px, so the insets below would silently do nothing and the
       boundary would sit under the notch. Neither half works alone.

       The gutter is a `max()` of the safe-area inset and a comfort floor, so a
       device with no inset still shows the drawn boundary the owner asked to
       keep, and a notched device gets whichever is larger. */
    .glyph-login {
      box-sizing: border-box;
      block-size: 100vh;      /* floor for an engine with neither unit */
      block-size: 100svh;     /* stable smallest viewport */
      block-size: 100dvh;     /* the exact current viewport — wins where supported */
      min-block-size: 0;
      place-items: stretch;
      /* 🔴 AN EXPLICIT TRACK, BECAUSE A DEFINITE CONTAINER IS NOT A DEFINITE ROW.
         Measured after the first attempt did nothing: the host was correctly 664px
         and `place-items: stretch` was correctly applied, and the drawn root still
         read 760px. The implicit grid row is `auto`, so it sized to ITS CONTENT —
         the 760px drawn box — and the item stretched to that 760px ROW rather than
         to the 664px host. A percentage height on the child then resolved against
         760 and changed nothing, which is why the min/max clamp below looked inert
         while being perfectly applied. `minmax(0, 1fr)` makes the row exactly the
         host's content box and lets it shrink below its content, which is the whole
         point of the `0` — a bare `1fr` has an automatic minimum equal to the
         content and would reproduce the bug. */
      grid-template-rows: minmax(0, 1fr);
      grid-template-columns: minmax(0, 1fr);
      overflow: hidden;
      overscroll-behavior: none;
      padding-block-start: max(env(safe-area-inset-top), var(--rogue-space-4));
      padding-block-end: max(env(safe-area-inset-bottom), var(--rogue-space-5));
      padding-inline-start: max(env(safe-area-inset-left), var(--rogue-space-4));
      padding-inline-end: max(env(safe-area-inset-right), var(--rogue-space-4));
    }

    /* The document itself must not scroll either — the host being exactly one
       viewport tall is necessary but not sufficient if anything ever sits
       beside it. Scoped by :has so this sheet still styles nothing but its own
       page; its specificity is (0,1,1), inside the ratchet's 0,2,0 budget. */
    :root:has(> body > .glyph-login),
    body:has(> .glyph-login) {
      block-size: 100%;
      overflow: hidden;
    }

    /* 🔴 min + max, NEVER `block-size`, and that is the whole trick. The drawn
       root's `height: 760px` is an INLINE declaration and an inline declaration
       outranks every layered rule for the SAME property — `@layer` settles
       stylesheet-vs-stylesheet and never reaches an element-attached one. But
       `min-block-size` and `max-block-size` are DIFFERENT properties, and the
       used height is clamped by both whatever the height came from. So the
       drawn box is pinned to exactly the safe-area box without the override
       keyword this sheet is forbidden to use, and without re-typing a byte of
       extracted markup. */
    .glyph-login > [data-glyph-login="mobile"] { block-size: 100%; min-block-size: 0; }
    .glyph-login > [data-glyph-login="mobile"] > * {
      min-block-size: 100%;
      max-block-size: 100%;
    }

    /* THE ANIMATION IS SIZED TO THE SPACE ABOVE THE FORM, not to the whole box.
       The canvas is drawn `inset: 0` and the engine places the mark at 27% of
       the CANVAS height, so shrinking the canvas moves the mark up with it — the
       proportion the drawing specifies is preserved at every size. The subtrahend
       is MEASURED at run time by `public/js/login-boot.js` (a ResizeObserver on
       the drawn form card) and published as `--glyph-login-form-block`; the
       fallback is only for the moments before that first measurement lands.
       Same min/max reasoning as above: the canvas carries `height: 100%` inline. */
    .glyph-login [data-particles] {
      max-block-size: calc(100% - var(--glyph-login-form-block, 264px));
    }
  }
}
