/*
 * The gOS application shell.
 *
 * One stylesheet for the chrome every gOS surface shares: the Newfoundation
 * Whyte faces, the page tokens, the g mark, the bar that carries it across the
 * top of an application, and the centred container under that bar. It is
 * served two ways from this one source:
 *
 *   - bundled, through the `@import` at the top of global.css, into every page
 *     this repo renders: the marketing pages, the playground, the sign-in page;
 *   - as `/app-shell.css` (src/pages/app-shell.css.ts), for a surface that is
 *     not bundled with the site. The ranking links it from its own document,
 *     and the console, built in the AGInetwork repo and served from both
 *     aginet.work and gos.computer, links it by absolute URL so it renders as
 *     a gOS surface on either origin.
 *
 * Because it is also loaded on its own, it declares no ground, no ink and
 * nothing below the bar. Each surface keeps its own colour scheme and its own
 * body type; the mark and the bar read over any of them by differencing
 * against the page, which is what makes the g white on a black surface and
 * black on a white one from a single asset.
 *
 * The vocabulary, which tests/app-shell.test.mjs pins and the console's own
 * tests mirror:
 *
 *   .brand            the g, linking to "/", with an optional name beside it;
 *                     with a name it is a box holding two links:
 *   .brand__home      the g's own link to "/"
 *   .brand__glyph     the mark itself: the inline pen-draw g in the site
 *                     header, an <img> of /images/g-arden.svg everywhere else
 *   .brand__name      the surface's name beside the mark: Playground, Console;
 *                     a link to that section's own home, never to "/"
 *   .app-bar          the fixed top bar of an application surface
 *   .app-bar__actions the trailing cluster in that bar: sign in, sign out
 *   .app-main         the container under the bar, cleared of it
 *   .app-table        a dashboard's list, drawn as a <table> inside it
 *   .app-card         the card a figure or an account is set in
 *   .app-button       the one button, a pill that inverts on hover
 *
 * And the menu, which is one behaviour on every surface: a panel that expands
 * from the top edge, and links that stagger in under it.
 *
 *   .site-menu-panel      the sheet that comes down behind the links, painted
 *                     the surface's own --app-ground and edged in its
 *                     --app-shadow
 *   .site-menu-hover-strip
 *                     legacy markup hook, kept inert for existing surfaces
 *   .site-nav             the fixed right-hand column the links live in
 *   .site-nav__list       the list; --site-menu-row-count sizes the panel
 *   .site-nav__item--home the one row that is visible at rest
 *   .site-nav__item--menu the rows that fade in, staggered by --nav-index
 *   .site-subnav          the column of section links beside the rows, one
 *                     section at a time, chosen by /menu-rail.js
 *   .site-menu-toggle     the phone control that opens the same menu
 */

