/* ==========================================================================
   ROCMeta app shell - how the site dresses INSIDE the installed app.

   The owner's verdict on v1 was exact: "resembles as if someone is opening
   the website from the browser". The launcher was an app screen; every page
   after it was the website - marketing header, footer columns, register
   CTAs. This sheet is the answer: when the page runs inside the installed
   app (TWA or installed PWA), the website chrome disappears and the app
   supplies its own - a bottom tab bar, an app-style sign-in, entrance
   motion.

   Loaded on EVERY page and INERT in a normal browser tab: every rule is
   gated on html.is-app, which the detector in roc_head sets PRE-PAINT
   (display-mode standalone, the android-app:// referrer, or the session
   flag). Cache-safe by construction - the HTML and this sheet are identical
   for everyone; only the class differs per device.

   Values carry fallbacks because two base sheets exist (forge.css and
   styles.css) and their custom properties differ.
   ========================================================================== */

/* The tab bar and top bar exist in every page's HTML; outside the app they
   do not exist at all - display:none also removes them from the
   accessibility tree. NOT the hidden attribute: Chrome's UA sheet enforces
   [hidden] at a priority author CSS cannot beat, verified live. */
.app-tabs { display: none; }
.app-top { display: none; }

/* /app-home has no other header, so the top bar is unconditional there -
   a member opening it in a normal browser still gets the mark and the
   account door. */
body.app-home-page .app-top { display: flex; }

