/* ============================================================
   Handshake v2 — brand lockup

   One component for every place the logo appears. Before this, three surfaces
   each rolled their own: the lander paired the mark with the literal word
   "Handshake" in body type, admin did the same in a div, and only the workspace
   used the drawn wordmark — from a different asset path than the other two.

   Sizes are in `em` so a single font-size on the lockup scales the mark and the
   wordmark together and they can never drift out of proportion. Clear space is
   the gap, set to a quarter of the mark height per the brand guide.

   Which colour variant goes on which surface is documented and MEASURED in the
   admin brand guide (/style-guide.html#brand). The short version: the H in every
   mark is a transparent knockout, so it shows whatever is behind the mark —
   the knockout file needs a dark backing, and light surfaces need a duo file.
   ============================================================ */

/* The proportions are TOKENS — --hs-lockup-* in hs-tokens.css, generated from
   tokens/primitives.json. They are not declared here, and they must not be
   re-declared anywhere else: every literal copy of "1.35em / 0.9em" is a fork
   waiting to drift, and this repo already grew four different mark-to-word
   ratios that way (1.0 on the workspace link-error card, 1.57 on the mobile
   topbar, 2.0 in the portal rail, 3.11 in the brand guide itself).

   They resolve at the DS root, not on .hs-lockup, because surfaces that
   predate the component style their own container (.v2-site-nav__brand,
   .hs-adm-brand) and never pick up the class — scoped to .hs-lockup the vars
   resolved to nothing there, the size declarations became invalid at
   computed-value time, and the mark fell back to its natural 168px. Root
   defaults cannot fail that way.

   Why 1.5 and not something else is argued in the token's own $comment. */

.hs-lockup {
  display: inline-flex;
  align-items: center;
  gap: var(--hs-lockup-gap);
  font-size: var(--hs-lockup-size-base);
  line-height: 1;
  color: inherit;
  text-decoration: none;
  /* handshake.css paints an aqua border-bottom on every `a` — chrome lockups
     are links for navigation, not body hyperlinks, so drop that treatment. */
  border-bottom: none;
}

/* Workspace rail / mobile topbar still use the pre-component class names.
   Match the handshake.css chrome exception so those `<a>`s lose the aqua rule
   even if this sheet loads first. */
:is(.surface-user, .surface-admin) a:is(.hs-lockup, .hs-portal-brand, .ws-mobile-topbar__brand) {
  border-bottom: none;
  color: inherit;
}

a.hs-lockup:hover,
:is(.surface-user, .surface-admin) a:is(.hs-lockup, .hs-portal-brand, .ws-mobile-topbar__brand):hover {
  opacity: 1;
}

.hs-lockup__mark {
  flex: none;
  /* the mark is a disc, so height and width track together */
  height: var(--hs-lockup-mark);
  width: var(--hs-lockup-mark);
  display: block;
}

.hs-lockup__word {
  flex: none;
  height: var(--hs-lockup-word);
  width: auto;
  display: block;
  /* Every wordmark file is 160x23. State that ratio here so `width: auto`
     resolves before the SVG decodes — without it the image is 0px wide on the
     first frame, the lockup snaps sideways when the file lands, and Chrome
     paints the alt text in the collapsed box while it waits. The admin sidebar
     is the place that showed: it paints pre-decode on in-session navigation. */
  aspect-ratio: 160 / 23;
}

/* Mark-only, for square or very narrow slots — favicons, avatars, app icons.
   Never a nested shape: the mark fills its frame on one flat colour. */
.hs-lockup--mark-only .hs-lockup__word {
  display: none;
}

.hs-lockup--sm {
  font-size: var(--hs-lockup-size-sm);
}

.hs-lockup--lg {
  font-size: var(--hs-lockup-size-lg);
}

/* ---- Adopted lockups --------------------------------------------------
   Seven surfaces drew the lockup before this component existed, each with its
   own class names and its own numbers. Renaming their markup is a large,
   risky diff across ~140k lines of hand-written frontend; binding their class
   names to the tokens is a small one, and it produces the same guarantee —
   after this block there is no selector left in the repo that can size a mark
   or a wordmark independently of the ratio.

   A surface may now choose exactly ONE thing: the lockup's font-size. That
   sets the mark; the wordmark follows at mark ÷ ratio. Anything that wants a
   36px mark asks for `font-size: calc(36px / 1.35)`, not for a 36px mark and
   a wordmark height it picked by eye.

   New markup uses .hs-lockup. This list is closed — do not add to it. */
[data-hs="2"] :is(.brand-mark, .hs-portal-bmark, .ws-mobile-topbar__mark) {
  flex: none;
  height: var(--hs-lockup-mark);
  width: var(--hs-lockup-mark);
  display: block;
}

[data-hs="2"] :is(.brand-word, .hs-portal-bword, .ws-mobile-topbar__word) {
  flex: none;
  height: var(--hs-lockup-word);
  width: auto;
  display: block;
  /* Same pre-decode collapse as .hs-lockup__word — see the note there. */
  aspect-ratio: 160 / 23;
}

/* The lander pages draw their mark and wordmark as inline <svg>, not <img>.
   The wrapper carries the size; the svg fills it. */
[data-hs="2"] :is(.brand-mark, .brand-word) > svg {
  display: block;
  height: 100%;
  width: 100%;
}

[data-hs="2"] .brand-word > svg {
  width: auto;
}

