/* Vahary.Branding — component styles for VaharyLockup / VaharyError.
   Pairs with brand.css (tokens + @font-face). Colors come only from --vahary-* tokens.
   Marks render via CSS mask-image so glyphs inherit the current text color (the "-onecolor"
   currentColor rule) with the aperture punched — no inline SVG, no id collisions — and the
   aperture dot renders VIOLET on top (FD-LOGIN-4: every rendered Vahary wordmark carries the
   violet aperture circle, surviving any text color).
   VaharyAuthShell v2 styles live in vahary-auth-shell.css (0.4.0). */

/* ---- The FocusOnNavigate ring -----------------------------------------------
   DELIBERATELY UNSCOPED, and the one rule in this package that reaches outside its own components.
   All eight Blazor products carry <FocusOnNavigate Selector="h1" />, so the framework puts
   tabindex="-1" on the routed page's <h1> and focuses it on every load for assistive tech. Chrome
   matches :focus-visible on that heading with no keyboard interaction at all and draws its own
   outline:auto 1px box round it — around the oversized product noun on every pre-auth page, on
   first paint, with nothing focusable inside it.

   Branding 0.6.0 scoped the auth shell's own 2px violet ring to interactive elements. That removed
   the PACKAGE's ring and left the UA one, which no scoping can reach — so five products each wrote
   this same rule privately (HQ, Visitor, Uptime, Blueprint, Studio) while three did not (Access,
   Operations, IntegratorOS) and simply show the box. That is the divergence a shared sheet exists
   to prevent, and both HQ and Visitor left notes naming this exact rule as pending upstream.

   It lives HERE, not in vahary-auth-shell.css, and unscoped, for two reasons that are easy to get
   wrong: that sheet is route-gated in Visitor and Blueprint so it would not load on the pages that
   need this; and the ring appears on console headings too, not only inside .vh-shell (measured by
   HQ), so a .vh-shell-scoped rule would leave it there — and four of the five private rules are
   unscoped, so a product deleting one after adopting 0.7.0 would silently bring the box back.

   Costs no keyboard affordance: tabindex="-1" means the element is NOT in the tab order, so nobody
   can land here by choice and lose a ring they needed. Every operable control keeps its ring. */
h1[tabindex="-1"]:focus{outline:none}

