/* --------------------------------------------------------------------------
   Link Button
   An L-shaped bracket with a rounded inner corner — a hairline down the left
   turning along the bottom. Hover skews the whole element -10deg (the same
   motion as the hero CTA) and extends the bottom rule to full width.

   Geometry measured from the 4x mocks: stroke 4px -> 1px, corner radius 14px
   -> 3.5px, stub 154px -> ~38px. The hover left edge shifts 13px over 72px,
   atan(13/72) = 10.2deg.
   -------------------------------------------------------------------------- */

:host {
  /* Webflow sets display: contents on <code-island> inline, so :host layout is
     unreliable — everything that matters lives on .lb. */
  display: inline-block;
}

.lb {
  --lb-polynesian-blue: #0e4c92;
  --lb-celestial-blue: #469dc8;
  --lb-syracuse-orange: #d34e24;
  --lb-font: "Aptos", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Hairlines stay 1px at every size rather than scaling to fractional pixels. */
  --lb-stroke: 1px;
  /* Everything else is in em so the bracket tracks the type across breakpoints. */
  --lb-radius: 0.22em;
  --lb-stub: 2.375em;
  --lb-skew: -10deg;

  /* The text colour lives in a custom property rather than straight on color,
     because custom properties inherit through the slot into a link the page
     dropped in. A class saying `color: var(--lb-ink)` therefore tracks the
     hover and focus colour below without restating it. */
  --lb-ink: var(--lb-polynesian-blue);

  /* Desktop. Override --lb-font-size from Webflow (a variable set on any
     ancestor inherits through the shadow boundary) to drive this from your own
     Body variable instead of these breakpoints. */
  --lb-font-size: 20px;

  position: relative;
  display: inline-flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  box-sizing: border-box;
  padding: 0 0 0.31em 0.5em;
  font-family: var(--lb-font);
  font-weight: 500;
  font-size: var(--lb-font-size);
  line-height: 1.2;
  color: var(--lb-ink);
  overflow-wrap: anywhere;

  /* With nothing dropped in yet the bracket is all there is, and an inline-flex
     box with no content is zero high. These give the empty state a shape to
     aim at in the Designer; every real link is already larger. */
  min-width: var(--lb-stub);
  min-height: 1.2em;

  transform: skewX(0deg);
  transform-origin: bottom left;
  transition: transform 0.25s ease, color 0.25s ease;
}

.lb *,
.lb::after {
  box-sizing: border-box;
}

/* One element draws the whole bracket: left border, bottom border, and the
   rounded corner joining them. Two separate bars could not round the joint.
   Animating its width extends the bottom rule while the left bar stays put. */
.lb::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--lb-stub);
  border-left: var(--lb-stroke) solid var(--lb-celestial-blue);
  border-bottom: var(--lb-stroke) solid var(--lb-celestial-blue);
  border-bottom-left-radius: var(--lb-radius);
  pointer-events: none;
  transition: width 0.25s ease;
}

/* A link the page dropped into the Link slot arrives wrapped in an unclassed
   <div slot="link">. display: contents drops that wrapper's box so the native
   <a> sits in the flex row itself, next to the bracket.

   That is the whole of what the component can do to it. ::slotted() matches the
   top-level assigned node and nothing below it, so no rule here reaches the
   <a> — not with !important, not with a combinator, which ::slotted() does not
   take. Everything that inherits (font, size, weight, line-height,
   letter-spacing, and --lb-ink) crosses the slot boundary on its own.

   Colour and underline do not, and setting them on .lb does not help: the
   browser's own `a { color: -webkit-link; text-decoration: underline }` is a
   declaration on the anchor, and a declaration beats an inherited value whatever
   its origin. That is why the link needs a class of its own — measured, not
   assumed: an unclassed link inside this bracket renders rgb(0, 0, 238).

   Scoped by slot name rather than written as a bare ::slotted(*), which would
   also match the Label slot's span. */
slot[name="linkSlot"]::slotted(*) {
  display: contents;
}

/* Webflow breakpoints. Tablet is <= 991px, mobile <= 767px. */
@media (max-width: 991px) {
  .lb { --lb-font-size: 15px; }
}

@media (max-width: 767px) {
  .lb { --lb-font-size: 14px; }
}

/* Guarded: a tap on a touch screen applies :hover and leaves it stuck. */
@media (hover: hover) {
  .lb:hover {
    transform: skewX(var(--lb-skew));
    --lb-ink: var(--lb-syracuse-orange);
  }

  .lb:hover::after {
    width: 100%;
  }
}

/* Keyboard parity — a hover-only affordance is invisible to keyboard users.

   :focus-within, not :focus-visible, because .lb is never the focused element:
   what takes focus is the page's own <a>, which is not a DOM descendant of it.
   :has(:focus-visible) does not match that — measured in Chrome, where :has() is
   scoped to the DOM tree, while :focus-within is defined over the flat tree and
   does. The cost is that :focus-within also fires on a mouse click, which is the
   thing :focus-visible exists to avoid; on a link the click navigates away before
   the quarter-second skew finishes, so it is a fair trade. */
.lb:focus-within {
  transform: skewX(var(--lb-skew));
  --lb-ink: var(--lb-syracuse-orange);
  outline: 2px solid var(--lb-celestial-blue);
  outline-offset: 4px;
}

.lb:focus-within::after {
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .lb,
  .lb::after {
    transition: none;
  }
}

