/* token-2049 — page styles.
 *
 * This target has no Sass step: the browser loads this file after core.css and
 * kit.css, as it is. So every kit concept arrives as the custom property
 * core.css publishes — a semantic role, a named type step, a gutter token — and
 * the four breakpoints are written as their values (sm 576, md 768, lg 1024,
 * xl 1440), min-width only.
 *
 * Almost all of the page is kit components: feature rows, cards,
 * the figures box and flag, footnotes, the event eyebrow and the split closing
 * band. What is left here is layout the kit does not own — each section's grid
 * — the page's small shapes, such as the hero's event wordmark, and the
 * booking calendar's dialog, which the kit does not ship.
 *
 * Blocks in this file:
 *   token-2049-page           the shell
 *   token-2049-hero           B — photo hero
 *   token-2049-capabilities   E — feature rows
 *   token-2049-quote          a brand panel holding a blockquote
 *   token-2049-movement       D — cards
 *   token-2049-reach          C — figures box
 *   token-2049-disclosure     L — footnotes
 *   token-2049-press          kit cards holding press articles
 *   token-2049-meeting        the booking calendar's dialog
 */

/* ------------------------------------------------------------------ shell */

/* Kit defect, worked around page-locally: `.st-btn` is chamfered with a
   clip-path, which clips the focus outline with everything else. Dropping the
   clip while the ring shows restores it. */
.token-2049-page .st-btn:focus-visible {
  clip-path: none;
}

/* ------------------------------------------------------------------ logo */

/* The Stable.com logo, as the app draws it. One colour, so it is a mask filled
   with the current colour: brand in the navbar and in the title's accent, on
   either ground. Height sets the size; the width follows the logo's 160:24. */
.token-2049-logo {
  display: inline-block;
  aspect-ratio: 160 / 24;
  background-color: currentColor;
  -webkit-mask: url(/token-2049/media/stable-wordmark.svg) center / contain no-repeat;
  mask: url(/token-2049/media/stable-wordmark.svg) center / contain no-repeat;
}

.token-2049-logo--nav {
  height: 24px;
}

/* ------------------------------------------------------------------- hero */

/* The photograph is the hero's ground. Two layers over it, both in ground
   roles so they follow the switch: a wash of the page colour from the left,
   which gives the copy a flat field to sit on, and a fade at the foot into the
   capabilities plate below. Each ground's photograph carries its own wash stop
   and fade depth, as the design sets them. */
.token-2049-hero {
  --hero-wash-stop: 63%;
  --hero-fade: 111px;
  display: flex;
  flex-direction: column;
  padding-block-end: 0;
  background-color: var(--bg-page);
}

.ground-light .token-2049-hero {
  --hero-wash-stop: 52%;
  --hero-fade: 144px;
}

@media (prefers-color-scheme: light) {
  .ground-auto .token-2049-hero {
    --hero-wash-stop: 52%;
    --hero-fade: 144px;
  }
}

.token-2049-hero__media {
  position: relative;
  display: block;
  order: 1;
  z-index: -1;
  margin-block-start: calc(var(--gutter-base) * 2);
}

.token-2049-hero__photo {
  position: relative;
  display: block;
}

.token-2049-hero__media img {
  display: block;
  width: 100%;
  height: auto;
}

/* The live site, placed on the photograph's screen. It renders at a laptop's
   own viewport and a perspective transform lays that rectangle onto the four
   corners of the glass, measured in the photograph's pixels (2826 wide); the
   script scales those pixels to the rendered width. It shows once loaded, so
   until then the photograph's own screen is what is seen. */
.token-2049-hero__screen {
  display: none;
}

.token-2049-hero__screen:not([hidden]) {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 1440px;
  height: 935px;
  border: 0;
  background: var(--bg-page);
  transform-origin: 0 0;
  transform:
    scale(var(--photo-scale, 0))
    matrix3d(0.602505, -0.0296387, 0, -0.0000772049,
             -0.188283, 0.758704, 0, -0.0000519082,
             0, 0, 1, 0,
             1510, 224, 0, 1);
  opacity: 0;
  transition: opacity 0.4s ease;
}