@font-face {
  font-family: "Newfoundation Whyte";
  src: url("/fonts/NewfoundationWhyte-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Newfoundation Whyte";
  src: url("/fonts/NewfoundationWhyte-Book.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Newfoundation Whyte";
  src: url("/fonts/NewfoundationWhyte-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Newfoundation Whyte";
  src: url("/fonts/NewfoundationWhyte-Medium.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* One container for every surface: this width, on this centre line, over
     this gutter. The header and the bar sit at this inset in this type. */
  --page-gutter: 44px;
  --site-content-max: 1250px;
  --site-container-gutter: var(--page-gutter);
  --site-menu-pad-y: 39.94px;
  --site-menu-font-size: 21.5px;
  /* The menu's row rhythm on a pointer. The phone menu sets its own. */
  --site-menu-line-height: 1.4;
  --site-menu-bottom-pad: clamp(24px, 2.4vw, 42px);
  --site-radius: 26px;

  /* The ground a surface paints and the ink it writes in.
   *
   * The shell has no ground of its own — that is the rule that lets one
   * stylesheet serve a white marketing page and a black dashboard — but the
   * menu panel is a sheet that comes down over the page, and a white sheet on
   * a black page is a hole in it. So the panel is painted the surface's own
   * ground, and these two are how a surface says what that is. A dark surface
   * sets them beside its own colours; the site takes the defaults.
   *
   * Only the phone menu needs the ink: on a pointer the rows difference
   * against the panel and come out legible on either. */
  --app-ground: #ffffff;
  --app-ink: #050505;

  /* And the edge that sheet casts as it comes down.
   *
   * A shadow is dark because ground is normally lighter than what falls on it.
   * On a black surface that is inverted: a black shadow under a black panel is
   * nothing at all, and the sheet arrives with no edge and no depth. So the
   * shadow is a surface value like the two above — the site casts the default
   * dark one, and a dark surface casts the same shadow in white. */
  --app-shadow: 0 9px 21px rgb(0 0 0 / 0.04);

  /* How the mark is painted when it cannot be blended (a section's entrance):
     its black source as it is on a light surface; a dark surface inverts it. */
  --app-mark-filter: none;

  /* A row's own ink. Which rows step back is the spotlight's (.is-spotlit). */
  --nav-link-opacity: 1;
  --nav-link-hover-opacity: 1;
  --nav-link-current-opacity: 1;

  font-family: "Newfoundation Whyte", Arial, Helvetica, sans-serif;
  font-synthesis: none;
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
}

/* The mark. Inline-flex so a name can follow it, and differenced against the
   page so it needs no second asset to be legible on a dark surface. Where it
   sits is its container's decision: the site header pins it to the top-left
   gutter, the app bar flows it as the bar's first item. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.34em;
  mix-blend-mode: difference;
  pointer-events: auto;
}

/* A black source inverted to white is what the difference blend needs, and
   both sources are black: the pen-draw glyph inlined by the site header and
   the g-arden.svg the footer and every application bar draw as an <img>. */
.brand__glyph {
  display: inline-flex;
  width: auto;
  height: 1.16em;
  margin: 0 -0.018em 0 -0.02em;
  filter: invert(1);
  transform: translateY(0.19em);
}

.brand__glyph svg {
  display: block;
  width: auto;
  height: 100%;
}

/* Quieter than the mark: the mark is the brand, the name is a label. */
.brand__name {
  opacity: 1;
}

/* A named mark is two links: only the g goes home, the name goes to the home
   of its own section. Both take the mark's ink rather than a link colour. */
.brand__home {
  display: inline-flex;
  align-items: center;
}

.brand a {
  color: inherit;
  text-decoration: none;
}

/* A section's entrance (/brand-entrance.js). Arriving in a section from
   anywhere else, the g draws itself large and flies to its corner, then the
   section's name and any header status information come in before the page
   comes up behind them. App bars carry the section name alone; status data
   such as Live's clock may still use the shared breadcrumb style. A few lines
   at the top of the page decide it before the page
   paints and set this attribute; until the entrance removes it, the page waits
   behind the mark. The mark is hidden until the entrance places it large, its
   corner draw held back so it does not draw twice, and it is painted in the
   surface's own ink rather than blended, because a transformed, promoted mark
   is where some engines stop compositing mix-blend-mode. */
html[data-section-entrance] :is([data-page-content], .app-main, .site-footer, .app-footer, .site-nav, .site-menu-toggle, .site-audio-toggle, .brand__name, .app-breadcrumb, .app-header-search) {
  opacity: 0;
  pointer-events: none;
}

html[data-section-entrance] .site-menu-hover-strip {
  pointer-events: none;
}

html[data-section-entrance] .brand[data-section] {
  visibility: hidden;
  pointer-events: none;
}

html[data-section-entrance] .brand[data-section] .gos-g-draw {
  animation: none;
}

html[data-section-entrance] :is(.app-bar, .brand[data-section]) {
  mix-blend-mode: normal;
}

html[data-section-entrance] .brand[data-section] .brand__glyph {
  filter: var(--app-mark-filter, none);
}

/* Section context belongs beside the mark, where every dashboard has a bar. */
.app-breadcrumb {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  min-width: 0;
  font: inherit;
  opacity: 1;
  white-space: nowrap;
}

/* Optional search stays in the header row, using the measured space between
   the breadcrumb and the menu's visible label. */
.app-header-search {
  position: fixed;
  z-index: 55;
  top: var(--app-header-search-top, calc(var(--site-menu-pad-y) - 5px));
  right: var(--app-header-search-right, 25vw);
  left: var(--app-header-search-left, 25vw);
  display: block;
  height: max(32px, calc(var(--site-menu-font-size) * 1.35));
  margin: 0;
  mix-blend-mode: normal;
  pointer-events: auto;
}
.app-header-search[hidden] { display: none; }
.app-header-search input[type="search"] {
  box-sizing: border-box;
  display: block;
  width: 100%;
  min-width: 0;
  min-height: 0;
  height: 100%;
  padding: 0 40px;
  border: 1px solid var(--app-ink, #050505);
  border-radius: 999px;
  background: var(--app-ground, #fff);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  color: var(--app-ink, #050505);
  font-family: inherit;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.2;
}
.app-header-search input::placeholder { color: currentColor; opacity: 0.65; }
.app-header-search input:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.dashboard-menu { display: contents; }
.site-nav__list[hidden] { display: none; }

.app-breadcrumb__dot {
  width: 0.17em;
  height: 0.17em;
  flex: none;
  border-radius: 50%;
  background: currentColor;
}

.app-list-scroll__sentinel { height: 1px; }
.app-list-scroll__sentinel[hidden], .app-scroll-top[hidden] { display: none; }
.app-scroll-top {
  position: fixed;
  z-index: 30;
  right: max(20px, env(safe-area-inset-right));
  bottom: max(20px, env(safe-area-inset-bottom));
  padding: 9px 13px;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: var(--app-ground);
  color: var(--app-ink);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.app-scroll-top:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

/* A surface whose name the mark already starts.
 *
 * The g is a G, so the Garden dashboard writes the rest of its own name and
 * the lockup reads as one word rather than as a mark beside a word that
 * repeats it. The letters are the mark's own ink, not the label grey, and the
 * gap closes to nothing: this is the same lockup the manifesto's garden sign
 * draws, which is where the measurements come from. */
.brand--word {
  align-items: baseline;
  gap: 0.005em;
  white-space: nowrap;
}

.brand--word .brand__glyph {
  height: 0.972em;
  transform: translateY(0.08em);
}

.brand__word {
  font-weight: inherit;
}

/* The bar. Fixed across the top at the header's own inset and gutter, in the
   header's type, differenced like the mark. It takes no pointer events of its
   own so it is never a full-width strip of dead space over the page; its
   children take them. */
.app-bar {
  position: fixed;
  z-index: 41;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: calc(var(--site-menu-pad-y) - 5px) var(--page-gutter) 0;
  color: #ffffff;
  font-size: var(--site-menu-font-size);
  font-weight: 700;
  line-height: 1;
  mix-blend-mode: difference;
  pointer-events: none;
}

.app-bar > * {
  pointer-events: auto;
}

/* Let the search blur the page behind the bar; blending the whole bar would
   isolate that backdrop. Its text and mark keep their own contrast blending. */
.app-bar:has(.app-header-search) { mix-blend-mode: normal; }
.app-bar:has(.app-header-search) > .app-breadcrumb { mix-blend-mode: difference; }

/* Controls in the bar are bar type, not form-control type. */
.app-bar :is(a, button) {
  color: inherit;
  font: inherit;
  text-decoration: none;
}

.app-bar button {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

/* The trailing cluster: sign in, sign out, a status. */
.app-bar__actions {
  display: flex;
  align-items: center;
  gap: 1em;
  margin-left: auto;
}

.app-bar__actions :is(a, button) {
  opacity: 1;
  transition: opacity 170ms ease;
}

.app-bar__actions :is(a, button):is(:hover, :focus-visible) {
  opacity: 1;
}

/* The page you are on, in a bar that is also a menu. */
.app-bar__actions :is(a, button)[aria-current] {
  opacity: 1;
}


/* ===========================================================================
 * The menu.
 *
 * One behaviour on every surface: at rest the top right shows a single row,
 * and pointing at the top of the page brings a panel down behind it — in the
 * surface's own ground, under the surface's own shadow — while the rest of the
 * rows fade in one after another. It lives here rather
 * than in the site's stylesheet because the console is built in another
 * repository and has to be the same menu, not a copy of it — the marketing
 * header, the playground, the ranking and the Garden dashboard all render the
 * markup below and get this file.
 *
 * A surface supplies the panel, the legacy hover-strip hook, a list whose
 * first row is `--home` and whose others are `--menu`, and per-row
 * `--nav-index` / `--nav-reverse-index` custom properties, which are what
 * make the stagger open in order and close in reverse. The panel's height is
 * counted from `--site-menu-row-count`, which the surface sets to its row
 * count plus two.
 * ======================================================================== */

.site-menu-panel {
  position: fixed;
  z-index: 40;
  top: 0;
  right: 15px;
  left: 15px;
  pointer-events: none;
  /* The rows at the menu's rhythm, plus one row of air and the pads. The row
     count a surface sets is its rows plus two, as it always was. */
  height: calc(
    var(--site-menu-pad-y) * 2 +
      var(--site-menu-font-size) * var(--site-menu-line-height) * (var(--site-menu-row-count, 12) - 1) +
      var(--site-menu-bottom-pad)
  );
  border-radius: 0 0 var(--site-radius) var(--site-radius);
  background: var(--app-ground);
  box-shadow: var(--app-shadow);
  opacity: 0;
  transform: translateY(-100%);
  transition:
    opacity 0ms linear 1000ms,
    transform 1000ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.site-menu-hover-strip {
  display: none;
  pointer-events: none;
}

.site-header {
  display: contents;
  color: #ffffff;
  font-size: var(--site-menu-font-size);
  font-weight: 700;
  line-height: 1;
  pointer-events: none;
  transition: color 180ms ease;
}

.site-header__content {
  display: contents;
}

body:has(.site-nav:hover) .site-menu-panel,
/* A surface with no .site-header wrapper of its own still opens for a
   keyboard: the focus lands in the nav. */
body:has(.site-nav:focus-within) .site-menu-panel,
body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .site-menu-panel {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 0ms linear,
    transform 120ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* The menu sheet and links need the whole header row. Leave the field usable
   when it itself has focus, but clear it while the menu is being explored. */
body:has(.site-nav:hover) .app-header-search,
body:has(.site-nav:focus-within) .app-header-search,
body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .app-header-search,
body.is-site-menu-open .app-header-search {
  visibility: hidden;
  pointer-events: none;
}

.site-audio-toggle,
.site-menu-toggle,
.site-nav {
  transition: opacity 360ms ease;
}

body[data-gos-auth="signed-in"] .site-header:not(:has([data-home-brand-intro])) .site-audio-toggle {
  display: none;
}

.site-menu-toggle {
  display: none;
}
:root {
  --site-menu-reveal-opacity: 420ms ease;
  --site-menu-reveal-transform: 620ms cubic-bezier(0.16, 1, 0.3, 1);
  --site-menu-reveal-offset: 28px;
  --site-menu-reveal-start: 140ms;
  --site-menu-reveal-stagger: 56ms;
  --site-menu-hide-stagger: 28ms;
}

.site-menu-toggle {
  border: 0;
  color: inherit;
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
}

body.is-site-menu-open .site-menu-toggle span { transform: rotate(45deg); }
body.is-site-menu-open .site-menu-toggle span::before { transform: rotate(-90deg); }

.site-menu-toggle:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.site-menu-toggle span {
  position: relative;
  display: block;
  width: 18px;
  height: 2px;
  border-radius: var(--site-radius);
  background: currentColor;
  transition: transform 180ms ease;
}

.site-menu-toggle span::before {
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  border-radius: inherit;
  background: currentColor;
  content: "";
  transform: translateY(-6px);
  transition: transform 180ms ease;
}

.site-nav {
  position: fixed;
  z-index: 60;
  /* The first row's words start where the mark's name and breadcrumb start:
     the header's line, plus the name's own drop (it is centred on the g, which
     is 1.16em tall), less the half-leading of the menu's taller rows. */
  top: calc(
    var(--site-menu-pad-y) - 5px +
      ((1.16 - 1) / 2 - (var(--site-menu-line-height) - 1) / 2) * var(--site-menu-font-size)
  );
  right: 0;
  width: 50vw;
  mix-blend-mode: difference;
  pointer-events: none;
}

.site-nav__list {
  display: flex;
  width: 100%;
  margin: 0;
  padding: 0;
  flex-direction: column;
  align-items: stretch;
  list-style: none;
  font-size: inherit;
  font-weight: 700;
  line-height: var(--site-menu-line-height);
  text-align: right;
}

.site-nav__link {
  display: block;
  width: 100%;
  min-width: 0;
  /* Stated rather than inherited: a surface that links only this stylesheet
     has no `a { color: inherit; text-decoration: none }` of its own, and the
     menu would draw underlined browser-blue rows on it. */
  color: inherit;
  text-decoration: none;
  padding: 0.022em var(--site-container-gutter) 0.022em 0;
  opacity: var(--nav-link-opacity);
  outline-offset: 6px;
  transition:
    opacity 170ms ease,
    transform 195ms cubic-bezier(0.2, 0.8, 0.2, 1),
    color 170ms ease;
}

.site-nav__item--home,
.site-nav__item--menu {
  display: flex;
  width: 100%;
  justify-content: stretch;
}

/* Where we are: the section the menu is showing (the page's own until the
   pointer settles on another) at full ink, every other row a step back. It is
   on the item rather than the link, so it turns at once instead of waiting out
   the link's stagger delay. menu-rail.js marks the item. */
.site-nav__list > .site-nav__item {
  transition: opacity 170ms ease;
}

body.is-site-menu-open .site-nav__list > .site-nav__item:not(.is-spotlit) {
  opacity: 0.8;
}

@media (min-width: 800px) {
  /* Only the visible link opens the menu. Once open, keep the full rows so
     the pointer can cross into the adjacent section links without a gap. */
  .site-nav:not(:hover):not(:focus-within) .site-nav__item--home .site-nav__link {
    width: fit-content;
    margin-left: auto;
    margin-right: var(--site-container-gutter);
    padding-right: 0;
  }

  body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .site-nav__list > .site-nav__item:not(.is-spotlit),
  .site-nav:is(:hover, :focus-within) .site-nav__list > .site-nav__item:not(.is-spotlit) {
    opacity: 0.8;
  }
}

.site-nav__item--home .site-nav__link {
  pointer-events: auto;
}

.site-nav__item--menu .site-nav__link {
  opacity: 0;
  pointer-events: none;
  text-align: right;
  transform: translateY(-8px);
  transition:
    opacity 120ms ease,
    transform 140ms cubic-bezier(0.2, 0.8, 0.2, 1),
    color 120ms ease;
  transition-delay: calc(var(--nav-reverse-index) * 20ms);
}

.site-nav__link:is(:hover, :focus-visible) {
  opacity: var(--nav-link-hover-opacity);
}

.site-nav__item--home .site-nav__link[aria-current="page"] {
  opacity: var(--nav-link-current-opacity);
}

.site-nav__item--menu .site-nav__link[aria-current="page"] {
  opacity: 0;
}

.site-nav:hover .site-nav__item--menu .site-nav__link,
.site-nav:focus-within .site-nav__item--menu .site-nav__link {
  opacity: var(--nav-link-opacity);
  pointer-events: auto;
  transform: translateY(0);
  transition:
    opacity 170ms ease,
    transform 195ms cubic-bezier(0.2, 0.8, 0.2, 1),
    color 170ms ease;
  transition-delay: calc(88ms + var(--nav-index) * 32ms);
}

.site-nav:hover .site-nav__item--menu .site-nav__link:is(:hover, :focus-visible),
.site-nav:focus-within .site-nav__item--menu .site-nav__link:is(:hover, :focus-visible) {
  opacity: var(--nav-link-hover-opacity);
}

.site-nav:hover .site-nav__item--menu .site-nav__link[aria-current="page"],
.site-nav:focus-within .site-nav__item--menu .site-nav__link[aria-current="page"] {
  opacity: var(--nav-link-opacity);
}

.site-nav:hover .site-nav__item--menu .site-nav__link[aria-current="page"]:is(:hover, :focus-visible),
.site-nav:focus-within
  .site-nav__item--menu
  .site-nav__link[aria-current="page"]:is(:hover, :focus-visible) {
  opacity: var(--nav-link-hover-opacity);
}


/* A row that acts rather than navigates. Sign out is a POST — a GET that ends
   a session is one a prefetcher can fire without anybody clicking it — so the
   menu has to be able to carry a button that reads as a link. */
button.site-nav__link {
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

/* The section menus: one section's links at a time, in a column beside the
   rows. menu-rail.js chooses the section, the page's own until the pointer
   settles on another one's name, and marks the nav [data-menu-active]. These
   rules show that list whenever the menu is open, on the rows' own stagger in
   both directions, so the page's section arrives with the menu and leaves
   with it, and a section taking over comes in the way the menu itself does.
   Every list sits in the one cell of a grid, so the section fading out and the
   one staggering in cross in place. The column is a descendant of .site-nav,
   so moving into it keeps the menu open. */
.site-subnav {
  position: absolute;
  top: 0;
  right: calc(var(--site-container-gutter) + 125px + 48px);
  display: grid;
  width: 180px;
  visibility: hidden;
  pointer-events: none;
  /* When the menu closes, the column stays until its rows have faded. */
  transition: visibility 0s linear 240ms;
}

.site-subnav__list {
  display: flex;
  grid-area: 1 / 1;
  width: 100%;
  margin: 0;
  padding: 0;
  flex-direction: column;
  list-style: none;
  font: inherit;
  line-height: var(--site-menu-line-height);
  text-align: right;
}

.site-subnav__list[hidden],
.site-subnav__item[hidden] { display: none; }
.site-subnav__item { display: flex; width: 100%; }

/* At rest, and while a section gives way: the rows' closing half. */
.site-subnav .site-subnav__link {
  padding: 0.022em 0;
  opacity: 0;
  pointer-events: none;
  text-align: right;
  transform: translateY(-8px);
  transition:
    opacity 120ms ease,
    transform 140ms cubic-bezier(0.2, 0.8, 0.2, 1);
  transition-delay: calc(var(--nav-reverse-index) * 20ms);
}

/* The phone's open menu. Its pointer and focus states are the desktop's own,
   below, so a focused toggle cannot hold the column open over a closed menu. */
body.is-site-menu-open .site-nav[data-menu-active] .site-subnav {
  visibility: visible;
  pointer-events: auto;
  transition-delay: 0s;
}

@media (min-width: 800px) {
  body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .site-nav[data-menu-active] .site-subnav,
  .site-nav[data-menu-active]:is(:hover, :focus-within) .site-subnav {
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s;
  }

  /* The section showing, while the menu is open: the rows' opening half. */
  body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .site-nav[data-menu-active] .site-subnav__list:not(.is-entering, .is-leaving) .site-subnav__link,
  .site-nav[data-menu-active]:is(:hover, :focus-within) .site-subnav__list:not(.is-entering, .is-leaving) .site-subnav__link {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
    transition:
      opacity 170ms ease,
      transform 195ms cubic-bezier(0.2, 0.8, 0.2, 1);
    transition-delay: calc(88ms + var(--nav-index) * 32ms);
  }
}

.site-subnav__back { display: none; }

@media (min-width: 800px) {
  /* The blur belongs to the open header, so it is not declared at rest. A
     resting filter is not free just because it is an identity: an element with
     any filter is rendered through a filter surface for its whole life, and
     this one wraps the entire page — fifteen thousand pixels of it. WebKit
     takes that literally, keeps the page out of the fast scrolling path and
     repaints the surface on the main thread every frame, which is felt as the
     page shuddering against the scroll rather than as slowness. `none`
     interpolates against blur(12px) as blur(0), so the blur arrives and leaves
     exactly as before; only the standing cost is gone. will-change went with
     it — it made the promotion permanent to save a hitch that is paid once. */
  [data-page-content],
  .app-main,
  .site-footer {
    transition: filter 0ms linear;
  }

  body:has(.site-nav:hover) [data-page-content],
  body:has(.site-nav:hover) .site-footer,
  body:has(.site-nav:hover) .app-main,
  body:has(.site-nav:focus-within) .app-main,
  body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) [data-page-content],
  body:has(.site-header:focus-within):not(:has(.app-header-search:focus-within)) .site-footer {
    filter: blur(12px);
    transition: filter 300ms ease;
  }

}

/* The container under the bar: the one content width, centred, starting
   where the bar's own height ends. */
.app-main {
  width: min(calc(100% - var(--page-gutter) * 2), var(--site-content-max));
  margin-inline: auto;
  padding-top: max(calc(var(--site-menu-pad-y) * 2 + var(--site-menu-font-size) * 1.5), var(--app-header-search-clearance, 0px));
}

body.app-dashboard {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

body.app-dashboard > :is([data-page-content], .ranking-app) {
  flex: 1;
}

.app-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Dashboard content is a workspace, so its width grows with the viewport. */
.app-dashboard .app-main {
  width: min(80vw, calc(100% - var(--page-gutter) * 2));
}

/* Garden, Live, and Network use the header's gutter on both sides. Keep this
   on shared dashboard selectors so Playground retains its narrower workspace. */
body.app-dashboard .app-main,
.console.app-dashboard .app-main {
  width: calc(100% - var(--page-gutter) * 2);
}

body.app-dashboard .app-footer,
.console.app-dashboard .app-footer {
  width: calc(100% - var(--page-gutter) * 2);
}

.app-footer {
  width: min(80vw, calc(100% - var(--page-gutter) * 2));
  margin: 0 auto;
  padding: 24px 0 36px;
  border-top: 1px solid var(--app-rule, rgb(5 5 5 / 16%));
  color: var(--app-ink);
  font-size: 13px;
  line-height: 1.35;
}

.app-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-footer a {
  color: inherit;
  opacity: 0.62;
  text-decoration: none;
}

.app-footer a:is(:hover, :focus-visible),
.app-footer a[aria-current="page"] {
  opacity: 1;
}

/* Shared dashboard table: frame, rows, typography and heading controls.
   Only real tables receive a frame; Playground's media log is a link list. */
.app-table:has(> table) {
  width: 100%;
  overflow-x: auto;
  border: 0.5px solid var(--app-ink);
  border-radius: 16px;
}

.app-table { background: var(--app-ground); color: var(--app-ink); }

.app-table.user-table caption { padding: 12px clamp(10px, 1.2vw, 16px); text-align: left; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; }
.app-table.user-table table { min-width: 960px; }
.app-table.user-table th:nth-child(1) { width: 26%; }
.app-table.user-table th:nth-child(2) { width: 18%; }
.app-table.user-table th:nth-child(n + 3) { width: 14%; }

.app-table thead th, .app-table tbody td { border-bottom: 0.5px solid var(--app-ink); }
.app-table tbody tr:last-child td { border-bottom: 0; }

.table-sort-heading { white-space: nowrap; }
.table-sort-button {
  display: inline-flex;
  align-items: baseline;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: inherit;
  cursor: pointer;
}
.table-sort-button:is(:hover, :focus-visible) { text-decoration: underline; text-underline-offset: 4px; }
.table-sort-button:focus-visible, .table-header-filter:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }
.table-sort-direction { white-space: pre; }
.table-filter-heading { min-width: 100px; white-space: nowrap; }
.table-filter-trigger {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  max-width: 100%;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  white-space: nowrap;
  cursor: pointer;
}
.table-filter-trigger::after {
  content: "";
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.table-filter-trigger:is(:hover, :focus-within) .table-filter-caption,
.table-filter-trigger.is-active .table-filter-caption {
  text-decoration: underline;
  text-underline-offset: 4px;
}
.table-filter-trigger:focus-within { outline: 1px solid currentColor; outline-offset: 3px; }
.table-filter-caption { display: block; }
.table-header-filter {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
}

.app-table table {
  font: 400 16px/1.35 "Newfoundation Whyte", sans-serif;
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
}

.app-table :is(th, td) {
  height: auto;
  padding: 10px clamp(10px, 1.2vw, 16px);
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.app-table thead th {
  background: var(--app-ground);
  color: var(--app-ink);
  font: inherit;
  text-transform: none;
}

.app-table tbody tr {
  cursor: pointer;
}

.app-table tbody tr:hover td {
  background: var(--app-ink);
  color: var(--app-ground);
}

.app-table .number {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* The card a dashboard sets a figure or an account in: the Network's account
   card, and every tile of Garden's dashboard. */
.app-card {
  padding: clamp(24px, 2.4vw, 34px);
  border: 0.5px solid var(--app-ink);
  border-radius: clamp(20px, 2vw, 30px);
  background: var(--app-ground);
}

/* The one button: the Network card's pill, inverting on hover. */
.app-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 18px;
  border: 0.5px solid currentColor;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.app-button:is(:hover, :focus-visible) {
  background: var(--app-ink);
  color: var(--app-ground);
  outline: 0;
}

.app-button:disabled {
  border-style: dashed;
  background: transparent;
  color: inherit;
  cursor: default;
}

@media (max-width: 799px) {
  :root {
    --site-menu-pad-y: 16.9px;
    --site-menu-font-size: 21.5px;
    --site-container-gutter: 14px;
  }

  /* On a phone the menu is not a hover: the panel fills the screen, the rows
     become the page, and a button opens it. */
  body.is-site-menu-open {
    overflow: hidden;
  }

  .site-menu-hover-strip {
    display: none;
    pointer-events: none;
  }

  .site-menu-panel {
    inset: 0;
    height: 100vh;
    border-radius: 0;
    background: var(--app-ground);
    box-shadow: none;
    opacity: 0;
    transform: translateY(-100%);
    transition:
      opacity 0ms linear 520ms,
      transform 560ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  body:not(.is-site-menu-open):has(.site-header:focus-within) .site-menu-panel {
    opacity: 0;
    transform: translateY(-100%);
  }

  body.is-site-menu-open .site-menu-panel {
    opacity: 1;
    transform: translateY(0);
    transition:
      opacity 0ms linear,
      transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .site-menu-toggle {
    position: fixed;
    z-index: 62;
    top: calc(var(--site-menu-pad-y) - 12px);
    right: var(--site-container-gutter);
    display: inline-grid;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    place-items: center;
    mix-blend-mode: difference;
  }

  /* A named surface reserves the centre for its label on narrow screens. */
  .site-header:has(.brand__name) .site-audio-toggle {
    left: auto;
    right: calc(var(--site-container-gutter) + 44px);
    transform: none;
  }

  .site-header .brand__name {
    font-size: clamp(14px, 4vw, 21px);
  }

  .site-nav {
    position: fixed;
    inset: 0;
    display: grid;
    width: 100%;
    grid-template-columns: minmax(0, 1fr);
    overflow-y: auto;
    padding: clamp(72px, 13vh, 112px) max(28px, var(--site-container-gutter))
      clamp(32px, 8vh, 72px);
    align-items: safe center;
    justify-items: center;
    color: var(--app-ink);
    mix-blend-mode: normal;
    pointer-events: none;
    visibility: hidden;
  }

  body.is-site-menu-open .site-nav {
    pointer-events: auto;
    visibility: visible;
  }

  .site-nav__list {
    width: min(100%, 560px);
    gap: clamp(4px, 1.4vh, 10px);
    align-items: stretch;
    font-size: inherit;
    line-height: 0.96;
    text-align: left;
  }

  .site-nav__item--home {
    display: flex;
  }

  .site-nav__item--menu {
    justify-content: stretch;
  }

  .site-nav__item--menu .site-nav__link,
  .site-nav__item--home .site-nav__link {
    display: flex;
    width: 100%;
    min-height: clamp(42px, 6.2vh, 58px);
    padding: 0.02em 0;
    align-items: center;
    justify-content: flex-start;
    font-size: clamp(29px, 9vw, 67px);
    color: var(--app-ink);
    line-height: 0.94;
    opacity: 0;
    pointer-events: none;
    text-align: left;
    transform: translateY(var(--site-menu-reveal-offset));
    transition:
      opacity var(--site-menu-reveal-opacity),
      transform var(--site-menu-reveal-transform);
    transition-delay: calc(var(--nav-reverse-index) * var(--site-menu-hide-stagger));
  }

  body.is-site-menu-open .site-nav__item--menu .site-nav__link,
  body.is-site-menu-open .site-nav__item--home .site-nav__link {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
    transition-delay: calc(var(--site-menu-reveal-start) + var(--nav-index) * var(--site-menu-reveal-stagger));
  }

  body.is-site-menu-open .site-nav__item--menu .site-nav__link:is(:hover, :focus-visible),
  body.is-site-menu-open .site-nav__item--menu .site-nav__link[aria-current="page"]:is(:hover, :focus-visible) {
    opacity: var(--nav-link-hover-opacity);
  }

  /* Over the sections rather than beside them. Going back to the sections
     is a cut, the way the menu itself closes on a phone. */
  .site-subnav {
    position: absolute;
    inset: 0;
    width: 100%;
    min-height: 100%;
    padding: clamp(112px, 16vh, 140px) max(28px, var(--site-container-gutter))
      clamp(32px, 8vh, 72px);
    overflow-y: auto;
    align-content: start;
    background: var(--app-ground);
    color: var(--app-ink);
    transition: none;
  }

  .site-subnav__list {
    width: min(100%, 560px);
    margin-inline: auto;
    gap: clamp(4px, 1.4vh, 10px);
    line-height: 0.96;
    text-align: left;
  }

  .site-subnav .site-subnav__link {
    min-height: clamp(42px, 6.2vh, 58px);
    padding: 0.02em 0;
    font-size: clamp(29px, 9vw, 67px);
    line-height: 0.94;
    text-align: left;
    transform: translateY(28px);
    transition: opacity 420ms ease, transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--nav-reverse-index) * 28ms);
  }

  body.is-site-menu-open .site-nav[data-menu-active] .site-subnav__list:not(.is-entering, .is-leaving) .site-subnav__link {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
    transition-delay: calc(140ms + var(--nav-index) * 56ms);
  }

  .site-subnav__back {
    position: absolute;
    top: 66px;
    left: max(28px, var(--site-container-gutter));
    display: block;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 16px;
    cursor: pointer;
  }


  /* Application surfaces run on the homepage's phone gutter. Scoped rather
     than set on :root because the site header keeps its own. */
  .app-bar,
  .app-main {
    --page-gutter: 14px;
  }

  /* Dense application navigation keeps its links on a second phone row. */
  .app-bar--wrap { flex-wrap: wrap; row-gap: 12px; }
  .app-bar--wrap .app-breadcrumb { font-size: 16px; }
  .app-bar--wrap .app-bar__actions {
    flex-basis: 100%;
    justify-content: flex-end;
    font-size: 16px;
  }
  body:has(> .app-bar--wrap) .app-main { --app-header-search-clearance: 100px; }


  .app-dashboard .app-main,
  .app-footer,
  body.app-dashboard .app-main,
  body.app-dashboard .app-footer,
  .console.app-dashboard .app-main,
  .console.app-dashboard .app-footer {
    width: calc(100% - 28px);
  }

  body.app-dashboard .site-header .brand,
  body:has(.playground-shell.app-dashboard) .site-header .brand {
    left: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-menu-panel,
  .site-audio-toggle,
  .site-menu-toggle,
  .site-nav,
  .site-nav__link {
    transition: none;
  }

  /* The section rules above are specific enough to outrank the line before. */
  .site-subnav,
  .site-subnav .site-subnav__link {
    transition: none !important;
  }
}

/* Shared payment refusals for Live and Network searches. */
.charge-notice { margin: 18px 0; }
.charge-notice p { margin: 0 0 10px; }
.charge-notice__actions { display: flex; flex-wrap: wrap; gap: 10px; }
.charge-notice__actions .outline-button { display: inline-flex; align-items: center; text-decoration: none; }
.charge-notice__actions .outline-button {
  padding: 8px 16px;
  border: 1px solid currentColor;
  border-radius: 999px;
  color: inherit;
  background: transparent;
  font: inherit;
  cursor: pointer;
}

.app-search-field { display: block; }
.app-search-field:not(.app-header-search) { width: 100%; }
.app-search-field textarea { box-sizing: border-box; width: 100%; min-height: 92px; padding: 16px 18px; border: 1px solid var(--ds-rule); border-radius: 14px; resize: vertical; background: var(--app-ground); color: var(--app-ink); font: 300 clamp(20px, 2.2vw, 28px)/1.3 "Newfoundation Whyte", sans-serif; }
.app-search-field textarea::placeholder { color: var(--ds-quiet); opacity: 1; }
.app-search-field textarea:focus-visible { outline: 2px solid var(--app-ink); outline-offset: 2px; }
.app-list-scroll [data-list-status] { margin-inline: 12px; font-size: 13px; }
.table-filter-trigger[data-app-dropdown-ready]::after,
.table-filter-trigger[data-app-dropdown-ready] .table-filter-caption { display: none; }
/* Panorama is the explicit fullscreen shell exception: its rail replaces
   the marketing bar and footer. These rules are inert on ordinary pages. */
.app-panorama {
  --app-ground: #fff;
  --app-ink: #050505;
  --app-rule: #d5d5d1;
  --ds-ground: var(--app-ground);
  --ds-ink: var(--app-ink);
  --ds-quiet: color-mix(in srgb, var(--app-ink) 62%, var(--app-ground));
  --ds-soft: color-mix(in srgb, var(--app-ink) 8%, var(--app-ground));
  --ds-rule: var(--app-rule);
  --panorama-rail-width: 184px;
  display: grid;
  grid-template-columns: var(--panorama-rail-width) minmax(0, 1fr);
  min-width: 0;
  height: 100dvh;
  margin: 0;
  overflow: hidden;
  background: var(--app-ground);
  color: var(--app-ink);
  font: 400 16px/1.35 "Newfoundation Whyte", Arial, sans-serif;
}
.app-panorama *, .app-panorama *::before, .app-panorama *::after { box-sizing: border-box; }
.app-panorama [hidden] { display: none !important; }
.app-panorama :is(button, input, textarea, select) { font: inherit; }
.app-panorama :is(a, button, input, select, textarea):where(:not([data-panorama-search])):focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.app-panorama .brand { mix-blend-mode: normal; }
.app-panorama .brand__glyph { width: 28px; height: 28px; margin: 0; filter: none; transform: none; }
.panorama-rail { position: relative; z-index: 30; display: flex; flex-direction: column; gap: 22px; min-height: 0; padding: 28px 0 16px 16px; background: var(--app-ground); overflow-y: auto; }
.panorama-brand { display: inline-flex; align-items: center; width: 44px; min-height: 44px; padding-left: 8px; }
/* Average of the former 4px main-row and 40px Briefing/Saved gaps. */
.panorama-destinations, .panorama-saved, .panorama-post, .panorama-utilities { display: grid; gap: 22px; }
.panorama-profile { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; color: inherit; background: transparent; }
.panorama-profile img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; }
.panorama-profile svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.panorama-utilities { margin-top: auto; }
.panorama-nav-link { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; padding: 8px; border: 0; border-radius: 12px; background: transparent; color: color-mix(in srgb, var(--app-ink) 80%, transparent); font: inherit; text-align: left; text-decoration: none; cursor: pointer; transition: background-color 220ms ease, color 220ms ease; }
.panorama-nav-link[aria-current="page"] { color: var(--app-ink); font-weight: 500; }
.panorama-nav-link:is(:hover, :focus-visible) { background: #f1f1f1; }
.panorama-nav-icon { display: inline-grid; place-items: center; flex: 0 0 28px; width: 28px; height: 28px; object-fit: contain; }
svg.panorama-nav-icon, .panorama-topbar svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.panorama-account-status { margin: 4px 8px; font-size: 14px; }
.panorama-workspace { position: relative; min-width: 0; min-height: 0; overflow: auto; outline: 0; }
.panorama-research-card { --app-ground: #000; --app-ink: #fff; --app-rule: #ffffff38; --ds-ground: #000; --ds-ink: #fff; --ds-soft: #262626; --ds-segmented-ground: #000; --ds-segmented-selected-ground: #000; --ds-segmented-selected-ink: #fff; --ds-quiet: #ffffffb8; --ds-rule: #ffffff38; margin: 16px; border-radius: var(--site-radius); background: #000; color: #fff; isolation: isolate; container-type: inline-size; }
.panorama-research-card > .app-main { width: 100%; max-width: none; margin: 0; padding: 24px; }
.panorama-research-card .earth-page { height: 100%; padding: 0; }
.app-panorama:has(.earth-page) { background: var(--app-ground); color: var(--app-ink); }
.panorama-research-card .earth-content { height: 100%; min-height: 0; }
.panorama-research-card .earth-map__fallback { width: min(63cqw, 720px); }
.panorama-research-card :is(.earth-activity, .earth-entities) { width: min(340px, calc((100% - 72px) / 2)); }
.panorama-workspace:has(.live-saved-page) { padding: 24px; }
.panorama-missing { padding: 24px; }
.panorama-workspace .live-saved-page.app-main { width: 100%; max-width: none; margin: 0; padding: 0; }
.panorama-topbar, .panorama-drawer-shade { display: none; }
.panorama-skip { position: fixed; z-index: 60; left: 16px; top: 8px; padding: 12px; transform: translateY(-200%); background: var(--app-ground); }
.panorama-skip:focus { transform: none; }
.panorama-outline-card { margin: 16px; border: 1px solid var(--app-rule); border-radius: var(--site-radius); background: var(--app-ground); overflow: hidden; isolation: isolate; }
.panorama-research-card, .panorama-outline-card { animation: panorama-shell-enter 220ms ease-out both; }
@keyframes panorama-shell-enter { from { opacity: 0; transform: translateY(6px); } }
@media (max-width: 1023px) and (min-width: 768px) {
  .app-panorama { --panorama-rail-width: 76px; }
  .panorama-nav-link > span:not(.panorama-nav-icon) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .panorama-brand { padding-left: 8px; }
}
@media (max-width: 767px) {
  .app-panorama { display: block; height: auto; min-height: 100dvh; overflow: visible; padding-top: 64px; }
  .panorama-topbar { position: fixed; inset: 0 0 auto; z-index: 35; display: flex; align-items: center; gap: 16px; height: 64px; padding: 10px 14px; border-bottom: 1px solid var(--app-rule); background: var(--app-ground); }
  .panorama-topbar .brand { display: grid; place-items: center; width: 44px; min-height: 44px; }
  .panorama-topbar button { width: 44px; height: 44px; margin-left: auto; }
  .panorama-topbar svg { width: 24px; height: 24px; }
  .panorama-rail { position: fixed; inset: 64px auto 0 0; z-index: 40; width: min(280px, calc(100vw - 44px)); padding-top: 16px; padding-right: 16px; transform: translateX(-101%); transition: transform 220ms ease; visibility: hidden; }
  .panorama-brand { display: none; }
  .app-panorama[data-panorama-drawer] .panorama-rail { transform: none; visibility: visible; }
  .app-panorama[data-panorama-drawer] .panorama-drawer-shade { position: fixed; inset: 64px 0 0; z-index: 39; display: block; width: 100%; border: 0; background: #0005; }
  .panorama-workspace { overflow: visible; min-height: calc(100dvh - 64px); }
  .panorama-outline-card { margin: 14px; min-height: calc(100dvh - 92px); }
  .panorama-research-card { margin: 14px; height: calc(100dvh - 92px); min-height: 0; overflow: auto; }
  .panorama-research-card > .app-main { padding: 16px; }
  .panorama-research-card .earth-page { padding: 0; height: calc(100dvh - 92px); }
  .panorama-research-card :is(.earth-activity, .earth-entities) { width: calc((100% - 34px) / 2); }
  .panorama-workspace:has(.live-saved-page) { padding: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .app-panorama .panorama-rail, .app-panorama .panorama-nav-link { transition: none; }
  .app-panorama :is(.panorama-research-card, .panorama-outline-card) { animation: none; }
}

/* One design pixel at 1440px; dimensions absorb 35% of viewport-width change. */
:root { --ui-responsive-unit:calc(0.65px + 35vw / 1440); }

/* Panorama public arrival is the fullscreen counterpart of its member shell. */
.panorama-public { box-sizing:border-box; margin:0; background:#f5f5f3; color:#050505; font:400 16px/1.35 "Newfoundation Whyte",Arial,sans-serif; }
.panorama-public *, .panorama-public *::before, .panorama-public *::after { box-sizing:border-box; }
.panorama-public [hidden] { display:none!important; }
.panorama-public :is(a,button):focus-visible { outline:2px solid currentColor; outline-offset:4px; }
.panorama-public--landing {
 --panorama-card-frame:calc(16 * var(--ui-responsive-unit));
 --panorama-card-padding:max(calc(32 * var(--ui-responsive-unit)),env(safe-area-inset-top),env(safe-area-inset-right),env(safe-area-inset-bottom),env(safe-area-inset-left));
 --panorama-control-size:max(44px,calc(44 * var(--ui-responsive-unit)));
 --panorama-menu-row:max(32px,calc(32 * var(--ui-responsive-unit)));
 --panorama-menu-offset:max(44px,calc(60 * var(--ui-responsive-unit)));
 --panorama-title-size:calc(112.32 * var(--ui-responsive-unit));
 --site-menu-font-size:calc(21.5 * var(--ui-responsive-unit));
 --site-radius:calc(26 * var(--ui-responsive-unit));
 --bottom-rhythm-gap:calc(192 * var(--ui-responsive-unit));
 padding:var(--panorama-card-frame); font-size:max(14px,calc(16 * var(--ui-responsive-unit))); font-weight:500;
}
html.panorama-public-document { scroll-behavior:smooth; }
.panorama-landing { position:relative; display:grid; place-items:center; height:calc(100dvh - 2 * var(--panorama-card-frame)); min-height:240px; overflow:hidden; border-radius:var(--site-radius,26px); background:#000; color:#fff; isolation:isolate; }
.panorama-landing-video, .panorama-landing-shade { position:absolute; inset:0; width:100%; height:100%; }
.panorama-landing-video { object-fit:cover; }
.panorama-landing-shade { background:rgb(0 0 0 / 42%); }
.panorama-landing h1 { position:relative; margin:0; font-size:min(var(--panorama-title-size),calc((100vw - 2 * var(--panorama-card-frame) - 2 * var(--panorama-card-padding)) / 5)); line-height:1.07; font-weight:inherit; }
.panorama-public .panorama-landing-signin { position:absolute; right:var(--panorama-card-padding); bottom:var(--panorama-card-padding); min-height:var(--panorama-control-size); padding:calc(12 * var(--ui-responsive-unit)) calc(24 * var(--ui-responsive-unit)); font-size:max(13px,calc(13 * var(--ui-responsive-unit))); background:#fff; color:#000; border-color:#fff; }
.panorama-public .panorama-landing-motion { position:absolute; left:var(--panorama-card-padding); bottom:var(--panorama-card-padding); width:var(--panorama-control-size); height:var(--panorama-control-size); color:#fff; }
.panorama-landing-motion svg { width:calc(20 * var(--ui-responsive-unit)); height:calc(20 * var(--ui-responsive-unit)); stroke:currentColor; stroke-width:2; fill:none; }
.panorama-public-bar { display:flex; justify-content:space-between; align-items:center; padding:16px 24px; gap:24px; }
.panorama-public-bar .ds-button { min-height:44px; }
.panorama-public-bar > a:first-child { color:inherit; text-decoration:none; }
.panorama-public-page { margin:0 16px 16px; padding:24px; border-radius:var(--site-radius,26px); min-height:calc(100dvh - 108px); background:#000; color:#fff; }
.panorama-public-page .app-main { margin:0; width:100%; max-width:none; padding:0; }
@media (max-width:767px) {
 .panorama-public-bar { padding:14px; }
 .panorama-public-page { margin-inline:14px; padding:16px; }
}

/* Video controls keep a fixed appearance, including the 17% playback ground. */
.panorama-public .panorama-landing .ds-icon-button { background: transparent; }
.panorama-public .panorama-landing .panorama-landing-motion { background: rgb(0 0 0 / 17%); }

/* Public Panorama uses the same mark and controls as the research shell. */
/* Align visible corner content to one fluid inset; targets retain a 44px minimum. */
.panorama-public-navigation { position:fixed; inset:var(--panorama-card-frame); z-index:20; display:flex; justify-content:space-between; align-items:flex-start; gap:calc(24 * var(--ui-responsive-unit)); padding:var(--panorama-card-padding); color:#050505; pointer-events:none; }
.panorama-public-navigation .brand { margin:calc((28 * var(--ui-responsive-unit) - var(--panorama-control-size)) / 2) 0 0 calc((28 * var(--ui-responsive-unit) - var(--panorama-control-size)) / 2); z-index:2; display:grid; place-items:center; width:var(--panorama-control-size); height:var(--panorama-control-size); mix-blend-mode:normal; pointer-events:auto; }
.panorama-public-navigation .brand__glyph { width:calc(28 * var(--ui-responsive-unit)); height:calc(28 * var(--ui-responsive-unit)); margin:0; filter:none; transform:none; }
.panorama-public-navigation .site-menu-toggle { position:relative; inset:auto; right:calc((18 * var(--ui-responsive-unit) - var(--panorama-control-size)) / 2); top:calc((2 * var(--ui-responsive-unit) - var(--panorama-control-size)) / 2 + 6 * var(--ui-responsive-unit)); z-index:2; display:grid; place-items:center; width:var(--panorama-control-size); height:var(--panorama-control-size); min-width:44px; padding:0; color:inherit; mix-blend-mode:normal; }
.panorama-public-navigation .site-menu-toggle span { width:calc(18 * var(--ui-responsive-unit)); height:calc(2 * var(--ui-responsive-unit)); }
.panorama-public-navigation .site-menu-toggle span::before { width:inherit; height:inherit; transform:translateY(calc(-6 * var(--ui-responsive-unit))); }
.panorama-public-navigation[data-panorama-surface="video"] { color:#fff; }
.panorama-public-navigation[data-panorama-surface="video"] .brand__glyph { filter:invert(1); }
.panorama-feature { min-height:calc(100dvh - 2 * var(--panorama-card-frame)); margin-top:var(--panorama-card-frame); padding:calc(var(--panorama-card-padding) + var(--panorama-menu-offset) + 4 * var(--panorama-menu-row) + 24 * var(--ui-responsive-unit)) var(--panorama-card-padding) calc(96 * var(--ui-responsive-unit)); display:grid; place-items:center; background:#fff; border-radius:var(--site-radius,26px); scroll-margin-top:var(--panorama-card-frame); font-size:var(--site-menu-font-size); line-height:1.07; }
.panorama-feature__copy { width:min(100%,calc(720 * var(--ui-responsive-unit))); }
.panorama-feature h2 { margin:0 0 calc(32 * var(--ui-responsive-unit)); font:inherit; }
.panorama-feature p { margin:0; }
.panorama-feature-menu { position:absolute; inset:0; z-index:1; display:grid; align-items:start; justify-items:end; padding:calc(var(--panorama-card-padding) + var(--panorama-menu-offset)) var(--panorama-card-padding) calc(100 * var(--ui-responsive-unit)); overflow-y:auto; color:inherit; pointer-events:none; visibility:hidden; transition:visibility 0s linear 720ms; }
.panorama-feature-menu ul { width: min(100%, 560px); display: flex; flex-direction: column; gap: 0; align-items: flex-end; padding: 0; margin: 0; list-style: none; }
.panorama-public .panorama-feature-menu a { display: flex; align-items: center; width: fit-content; max-width: 100%; min-height: var(--panorama-menu-row); padding: .02em 0; color: inherit; font-size: var(--site-menu-font-size); font-weight: inherit; line-height: .9; text-decoration: none; opacity: 0; transform: translateY(calc(-1 * var(--site-menu-reveal-offset))); transition: opacity var(--site-menu-reveal-opacity), transform var(--site-menu-reveal-transform); transition-delay: calc(var(--nav-index) * var(--site-menu-hide-stagger)); }
.panorama-public.is-site-menu-open { overflow:auto; }
.panorama-public.is-site-menu-open .panorama-feature-menu { visibility: visible; transition-delay: 0s; }
.panorama-public.is-site-menu-open .panorama-feature-menu a { opacity: 1; transform: translateY(0); pointer-events: auto; transition-delay: calc(var(--site-menu-reveal-start) + var(--nav-index) * var(--site-menu-reveal-stagger)); }
@media (prefers-reduced-motion: reduce) {
  html.panorama-public-document { scroll-behavior:auto; }
  .panorama-feature-menu, .panorama-public .panorama-feature-menu a, .site-menu-toggle span, .site-menu-toggle span::before { transition: none; }
}