/* The containers: only a font-size and the gap. Each font-size is chosen so
   the MARK keeps the footprint that surface was laid out around — the mark is
   the icon slot with layout meaning, so it anchors and the wordmark follows.

   The v1 lander lockup (.brand > .bmark + .bword) is NOT here. It sized itself
   from literal fallbacks in lander.css because old-lander.html loaded no
   design-system CSS at all. That page was deleted on 2026-09-06 and no page
   uses .brand any more, so those rules are now dead and this pair can move in
   whenever someone is in lander.css for another reason. */
[data-hs="2"] :is(.brand-lockup, .hs-portal-brand, .ws-mobile-topbar__brand,
  .ws-unlock__brand) {
  display: inline-flex;
  align-items: center;
  gap: var(--hs-lockup-gap);
  line-height: 1;
}

/* The portal rail is the one place the old footprint could not survive the
   correction. It ran a 36px mark against an 18px wordmark — a 2.0 ratio — and
   that only looked balanced because the wordmark was starved. Hold the mark at
   36 and the corrected wordmark grows to 24px, which makes the lockup 214px
   wide in a 244px rail: 88% of the width, shouting over 14px nav labels.

   So the rail takes the base step instead, the same one the lander nav uses:
   24.3px mark, 16.2px wordmark, 144px overall. Chrome, not a hero. */
[data-hs="2"] .hs-portal-brand {
  font-size: var(--hs-lockup-size-base);
}

/* 22px mark in the mobile topbar: 22 ÷ 1.35. */
[data-hs="2"] .ws-mobile-topbar__brand {
  font-size: calc(22px / 1.35);
}

/* ---- Surface overrides ------------------------------------------------
   The lander sizes its nav brand with `!important` in scroll-lander-ux.css and
   targets `.v2-site-nav__brand img`, which would hit the mark and the wordmark
   with the same height and squash the pair. Re-assert the ratio at a matching
   weight. */
[data-hs="2"] .v2-site-nav__brand {
  gap: 0.4em;
}

[data-hs="2"] .v2-site-nav__brand .hs-lockup__mark {
  height: var(--hs-lockup-mark) !important;
  width: var(--hs-lockup-mark) !important;
}

[data-hs="2"] .v2-site-nav__brand .hs-lockup__word {
  height: var(--hs-lockup-word) !important;
  width: auto !important;
}

/* Admin sidebar: the lockup sits above a role tag, so it stacks. */
[data-hs="2"] .hs-adm-brand {
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

/* Owner rail: same stack, so a Dev/Staging pill sits under the lockup. */
[data-hs="2"] .hs-portal-nav-brand {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}

/* Non-production only. `data-hs-env` is stamped by env-tab-title.js / page-ssr.
   Production never sets the attribute, so these stay `display: none`. */
.hs-env-pill {
  display: none;
  align-items: center;
  align-self: flex-start;
  height: 18px;
  padding: 0 8px;
  border-radius: var(--hs-radius-pill);
  border: var(--hs-size-hairline) solid transparent;
  font-family: var(--hs-font-ui);
  font-size: var(--hs-text-2xs);
  font-weight: var(--hs-weight-bold);
  letter-spacing: 0.02em;
  line-height: 1;
  white-space: nowrap;
}

[data-hs="2"][data-hs-env="dev"] .hs-env-pill--dev,
[data-hs="2"][data-hs-env="staging"] .hs-env-pill--staging {
  display: inline-flex;
}

[data-hs="2"][data-hs-env] .hs-adm-brand__tag,
[data-hs="2"][data-hs-env] [data-hs-env-replace] {
  display: none;
}

.hs-adm-auth .hs-env-pill {
  margin-bottom: 12px;
}

[data-hs="2"][data-hs-env="dev"] .hs-adm-auth .hs-env-pill--dev,
[data-hs="2"][data-hs-env="staging"] .hs-adm-auth .hs-env-pill--staging {
  display: flex;
  width: max-content;
  margin-inline: auto;
}

.hs-env-pill--dev {
  background: var(--hs-info-bg);
  border-color: var(--hs-info-border);
  color: var(--hs-info-fg);
}

.hs-env-pill--staging {
  background: var(--hs-warning-bg);
  border-color: var(--hs-warning-border);
  color: var(--hs-warning-fg);
}

[data-hs="2"] .hs-adm-brand .hs-lockup {
  font-size: 16px;
}

/* admin-dashboard.css sets `.hs-adm-brand img { width:30px; height:30px }`,
   which squares off the wordmark — it rendered 30x30 instead of 106x15. That
   selector is 0-1-1; these are 0-2-1, so no !important is needed. */
[data-hs="2"] .hs-adm-brand .hs-lockup__mark {
  width: var(--hs-lockup-mark);
  height: var(--hs-lockup-mark);
}

[data-hs="2"] .hs-adm-brand .hs-lockup__word {
  width: auto;
  height: var(--hs-lockup-word);
}

/* ---- On dark ----------------------------------------------------------
   A marker class, not a restyle. The variant is chosen by swapping the two
   SVG files (knockout mark + cream wordmark); this class exists so the intent
   is legible in the markup and so a reviewer can grep for every dark-surface
   lockup. The admin sidebar is forest-900 at luminance 0.009 — the everglade
   wordmark measures 1.6:1 there, which is why the pairing is not optional. */
.hs-lockup--on-dark {
  /* Same value as the old literal --hs-forest-200, through the role token —
     the palette step stays out of text colour and the one-off token gains
     its one intended consumer. */
  color: var(--hs-fg-inverse-secondary);
}