.token-2049-hero__screen.is-live {
  opacity: 1;
}

@media (min-width: 1024px) {
  /* The copy's column spans the hero and sits over the screen; it lets the
     pointer through everywhere but the copy itself. */
  .token-2049-hero > .st-container {
    pointer-events: none;
  }

  .token-2049-hero__copy {
    pointer-events: auto;
  }
}

.token-2049-hero__media img.st-duo__dark {
  display: var(--show-on-dark);
}

.token-2049-hero__media img.st-duo__light {
  display: var(--show-on-light);
}

.token-2049-hero__media::after {
  content: "";
  pointer-events: none;
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  height: var(--hero-fade);
  background: linear-gradient(to bottom, transparent, var(--bg-surface));
}

@media (min-width: 1024px) {
  /* The photograph's composition is set at 700 tall; below that the laptop
     would be cropped under the copy. Where the photograph renders taller than
     that, the section grows to hold all of it plus a margin, so the laptop's
     lid clears the navbar and its ground switch. The copy sits on the
     section's middle, clear of the navbar at either end. */
  .token-2049-hero {
    min-height: max(700px, min(100vw * 1413 / 1440, 1620px) * 1483 / 2826 + 32px);
    justify-content: center;
    padding-block: 92px;
  }

  .token-2049-hero__media {
    position: absolute;
    inset: 0;
    margin: 0;
    overflow: hidden;
  }

  /* At the design's scale — 1413 of 1440, sat on the section's foot — rather
     than covering the section: the copy here runs taller than the design's, and
     a cover fit would grow the laptop and push it under the copy. What is left
     above is the page colour; the photograph's own sky is faded into it so no
     edge shows on the light ground. Below 1440 the laptop shrinks less
     quickly than the column, so it bleeds off the right edge instead of
     sliding under the copy; above it, it stops growing, so a wide screen shows
     more page colour rather than a laptop that reaches the copy. Its left
     edge fades as well, for when that edge is on screen. */
  .token-2049-hero__photo {
    position: absolute;
    inset-inline-end: min(0px, (100vw - 1440px) * 0.35);
    inset-block-end: 0;
    width: min(100% * 1413 / 1440, 1620px);
    mask-image:
      linear-gradient(to bottom, transparent, #000 20%),
      linear-gradient(to right, transparent, #000 25%);
    mask-composite: intersect;
  }

  .token-2049-hero__media::before {
    content: "";
    pointer-events: none;
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(105deg, var(--bg-page) 3%, transparent var(--hero-wash-stop));
  }
}

.token-2049-hero__copy {
  max-width: 600px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--gutter-base) * 1.25);
}

.token-2049-hero__title {
  margin-block-start: calc(var(--gutter-base) / 4);
  /* The kit's 60px holds at every width, and the Stable.com logo (below)
     cannot wrap. Scale down until the logo and the words around it sit well
     on a phone's column; at ~410px and up this is the kit's 60px again. */
  font-size: clamp(40px, calc((100vw - 2 * var(--gutter-base)) / 6.3), 60px);
  line-height: 1.2;
}

/* The accent glows, after the w3schools "glowing text" recipe: stacked shadows
   in the brand colour, breathing between a tight and a wide spread. A page
   decision against the kit, which has no shadows and one ambient layer per page
   (the closing bloom) — so it lives here, not in the kit. A filter rather than
   text-shadow, because the delta is an SVG and text-shadow would skip it. */
.token-2049-hero__title .st-title__accent {
  --glow: color-mix(in srgb, var(--brand-default) 40%, transparent);
  filter: drop-shadow(0 0 6px var(--glow)) drop-shadow(0 0 16px var(--glow));
}

/* On the dark ground the glow can carry the w3schools strength; on the light
   one the same spread reads as a smudge, so it stays softer there. */