/* --- the top bar (self-contained: both base sheets must carry it) ------- */
.app-top {
  align-items: center; justify-content: space-between; gap: .75rem;
  padding: calc(clamp(.35rem, 1.2dvh, .55rem) + env(safe-area-inset-top)) 1rem clamp(.35rem, 1.2dvh, .55rem);
  border-bottom: 1px solid var(--hair, rgba(255, 255, 255, .08));
}
.app-top-mark {
  margin: 0; font: 800 1.05rem/1 var(--f-body, Inter, system-ui, sans-serif);
  letter-spacing: .02em;
}
.app-top-mark b { color: var(--ember-1, #d9a441); }
.app-top-mark span { color: #9a9caa; font-weight: 700; }
.app-top-account {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: clamp(1.9rem, 4.8dvh, 2.35rem); padding: 0 .85rem;
  border: 1px solid var(--hair, rgba(255, 255, 255, .08)); border-radius: 999px;
  color: var(--text-2, #b9bbc6); font: 600 .72rem/1 var(--f-body, Inter, system-ui, sans-serif);
  text-decoration: none;
}
.app-top-dot {
  width: 7px; height: 7px; flex: 0 0 auto; border-radius: 50%;
  background: var(--ok, #6cc48f); box-shadow: 0 0 0 4px rgba(108, 196, 143, .12);
}
/* The Guest chip exists in every page's HTML and shows only on the app's
   sign-in screens (the swap lives in the auth block below). Steel dot:
   a guest is present, not signed in. */
.app-top-guest { display: none; }
.app-top-guest .app-top-dot { background: #9a9caa; box-shadow: 0 0 0 4px rgba(154, 156, 170, .12); }

html.is-app { -webkit-tap-highlight-color: transparent; }
html.is-app body { overscroll-behavior-y: none; }

/* Everything visual applies on handset/tablet widths only: a desktop
   PWA window keeps the normal site - bottom thumb tabs on a 1400px
   window would be a costume, not a fit. */
@media (max-width: 900px) {

  /* The website's chrome is what made the app read as a browser. Gone -
     replaced by the app's own top bar on every screen (the owner's
     consistency rule: the mark left, My Account right, Home included). */
  html.is-app .site-header,
  html.is-app .site-footer { display: none; }
  html.is-app .app-top { display: flex; }
  /* 4.6rem, not the bar's own ~4.05rem: the difference is DESIGN AIR above
     the tab bar. At 4rem the reserve equalled the bar to the pixel and the
     launcher's last card sat visually against it - the owner's "hiding
     almost underneath the nav footer". Rem on purpose, so the air scales
     with the same font setting that scales the bar. */
  html.is-app body { padding-bottom: calc(4.6rem + env(safe-area-inset-bottom)); }

  /* The brand signature at the status-bar edge: a 2px ember hairline over
     every app screen. Small on purpose - it marks the surface as ROCMeta
     without spending a pixel of layout. */
  html.is-app body::before {
    content: ""; position: fixed; top: 0; left: 0; right: 0; height: 2px;
    z-index: 90; pointer-events: none;
    background: linear-gradient(90deg, transparent, #d9a441 28%, #ff7a3c 72%, transparent);
  }

  /* --- the tab bar ------------------------------------------------------ */
  html.is-app .app-tabs {
    display: grid;
    grid-auto-flow: column; grid-auto-columns: 1fr;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
    padding: .3rem max(.4rem, env(safe-area-inset-right))
             calc(.3rem + env(safe-area-inset-bottom))
             max(.4rem, env(safe-area-inset-left));
    background: rgba(14, 15, 19, .94);
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
    border-top: 1px solid var(--hair, rgba(255, 255, 255, .08));
  }
  html.is-app .app-tabs a {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: .22rem;
    min-height: 3.35rem; border-radius: .55rem;
    color: var(--text-3, #7d7f8b); text-decoration: none;
    font: 600 .64rem/1 var(--f-body, Inter, system-ui, sans-serif);
    letter-spacing: .05em; text-transform: uppercase;
  }
  html.is-app .app-tabs a:active { transform: translateY(1px); }
  html.is-app .app-tabs svg { width: 1.35rem; height: 1.35rem; }
  html.is-app .app-tabs a[aria-current] {
    color: var(--ember-1, #d9a441);
    background: rgba(217, 164, 65, .09);
  }
  html.is-app .app-tabs a[aria-current] svg {
    filter: drop-shadow(0 0 7px rgba(217, 164, 65, .5));
  }

  /* Tap feedback on the launcher cards: a press, not a click. */
  html.is-app .ah-tool:active { transform: scale(.98); }

  /* --- sign-in becomes an app screen ------------------------------------ */
  /* No tabs on the auth screens: a login with navigation underneath says
     "website". The card centres in the viewport; margin:auto (not grid
     centring) so a card taller than a small phone stays scrollable.
     :not(.account-shell) EVERYWHERE here - /account reuses .auth-shell with
     THREE stacked sections, and the flex centring built for one card laid
     them out as a squeezed row with the tab bar hidden: the owner's
     "messed up" report, verbatim. The account page is an app page like any
     other - chrome off, tabs on, normal flow. */
  html.is-app body:has(.auth-shell:not(.account-shell)) .app-tabs { display: none; }
  /* The top bar STAYS on the sign-in screens (owner: same header as
     signed in) - with the Guest chip in place of My Account, since an
     account door on a login screen points at a wall. */
  html.is-app body:has(.auth-shell:not(.account-shell)) a.app-top-account { display: none; }
  html.is-app body:has(.auth-shell:not(.account-shell)) .app-top-guest { display: inline-flex; }
  /* The BODY is the flex column and the shell fills what the top bar
     leaves - shell min-height:100dvh ignored the bar above it and forced
     exactly one bar-height of scroll, measured. */
  html.is-app body:has(.auth-shell:not(.account-shell)) {
    padding-bottom: 0; min-height: 100dvh;
    display: flex; flex-direction: column; box-sizing: border-box;
  }
  html.is-app .auth-shell:not(.account-shell) {
    flex: 1; min-height: 0; display: flex; box-sizing: border-box;
    padding-top: .75rem;
    padding-bottom: .7rem;
  }
  /* Top-aligned, not centred: vertical centring parked the card mid-air
     with a blank band under the top bar - the owner's "too much top blank
     space". The card now sits just under the bar; spare height falls
     below the form, where empty space reads as calm instead of absence. */
  html.is-app .auth-shell:not(.account-shell) > .auth-card { margin: .25rem 0 auto; width: 100%; }
  /* The app's sign-in and sign-up fit the screen (owner): the lede
     paragraphs go - "One free account opens all three tools..." is the
     website talking; the app's five cards already said it - and the
     rhythm tightens. A form may still scroll when the keyboard or the
     password guide genuinely needs it: CLIPPING A FORM IS WORSE. */
  html.is-app .auth-shell:not(.account-shell) .auth-lede { display: none; }
  html.is-app .auth-shell:not(.account-shell) .auth-card { padding: .8rem 1rem .85rem; }
  html.is-app .auth-shell:not(.account-shell) .auth-card h1 { font-size: 1.4rem; margin: .1rem 0 .4rem; }
  html.is-app .auth-shell:not(.account-shell) .fld { margin-bottom: .5rem; }
  html.is-app .auth-shell:not(.account-shell) .fld label { margin-bottom: .2rem; }
  html.is-app .auth-shell:not(.account-shell) .auth-links { margin: .45rem 0 0; font-size: .76rem; }
  html.is-app .auth-shell:not(.account-shell) .auth-check { margin: .5rem 0; }
  html.is-app .auth-shell:not(.account-shell) .auth-password-guide { padding: .55rem .65rem; }
  /* The password protocol panel is 235px tall and only matters while the
     password is being typed - measured, it was the whole difference
     between the sign-up fitting the screen and scrolling. In-app it
     appears when the password field takes focus (the keyboard is up and
     the form scrolls naturally then) and stays while it has focus. */
  html.is-app .auth-shell:not(.account-shell) .auth-password-guide { display: none; }
  html.is-app .auth-shell:not(.account-shell) .auth-card:has([data-password-primary]:focus) .auth-password-guide,
  html.is-app .auth-shell:not(.account-shell) .auth-card:has([data-password-confirm]:focus) .auth-password-guide { display: block; }
  html.is-app .auth-shell:not(.account-shell) .auth-alert { padding: .55rem .7rem; margin: 0 0 .55rem; }
  html.is-app .auth-shell:not(.account-shell) .auth-alt { margin-top: .45rem; }

  /* THE AUTH SCREENS ARE PINNED IN PX (the launcher's dvh lesson, third
     verse): rem tracks the phone's font-size setting, and at 1.3x the
     login card measured 113px past the screen - the owner's "still
     scrollable" on a phone whose scale my 100% tests never exercised.
     Heights and control type are px so the screen fits at ANY scale;
     input text stays 16px, the mobile floor. */
  html.is-app .auth-shell:not(.account-shell) .auth-card { padding: 12px 16px 12px; }
  html.is-app .auth-shell:not(.account-shell) .auth-card .eyebrow { font-size: 10.5px; }
  html.is-app .auth-shell:not(.account-shell) .auth-card h1 { font-size: 21px; margin: 2px 0 7px; }
  html.is-app .auth-shell:not(.account-shell) .auth-alert { font-size: 13px; padding: 8px 10px; margin: 0 0 8px; }
  html.is-app .auth-shell:not(.account-shell) .fld { margin-bottom: 8px; }
  html.is-app .auth-shell:not(.account-shell) .fld label { font-size: 12px; line-height: 1.3; margin-bottom: 3px; }
  /* min-height: 0 is load-bearing: forge gives inputs min-height var(--tap)
     (rem), and MIN-HEIGHT BEATS HEIGHT - round 11's lesson, second sighting. */
  html.is-app .auth-shell:not(.account-shell) .fld input { font-size: 16px; height: 40px; min-height: 0; padding-top: 0; padding-bottom: 0; box-sizing: border-box; }
  html.is-app .auth-shell:not(.account-shell) .fld { gap: 4px; }
  html.is-app .auth-shell:not(.account-shell) .auth-card form > .fld { margin-top: 8px; }
  html.is-app .auth-shell:not(.account-shell) .auth-submit { margin-top: 10px; }
  html.is-app .auth-shell:not(.account-shell) .auth-check { font-size: 13px; margin: 7px 0; min-height: 0; }
  html.is-app .auth-shell:not(.account-shell) .btn { min-height: 42px; padding-top: 0; padding-bottom: 0; font-size: 13.5px; }
  html.is-app .auth-shell:not(.account-shell) .auth-alt { margin-top: 8px; gap: 8px; }
  html.is-app .auth-shell:not(.account-shell) .auth-alt-row { margin-top: 8px; gap: 8px; }
  html.is-app .auth-shell:not(.account-shell) .password-toggle { font-size: 12px; }
  html.is-app .auth-shell:not(.account-shell) .auth-password-match { font-size: 12px; line-height: 1.4; }
  html.is-app .auth-shell:not(.account-shell) .fld input { line-height: 20px; }
  /* The top bar joins the px pin app-wide: its rem type grew the bar 16px
     at large font scales, charged against every fixed screen. */
  html.is-app .app-top-mark { font-size: 17px; }
  html.is-app .app-top-account { font-size: 11.5px; min-height: 38px; }
  /* On the account page the chip is the lit tab: you are here. */
  html.is-app body.account-page a.app-top-account {
    color: var(--ember-1, #d9a441); border-color: var(--ember-line, rgba(217, 164, 65, .35));
  }

  /* --- the tools lose their welcome briefing ---------------------------- */
  /* The member-welcome card (the shared Welcome back + 1/2/3 steps briefing
     on Generator, Simulator and Rater) is the website onboarding a visitor
     needs once. An app user tapped a tab to USE the tool - owner's call:
     straight to work. The website keeps the card untouched. */
  html.is-app .section:has(> .member-welcome) { display: none; }
  html.is-app .member-welcome { display: none; }
  /* Hiding the welcome card also hid its Choose my heroes button, and
     forge.css hides the entry card's own CTA once a roster exists
     (body.has-roster .entry-cta) - together the app had NO way into the
     picker, owner-caught. In-app the entry CTA always shows. */
  html.is-app body.has-roster .entry-cta { display: inline-flex; }

  /* The account page's Return to ROCMeta opens the full website - inside
     the app that road is Home's ROCMeta Website card, owner's call. */
  html.is-app .account-return { display: none; }

  /* --- My Account, dressed as the app (owner's #4) ----------------------- */
  /* The page already stacks well on small screens (forge.css's 820/520
     blocks); what it lacked in-app was the launcher's language. The three
     panels take the signature notch the five Home cards wear, the rhythm
     tightens to app spacing, headings tone down to the launcher's scale,
     and the footer stops being a two-column grid with one column hidden
     (Return is display:none here) - Sign out stands alone, centred. */
  html.is-app .auth-shell.account-shell {
    padding-top: .9rem; padding-bottom: .4rem; gap: .7rem;
  }
  html.is-app .account-shell > section {
    border-radius: var(--r-md, 12px);
    clip-path: polygon(12px 0, 100% 0, 100% 100%, 0 100%, 0 12px);
  }
  html.is-app .account-command-card,
  html.is-app .account-roster-panel,
  html.is-app .account-security { padding: 1rem; }
  html.is-app .account-command-head h1 { font-size: 1.5rem; }
  html.is-app .account-roster-head h2,
  html.is-app .account-security-head h2 { font-size: 1.25rem; }
  html.is-app .account-footer-actions {
    display: flex; justify-content: center; padding: .1rem 0 .5rem;
  }
  html.is-app .account-footer-actions form { width: auto; }
  html.is-app .account-footer-actions .btn {
    width: auto; min-height: var(--tap, 2.75rem); padding: 0 2.2rem;
  }

  /* --- motion ----------------------------------------------------------- */
  /* NO entrance animations. They started content at opacity 0 and trusted
     the animation to finish - and a paused or interrupted animation
     (hidden prerender, heavy anchor-jump load: the owner's "Read" bug,
     where a 227-row ranked page arrived VERY messed up) holds the entire
     main invisible or half-faded. Interaction feedback (:active presses,
     haptics) stays; arrival is instant and dependable instead of animated
     and fragile. */

  /* The launcher needs NO extra bottom padding: the body's own tab-bar
     clearance already covers it, and reserving it twice cost 64px of a
     short phone's height - measured, it was the difference between the
     screen fitting and scrolling. */
}