/* Accessible name for the lockup (the marks are aria-hidden). */
.vh-visually-hidden{
  position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

/* ---- Lockup ---------------------------------------------------------------- */
.vh-lockup{
  display:inline-flex; align-items:center; gap:.5em;
  font-family:var(--vahary-font-body); line-height:1; white-space:nowrap;
  color:var(--vahary-fg);
}
/* The mask lives on ::before (glyphs in currentColor, aperture punched) so the ::after violet
   dot can render UNMASKED inside the aperture. Masking the element itself would clip the dot
   away with everything else outside the glyphs — that was the pre-0.4.0 shape, which rendered
   the aperture as an empty hole and failed FD-LOGIN-4 (every rendered Vahary wordmark carries
   the VIOLET aperture circle; it must survive any text color, hence a fixed accent token and
   never currentColor). */
.vh-lockup__mark{
  display:inline-block; flex:none; position:relative;
}
.vh-lockup__mark::before{
  content:""; position:absolute; inset:0; background-color:currentColor;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:center; mask-position:center;
  -webkit-mask-size:contain; mask-size:contain;
}
.vh-lockup__mark::after{
  content:""; position:absolute; border-radius:50%;
  background:var(--vahary-accent, #5B21B6); /* violet on both grounds (brand.css maps the ramp) */
}
/* Vahary wordmark ("Vahary") — aspect 4485x784; dot cx368 cy638.8 r56.7 (aperture punch r87.5) */
.vh-lockup__wordmark{
  height:.86em; width:calc(.86em * (4485 / 784));
}
.vh-lockup__wordmark::before{
  -webkit-mask-image:url("vahary-wordmark-onecolor.svg"); mask-image:url("vahary-wordmark-onecolor.svg");
}
.vh-lockup__wordmark::after{
  width:calc(100% * 113.4 / 4485); height:calc(100% * 113.4 / 784);
  left:calc(100% * 311.3 / 4485); top:calc(100% * 582.1 / 784);
}
/* Vahary monogram (the V aperture) — aspect 1x1; dot cx500 cy916.3 r56.7 (aperture punch r135) */
.vh-lockup__monogram{
  height:1.15em; width:1.15em;
}
.vh-lockup__monogram::before{
  -webkit-mask-image:url("vahary-monogram-onecolor.svg"); mask-image:url("vahary-monogram-onecolor.svg");
}
.vh-lockup__monogram::after{
  width:calc(100% * 113.4 / 1000); height:calc(100% * 113.4 / 1000);
  left:calc(100% * 443.3 / 1000); top:calc(100% * 859.6 / 1000);
}
/* Software (prefix): descriptor follows the Vahary wordmark, set in steel. */
.vh-lockup__descriptor{
  font-weight:700; letter-spacing:.005em; color:var(--vahary-steel);
}
/* The hardware "X by Vahary" endorsement lockup (vh-lockup--endorsement / __coined / __endorse)
   was retired by D32 (branded house): hardware is the Vahary V-Series and renders the same
   brand-led lockup as software. */

/* ---- Auth shell ------------------------------------------------------------ */
/* The v1 centered-card styles (.vh-auth / __brand / __card / __footer) were REMOVED in 0.4.0:
   VaharyAuthShell v2 is the Monument/Aperture template system and styles from its own sheet,
   vahary-auth-shell.css (link it alongside brand.css). v1 had zero adopters (login audit). */

/* ---- The full-page state surface (404 / 500 / maintenance) ------------------- */
/* NAMED .vh-errorpage, NOT .vh-error — do not "tidy" this back.
   This is the full-page state SURFACE (VaharyError). vahary-auth-shell.css uses .vh-error for
   something entirely different: the inline error BAND inside a sign-in form. Both sheets ship from
   this same package, and where a host linked both, the two collided IN BOTH DIRECTIONS:
     - this block's min-height:100vh landed on the auth band, inflating it to fill the viewport and
       pushing the sign-in form off the bottom of the page (hit Visitor, Uptime and Access);
     - the band's default display:none landed on this surface, blanking a 404 page whose copy was
       in the DOM (hit Uptime).
   Every structural check passed while both pages were unusable, because the markup, the classes and
   the state toggles were all correct — only the computed box was wrong. The class name was the bug.

   0.7.0 — WHY THE MONUMENT STATE PAGE IS STYLED HERE AND NOT IN vahary-auth-shell.css.
   It was written there first, on the reasoning that every product links that sheet after this one,
   so package-side restyling would win with no product repo changes. That reasoning was established
   by READING App.razor files, and it is wrong: Visitor route-gates the auth shell sheet behind
   IsAuthShellPath (/login, /logout, /auth/refresh, /forgot-password, /reset-password) — and Visitor
   renders VaharyError on /not-found and /Error, neither of which is in that list. The state page
   would have shipped there as an unstyled inline <svg> over a fallback card.
   Visitor's own App.razor comment names this exact hazard for the OTHER sheet: "a route conditional
   on a brand sheet is a silent trap: an auth page that later reaches for VaharyError would render
   with correct markup and no styling."
   So the rule is: VaharyError's CSS lives in the sheet VaharyError's consumers actually load on
   every route, and depends on NOTHING from the route-gated one. The background layers use private
   .vh-sp-* names so that on an auth path, where both sheets load, there is nothing to collide with.

   The .vh-errorpage__* class vocabulary is UNCHANGED from the pre-0.7.0 centred card, deliberately:
   Access, Visitor and Uptime each hand-write <p class="vh-errorpage__code"> as a SIBLING of the
   component for their trace id. Renaming would have silently unstyled all three — the same failure
   mode the 0.6.0 rename above exists to stop. */
.vh-errorpage{
  /* self-contained token block: this surface must render correctly with ONLY brand.css alongside */
  --vh-sp-paper:var(--vahary-paper, #F2F3F1);
  --vh-sp-steel:#8B949C;
  --vh-sp-void:#0D1013;
  --vh-sp-hairline:#252C33;
  --vh-sp-carve:#181E25;
  --vh-sp-accent:var(--vahary-violet, #5B21B6);
  --vh-sp-accent-ink:#FFFFFF;
  --vh-sp-accent-bright:#8B5CF6;
  --vh-sp-accent-rgb:139,92,246;

  position:relative; overflow:clip; color-scheme:dark; box-sizing:border-box;
  min-height:100vh; min-height:100dvh;
  display:flex; flex-direction:column; align-items:flex-start; justify-content:center;
  gap:0; text-align:left;
  padding:clamp(1.6rem,4vh,3rem) clamp(1.6rem,6vw,6rem);
  background:var(--vh-sp-void); color:var(--vh-sp-paper);
  font-family:var(--vahary-font-body, system-ui, sans-serif); line-height:1.6;
}
.vh-errorpage *,.vh-errorpage *::before,.vh-errorpage *::after{box-sizing:border-box}

/* the off-edge V with its aperture dot — the Monument pattern, per FD-LOGIN-1's state-page clause */
.vh-sp-monument{
  position:absolute; z-index:0; pointer-events:none; color:var(--vh-sp-carve);
  height:132vh; width:132vh; right:-34vh; bottom:-4vh;
}
.vh-sp-monument svg{width:100%; height:100%; overflow:visible; display:block}
.vh-sp-dot{fill:var(--vh-sp-accent-bright); filter:drop-shadow(0 0 26px rgba(var(--vh-sp-accent-rgb),.4))}
.vh-sp-groundline{
  position:absolute; left:0; right:0; bottom:9vh; height:1px; z-index:0;
  background:linear-gradient(90deg, transparent 34%, var(--vh-sp-hairline) 58%, transparent 96%);
}

/* ---- content ---- */
.vh-errorpage__brand{
  position:absolute; z-index:1; top:clamp(1.6rem,4vh,3rem); left:clamp(1.6rem,6vw,6rem);
  display:flex; align-items:center; gap:.6rem; color:var(--vh-sp-paper); margin:0; font-size:inherit;
}
.vh-errorpage__brand svg{height:19px; width:auto; display:block}
.vh-errorpage__code,
.vh-errorpage__title,
.vh-errorpage__body,
.vh-errorpage__actions,
.vh-errorpage__meta{position:relative; z-index:1}
.vh-errorpage__code{
  /* the full fallback chain, not a bare var(): this class also lands on the trace-id line the three
     products render OUTSIDE the component, where a missing token would drop the whole declaration */
  font-family:var(--vahary-font-mono, 'IBM Plex Mono', ui-monospace, monospace);
  font-size:.72rem; font-weight:400; letter-spacing:.30em; text-transform:uppercase;
  color:var(--vh-sp-steel, #8B949C); margin:0 0 1.1rem; display:block;
}
.vh-errorpage__title{
  font-family:var(--vahary-font-display, 'Tektur', system-ui, sans-serif);
  font-weight:500; letter-spacing:.01em; font-size:clamp(2.2rem,5vw,3.8rem); line-height:1.04;
  margin:0 0 .5em; max-width:16em;
}
.vh-errorpage__body{max-width:32rem; color:var(--vh-sp-steel); margin:0; font-size:1rem}
.vh-errorpage__actions{margin-top:2.2rem}
.vh-errorpage__actions a{
  display:inline-flex; align-items:center; height:52px; padding:0 1.6rem; border-radius:2px;
  background:var(--vh-sp-accent); color:var(--vh-sp-accent-ink); text-decoration:none;
  font-weight:700; font-size:.98rem;
  transition:filter 150ms, transform 150ms;
}
.vh-errorpage__actions a:hover{filter:brightness(1.15)}
.vh-errorpage__actions a:active{transform:translateY(1px)}
.vh-errorpage a:focus-visible,.vh-errorpage button:focus-visible{
  outline:2px solid var(--vh-sp-accent-bright); outline-offset:3px}
/* the state page's <h1> gets tabindex="-1" + programmatic focus from Blazor's FocusOnNavigate too,
   and the browser draws its own ring on it — see the longer note in vahary-auth-shell.css */
.vh-errorpage [tabindex="-1"]:focus{outline:none}
/* the trace-id line, when a product moves it inside via the Meta slot */
.vh-errorpage__meta{
  margin-top:2.4rem; font-family:var(--vahary-font-mono, 'IBM Plex Mono', ui-monospace, monospace);
  font-size:.64rem; letter-spacing:.16em; text-transform:uppercase; color:#3B434B;
}
.vh-errorpage__meta code{font-family:inherit; color:var(--vh-sp-steel)}
@media (max-width:760px){
  .vh-errorpage{overflow:auto}
  .vh-errorpage__title{font-size:clamp(2rem,9vw,2.6rem)}
  .vh-sp-monument{height:104vh; width:104vh; right:-46vh; bottom:-2vh; opacity:.85}
}