.ground-dark .token-2049-hero__title .st-title__accent {
  --glow: color-mix(in srgb, var(--brand-default) 60%, transparent);
}

@media (prefers-reduced-motion: no-preference) {
  .token-2049-hero__title .st-title__accent {
    animation: token-2049-glow 1.6s ease-in-out infinite alternate;
  }
}

@keyframes token-2049-glow {
  from { filter: drop-shadow(0 0 2px var(--glow)) drop-shadow(0 0 8px var(--glow)); }
  to   { filter: drop-shadow(0 0 6px var(--glow)) drop-shadow(0 0 18px var(--glow)); }
}

/* In the title the logo stands for the word: cap height and advance of the
   title's own letters, sat on its baseline. */
.token-2049-hero__logo {
  height: 0.72em;
  vertical-align: baseline;
}

/* The event's wordmark: one colour, drawn in the text colour so it follows the
   ground. */
.token-2049-hero__mark {
  flex: none;
  width: 168px;
  height: 21px;
  background-color: var(--text-primary);
  -webkit-mask: url(/token-2049/media/token2049-wordmark.svg) center / contain no-repeat;
  mask: url(/token-2049/media/token2049-wordmark.svg) center / contain no-repeat;
}

.token-2049-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: calc(var(--gutter-base) * 0.75);
  padding-block-start: calc(var(--gutter-base) * 0.375);
}

/* ----------------------------------------------------------- capabilities */

.token-2049-capabilities__head {
  display: flex;
  flex-direction: column;
  gap: calc(var(--gutter-base) * 1.5);
  max-width: 900px;
  margin-block-end: calc(var(--gutter-base) * 1.5);
}

@media (min-width: 1024px) {
  .token-2049-capabilities__head {
    gap: calc(var(--gutter-base) * 2.5);
    margin-block-end: 0;
  }
}

/* ------------------------------------------------------------------- quote */

.token-2049-quote__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--gutter-base) * 2.5);
}

.token-2049-quote__figure {
  position: relative;
  width: 100%;
  max-width: 900px;
  padding: calc(var(--gutter-base) * 2.5) calc(var(--gutter-base) * 1.5);
  display: flex;
  flex-direction: column;
  gap: calc(var(--gutter-base) * 1.5);
}

@media (min-width: 768px) {
  .token-2049-quote__figure {
    padding: calc(var(--gutter-base) * 3.5) calc(var(--gutter-base) * 4);
  }
}

.token-2049-quote__text {
  font-size: var(--size-body-l);
  line-height: var(--line-body-l);
  color: var(--text-primary);
  text-wrap: pretty;
}

@media (min-width: 768px) {
  .token-2049-quote__text {
    font-size: var(--size-h3);
    line-height: var(--line-h3);
  }
}

.token-2049-quote__text p::before { content: "\201C"; }
.token-2049-quote__text p::after { content: "\201D"; }

.token-2049-quote__by {
  font-size: var(--size-caption);
  line-height: var(--line-caption);
  text-transform: uppercase;
  color: var(--brand-default);
}

/* ---------------------------------------------------------------- movement */

.token-2049-movement__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--gutter-base) * 2.5);
}

.token-2049-movement__title {
  text-align: center;
}

.token-2049-movement .st-cards {
  width: 100%;
}

.token-2049-movement .st-card {
  min-height: 208px;
}

.token-2049-movement__closing {
  max-width: 640px;
  font-size: var(--size-body-l);
  line-height: var(--line-body-l);
  color: var(--text-primary);
  text-align: center;
  text-wrap: balance;
}

/* ------------------------------------------------------------------- reach */

.token-2049-reach__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: calc(var(--gutter-base) * 3);
}

@media (min-width: 1024px) {
  .token-2049-reach__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: calc(var(--gutter-base) * 5);
    align-items: start;
  }
}

.token-2049-reach__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--gutter-base) * 1.5);
}

.token-2049-reach__copy .st-lede {
  max-width: 562px;
}

.token-2049-reach__statement {
  max-width: 475px;
  padding-block-start: calc(var(--gutter-base) * 1.5);
  border-block-start: var(--hairline) solid var(--border-subtle);
  font-size: var(--size-body-l);
  line-height: var(--line-body-l);
  color: var(--text-primary);
}

.token-2049-reach__figures {
  display: flex;
  flex-direction: column;
  gap: calc(var(--gutter-base) * 1.25);
}

.token-2049-reach__source {
  font-size: var(--size-caption);
  line-height: var(--line-caption);
  color: var(--text-secondary);
}

/* -------------------------------------------------------------- disclosure */

/* A quiet band: half a section's rhythm, because it is fine print between two
   full sections rather than a section of its own. */
.token-2049-disclosure.st-section {
  padding-block: calc(var(--gutter-base) * 2.5);
}

/* ------------------------------------------------------------------- press */

.token-2049-press__inner {
  display: flex;
  flex-direction: column;
  gap: calc(var(--gutter-base) * 2.5);
}

/* The kit's cards, two-up from md rather than three. */
@media (min-width: 768px) {
  .token-2049-press__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.token-2049-press__list > li {
  display: flex;
}

.token-2049-press__item {
  flex: 1;
}

.token-2049-press__item .st-card__title {
  text-wrap: balance;
}

/* The link sits at the card's foot whatever the headline's length, so the two
   links line up; its box is the tap minimum, with the text centred in it. */
.token-2049-press__link {
  margin-block-start: auto;
  min-block-size: 44px;
}

/* The outlet's wordmark, in one colour so it follows the ground: a mask filled
   with the text colour, as the event's wordmark is. Height sets the size; the
   width follows each wordmark's own proportions. */
.token-2049-press__outlet {
  display: block;
  height: 20px;
  background-color: var(--text-primary);
  -webkit-mask: var(--outlet) left center / contain no-repeat;
  mask: var(--outlet) left center / contain no-repeat;
}

.token-2049-press__outlet--tradingview {
  --outlet: url(/token-2049/media/press-tradingview.svg);
  aspect-ratio: 147 / 28;
}

.token-2049-press__outlet--yahoo-finance {
  --outlet: url(/token-2049/media/press-yahoo-finance.svg);
  aspect-ratio: 1284.1 / 181.3;
}

.token-2049-press__meta {
  font-size: var(--size-caption);
  line-height: var(--line-caption);
  color: var(--text-secondary);
}

/* ----------------------------------------------------------------- meeting */

/* The kit ships no dialog, so this is the page's: a flat panel in the kit's
   surface and hairline, square like everything else in it, over a scrim of the
   page colour. The calendar is a third-party page, so its own ground shows
   inside the frame whichever ground the page is on. */
.token-2049-meeting {
  width: min(1000px, 100vw - 2 * var(--gutter-base));
  height: min(760px, 100dvh - 2 * var(--gutter-base));
  max-width: none;
  max-height: none;
  padding: 0;
  border: var(--hairline) solid var(--border-subtle);
  border-radius: 0;
  background-color: var(--bg-surface);
  color: var(--text-primary);
  overflow: hidden;
}

.token-2049-meeting::backdrop {
  background-color: color-mix(in srgb, var(--bg-page) 80%, transparent);
}

.token-2049-meeting__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background-color: var(--bg-surface);
}

/* The tap minimum, in the frame's corner, over the calendar. */
.token-2049-meeting__close {
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-inline-start: var(--hairline) solid var(--border-subtle);
  border-block-end: var(--hairline) solid var(--border-subtle);
  background-color: var(--bg-surface);
  color: var(--text-primary);
  cursor: pointer;
}

.token-2049-meeting__close:hover {
  color: var(--brand-default);
}

.token-2049-meeting__close:focus-visible {
  outline: 2px solid var(--brand-default);
  outline-offset: -2px;
}
