/* ============================================================
   Type scale correction.

   Material sets html{font-size:20px}, so every rem here rendered 25% larger
   than the marketing site, whose html stays at the 16px default. Rather than
   rewrite every value, load the fonts properly and state the sizes in px so
   both sites agree.
   ============================================================ */

/* The fonts are loaded by link tags in overrides/main.html: an @import is only
   honoured at the very top of the FIRST stylesheet, and this file loads second. */

/* Shared site footer (every page). Self-contained: no dependency on .homepage or page-level vars. */
.footer--site {
  --f-bg: #1f1e1c; --f-text: #f4f2eb; --f-muted: #b8b6ae; --f-dim: #93918a; --f-label: #8d8b84; --f-accent: #ceccc8;
  --f-font: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  margin-top: clamp(6rem, 12vw, 10rem);
  padding: clamp(5.5rem, 11vw, 10rem) 0 1.5rem;
  background: var(--f-bg) !important;
  border: 0 !important;
  color: var(--f-text) !important;
  font-family: var(--f-font);
}
.footer--site .footer-shell {
  width: min(100% - 48px, 76rem);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(17rem, 1.15fr) minmax(0, 2.2fr);
  gap: clamp(3rem, 9vw, 8rem);
  align-items: start;
}
.footer--site .footer-intro { max-width: 24rem; }
footer.footer--site .logo {
  display: inline-flex !important;
  color: var(--f-text) !important;
  font-family: var(--f-font) !important;
  font-size: clamp(1.75rem, 3vw, 2.25rem) !important;
  font-weight: 600 !important;
  letter-spacing: -.045em !important;
  line-height: 1 !important;
  text-decoration: none !important;
  -webkit-text-fill-color: currentColor !important;
  background: none !important;
}
footer.footer--site .logo strong { font-weight: 600 !important; color: var(--f-text) !important; -webkit-text-fill-color: currentColor !important; }
footer.footer--site .logo span { color: var(--f-accent) !important; font-weight: 400 !important; -webkit-text-fill-color: currentColor !important; }
/* The wordmark image, sized as on 1p.dev (styles-v9.css). Without this it
   renders at its natural 925px and sits over the link columns. */
footer.footer--site .logo { display: block !important; line-height: 0 !important; }
footer.footer--site .footer-wordmark { display: block; height: 6.5rem; width: auto; max-width: 100%; }
.footer--site .footer-intro > p {
  margin: 1.65rem 0 0;
  color: var(--f-muted) !important;
  font-family: var(--f-mono, 'JetBrains Mono', ui-monospace, monospace);
  font-size: 1rem;
  letter-spacing: -.01em;
  line-height: 1.6;
}
.footer--site .footer-start {
  display: inline-flex; gap: .6rem; margin-top: 2rem;
  color: var(--f-text) !important;
  font-family: var(--f-font); font-size: .95rem; font-weight: 600; text-decoration: none;
}
.footer--site .footer-start span { color: var(--f-accent); transition: transform .2s ease; }
.footer--site .footer-start:hover span { transform: translateX(.2rem); }
/* The 6.5rem track floor could not shrink, so below about 1620px the five
   columns demanded more width than the container had and punched out of the
   viewport (245px of horizontal scroll at 1025px). minmax(0, 1fr) lets them
   shrink.
   `min-width: 0` on the child defeats the default `min-width: auto` on a grid
   item, without which a long link re-inflates the track. */
.footer--site .footer-nav {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(1.75rem, 4vw, 4rem);
  padding-top: .9rem;
}
.footer--site .footer-group { min-width: 0; }
footer.footer--site .footer-group h2 {
  margin: 0 0 1.25rem !important;
  color: var(--f-label) !important;
  font-family: var(--f-font) !important;
  font-size: .68rem !important;
  font-weight: 500 !important;
  letter-spacing: .18em !important;
  text-transform: uppercase !important;
  line-height: 1 !important;
  -webkit-text-fill-color: currentColor !important;
  background: none !important;
}
.footer--site .footer-group a {
  display: block; width: max-content; max-width: 100%;
  margin: 0 0 .8rem;
  color: #e1dfd8 !important;
  font-family: var(--f-font); font-size: .95rem; line-height: 1.35; text-decoration: none;
  transition: color .15s ease;
}
.footer--site .footer-group a:hover,
.footer--site .footer-start:hover { color: var(--f-accent) !important; }
.footer--site a:focus-visible { outline: 2px solid var(--f-accent); outline-offset: 4px; }
.footer--site .footer-meta {
  width: min(100% - 48px, 76rem);
  margin: clamp(5rem, 10vw, 9rem) auto 0;
  padding-top: 1.2rem;
  border-top: 1px solid rgba(244, 242, 235, .15);
  display: flex; justify-content: space-between; gap: 1rem;
}
.footer--site .footer-meta p {
  margin: 0; color: var(--f-dim) !important;
  font-family: var(--f-font); font-size: .75rem; line-height: 1.5;
}
/* Five columns stop being readable well before 900px: at 1025px they are 76px
   wide and the longer labels clip. Drop to two columns at the same 1220px
   boundary the rest of the theme uses. */
@media (max-width: 1219px) {
  .footer--site .footer-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.5rem 1.5rem; }
}
@media (max-width: 900px) {
  .footer--site .footer-shell { grid-template-columns: 1fr; gap: 3.5rem; }
}
@media (max-width: 760px) {
  .footer--site { padding-top: 5rem; }
  .footer--site .footer-shell, .footer--site .footer-meta { width: min(100% - 36px, 76rem); }
  .footer--site .footer-meta { margin-top: 4rem; display: block; }
  .footer--site .footer-meta p + p { margin-top: .35rem; }
}
@media (max-width: 480px) {
  .footer--site .footer-nav { grid-template-columns: 1fr; gap: 2rem; }
}


/* ---- Header: the menu of 1p.dev ----
   As on 1p.dev (.nav and .nav-menu in site/assets/site.css) there is no bar and
   no band across the page. The header is see-through, the red logo stands on
   its own at the left, and the site links and the Login button float on the
   right in one frosted pill: the page colour at 74% over a blur of whatever
   scrolls beneath, no border, the site's panel shadow and squircle corners.
   The template script moves the links (.esb-shell) onto the header row from
   1220px, and into their own row (.p1-sitebar) under it below that. Sizes are
   in px, because Material sets a 20px root. */

/* hidden until the script has decided where the links live, to avoid a flash */
.p1-sitebar:not(.is-ready) { display: none; }
.p1-sitebar.is-ready { display: none; }   /* wide screens: links are in the header */

.md-header {
  background: transparent !important;
  border-bottom: 0 !important;
  box-shadow: none !important;
}
.md-header__inner { height: var(--nav-h); }

/* the pill: on the header row, and in the row under it down to 769px */
.md-header__inner .esb-shell,
.p1-sitebar .esb-shell {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2vw, 28px);
  flex: none;
  width: auto;
  height: var(--nav-pill-h);
  margin-left: auto;
  padding: 0 5px 0 32px;
  border-radius: 999px;
  corner-shape: squircle;
  background: var(--nav-glass);
  -webkit-backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
  backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
  box-shadow: var(--sh-2);
}

/* the labels: Hanken Grotesk, medium; the current one bold */
/* the little red heart before Being good, as on 1p.dev */
.esb-shell > a[href$="#being-good"] { position: relative; margin-left: 1.15em; }
.esb-shell > a[href$="#being-good"]::before { content: "\2764\FE0E"; position: absolute; left: -1.55em; top: 50%; margin-top: -.5em; line-height: 1; font-size: .78em; color: #e5484d; animation: heart-beat 4.5s ease-in-out infinite; transform-origin: 50% 60%; }
@keyframes heart-beat { 0%, 20%, 100% { transform: scale(1); } 5% { transform: scale(1.18); } 10% { transform: scale(1); } 15% { transform: scale(1.12); } }
@media (prefers-reduced-motion: reduce) { .esb-shell > a[href$="#being-good"]::before { animation: none; } }
.esb-shell > a:not(.esb-cta),
.esb-group > summary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--f-body);
  font-size: var(--t-nav);
  font-weight: 500;
  line-height: 1.6;   /* 1p.dev's (its body's): with the same line box the letters land on the same pixel row. With
                         "normal" they sat a tenth of a pixel lower, which the browser could round to a whole pixel or two */
  letter-spacing: normal;
  color: var(--c-ink);
  white-space: nowrap;
  text-decoration: none;
  transition: color .18s ease;
}
.esb-shell > a:not(.esb-cta):hover,
.esb-group > summary:hover { color: var(--c-purple); }
.esb-group.has-current > summary { color: var(--c-ink); font-weight: 700; }
/* every label keeps room for its bold self (a hidden bold copy under it, with
   no height), so marking one never nudges the others along */
.esb-shell > a[data-label],
.esb-group-text[data-label] { display: inline-flex; flex-direction: column; align-items: center; gap: 0; }
.esb-shell > a[data-label]::after,
.esb-group-text[data-label]::after {
  content: attr(data-label) / "";
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
  pointer-events: none;
  user-select: none;
}

/* Information, the group that holds Docs: a <details>. The template script adds
   Escape, click-outside and the transition, and reads the closing time here. */
.esb-group { position: relative; flex: none; --esb-dropdown-close-dur: .18s; }
.esb-group > summary { list-style: none; cursor: pointer; }
.esb-group > summary::-webkit-details-marker { display: none; }
.esb-group > summary::marker { content: ""; }
.esb-group > summary:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 3px; border-radius: 6px; }
.esb-group-label { display: inline-flex; align-items: center; gap: 4px; }
.esb-chev { flex: none; opacity: .7; transition: transform .35s cubic-bezier(.22,1,.36,1); }
.esb-group[open] .esb-chev { transform: rotate(180deg); opacity: 1; }
.esb-group:not([open]) .esb-panel { display: none; }
.esb-panel {
  position: absolute;
  z-index: 120;
  top: calc(100% + 12px);
  left: 50%;
  translate: -50% 0;
  min-width: 200px;
  padding: 8px;
  background: var(--c-surface);
  border-radius: 14px;
  box-shadow: var(--sh-2);
}
.esb-panel::before { content: ""; position: absolute; left: 0; right: 0; top: -12px; height: 12px; }
/* the dropdowns, Information's and Dashboard's alike, float under the pill as
   panels of their own, as on 1p.dev: white, rounded, the panels' shadow, a small
   gap, and a small nub on top pointing up at their button */
.md-header__inner .esb-group,
.p1-sitebar .esb-group { align-self: stretch; display: flex; align-items: center; }
.md-header__inner .esb-panel,
.p1-sitebar .esb-panel { top: calc(100% + 10px); }
.md-header__inner .account-panel { top: calc(100% + 15px); }
.esb-panel::before, .account-panel::before { top: -16px; height: 16px; }
.esb-panel::after, .account-panel::after {
  content: ""; position: absolute; top: -5px; width: 10px; height: 10px;
  border-radius: 2px 0 0 0; background: inherit; rotate: 45deg;
  box-shadow: -2px -2px 4px -2px rgba(27, 31, 39, .12);
}
.esb-panel::after { left: calc(50% - 5px); }
.account-panel::after { right: 30px; }
.esb-panel a {
  display: block;
  padding: 8px 12px;
  border-radius: 10px;
  font-family: var(--f-body);
  font-size: var(--t-small);
  font-weight: 400;
  line-height: 1.6;
  color: var(--c-ink-2);
  text-decoration: none;
}
.esb-panel a:hover,
.esb-panel a[aria-current] { background: var(--c-lav-soft); color: var(--c-ink); }
.esb-group.t-anim .esb-panel {
  opacity: 0;
  transform: translateY(-4px) scale(.98);
  transform-origin: top center;
  pointer-events: none;
  transition: opacity .18s ease, transform .18s cubic-bezier(.22,1,.36,1);
}
.esb-group.t-anim.is-open .esb-panel { opacity: 1; transform: none; pointer-events: auto; }
.esb-group.t-anim.is-closing .esb-panel { opacity: 0; transform: translateY(-4px) scale(.98); }

/* Login: the dark button inside the pill's right end. account-nav.js (loaded
   from https://1p.dev/) finds it as `.esb-shell .esb-cta`; signed in, it puts a
   "Dashboard" menu (.account-menu) in its place whose button keeps the class.
   The pill's links sit closer together than the button sits to them. */
.esb-shell > .esb-cta,
.esb-shell > .account-menu { margin-left: calc(32px - clamp(18px, 2vw, 28px)); }
.esb-shell .esb-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* (border-box, as on 1p.dev: signed in, the button is the menu's <summary>, which was content-box here, so its
     border came on top of the 42 px and the Dashboard button stood 2 px taller than Login and than 1p.dev's) */
  box-sizing: border-box;
  min-height: 42px;
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: 999px;
  corner-shape: squircle;
  background: var(--c-ink);
  color: #fff;
  font-family: var(--f-body);
  font-size: var(--t-nav);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.esb-shell .esb-cta:hover { background: var(--c-purple); color: #fff; }
/* signed in, the button reads Dashboard, in purple; Login stays black */
.esb-shell .account-menu > summary.esb-cta { background: var(--c-purple); }
.esb-shell .account-menu > summary.esb-cta:hover, .esb-shell .account-menu[open] > summary.esb-cta { background: var(--c-purple-ink); }
.esb-cta .nav-user { flex: none; }   /* (no margin of its own: the same as 1p.dev's, so the two buttons match) */
.esb-cta .nav-chev { flex: none; }
/* while a stored sign-in waits to be drawn, the button stays hidden so "Login"
   never flashes first (the class is set by a script in the template) */
.p1-signed-in .esb-cta { visibility: hidden; }
/* one width whatever it says, as on 1p.dev (site.css, after .p1-signed-in .nav-cta): "Login" holds a hidden
   "Dashboard" with room for the icon (16 px and the 8 px gap) and the chevron (8 px gap, 12 px);
   a "Dashboard" link with no menu takes the chevron's room as padding, half each side. So the pill is the same
   width here as on 1p.dev, signed in or not */
.esb-shell a.esb-cta:not(:has(.nav-user)) { flex-direction: column; gap: 0; }
.esb-shell a.esb-cta:not(:has(.nav-user))::after { content: "Dashboard" / ""; height: 0; overflow: hidden; visibility: hidden; padding: 0 20px 0 24px; }
.esb-shell a.esb-cta:has(.nav-user) { padding-inline: 28px; }

/* Below 1220px the header row holds the logo, search and the button for the
   docs' own navigation, and the menu sits in the row under it: still the pill
   down to 769px, then, as on 1p.dev's phones, no pill. */
@media screen and (max-width: 1219px) {
  /* Above the page and the contents rail (the pill's backdrop filter makes it a
     stacking context of its own, which the sticky rail would otherwise paint
     over), below the header (4) and the navigation drawer (5). */
  .p1-sitebar.is-ready {
    display: flex;
    justify-content: flex-end;
    position: relative;
    z-index: 3;
    padding: 0 clamp(22px, 5vw, 72px);
    background: none !important;
    border: 0 !important;
  }
}
/* On a phone there is no pill: the links stand in a plain row that wraps, so
   Login is always in view, and the panels float as cards. */
@media screen and (max-width: 768px) {
  .p1-sitebar.is-ready { display: block; padding: 0; }
  .p1-sitebar .esb-shell {
    flex-wrap: wrap;
    height: auto;
    margin: 0;
    padding: 2px clamp(22px, 5vw, 72px) 8px;
    gap: 8px 20px;
    border-radius: 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
  }
  .p1-sitebar .esb-shell > * { flex: none; }
  .p1-sitebar .esb-panel {
    top: calc(100% + 8px);
    left: 0;
    translate: none;
    border-radius: 14px;
    background: var(--c-surface);
    box-shadow: var(--sh-2);
  }
  .p1-sitebar .esb-group.t-anim .esb-panel { transform-origin: top left; }
  .p1-sitebar .esb-shell > .esb-cta,
  .p1-sitebar .esb-shell > .account-menu { margin-left: 0; }
  .p1-sitebar .esb-shell .esb-cta { min-height: 36px; padding: 0 12px; }
  .p1-sitebar .esb-shell a.esb-cta:has(.nav-user) { padding-inline: 22px; }
  /* the account list is wider than the room beside the button, so it hangs
     from the row's right edge instead */
  .p1-sitebar .account-menu { position: static; }
  .p1-sitebar .account-panel { top: 100%; right: clamp(22px, 5vw, 72px); }
}
/* Below 960px search opens over the page. The header is see-through, so the
   open search takes the page colour, or the header row would show through
   around the field. */
@media screen and (max-width: 959px) {
  [data-md-toggle=search]:checked ~ .md-header .md-search__inner { background: var(--c-page); }
}

@media screen and (max-width: 1219px) {
  /* Material hides the header logo below its breakpoint, leaving a bare
     hamburger. Put it back, first in the row and on 1p.dev's page margin -- but
     scope every rule to .md-header, because the nav DRAWER reuses .md-logo and
     .md-nav__title and would otherwise get a giant logo and giant headings too. */
  .md-header > .md-header__inner { gap: 0; padding: 0 clamp(22px, 5vw, 72px); }
  .md-header .md-header__button.md-logo {
    display: inline-flex !important;
    align-items: center;
    padding: 0;
    margin: 0;
  }
  /* Search, then the button for the docs' own navigation, at the right; each
     stands on its own like the Menu button on 1p.dev's phones. Material shows
     and hides these by width, so `display` is left to it. */
  .md-header .md-header__button[for=__drawer] { order: 1; }
  .md-header .md-header__button:not(.md-logo) {
    margin: 0 0 0 8px;
    padding: 10px;
    border: 1px solid var(--c-line-2);
    border-radius: 999px;
    background: var(--c-surface);
    color: var(--c-ink);
  }
  .md-header .md-header__button:not(.md-logo) svg { width: 20px; height: 20px; }
  .md-header .md-header__button[for=__search] { margin-left: auto; }

  /* The drawer: keep Material's own sizing, do not inherit the header rules */
  .md-nav--primary .md-nav__title {
    font-size: .72rem !important;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: none;
    /* Material sizes this block for a stacked logo; without one it is 112px of
       empty space at the top of the drawer */
    height: 2.6rem !important;
    min-height: 0 !important;
    line-height: 2.6rem !important;
    padding: 0 .8rem !important;
    background: #fbfbf8;
    color: #0c0c0f;
    box-shadow: none;
    border-bottom: 1px solid rgba(8,9,11,.08);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .md-nav--primary .md-nav__title ~ .md-nav__list { padding-top: .3rem; }
  .md-nav--primary .md-nav__title .md-nav__button.md-logo { display: none !important; }
  .md-nav--primary .md-nav__link {
    font-size: .74rem !important;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    padding: .5rem .8rem;
  }
  .md-nav--primary .md-nav__item--nested > .md-nav__link { font-weight: 600; }

  /* the search box floated mid-header with nothing anchoring it, and stretched
     the full row when given flex:1 */
  /* Below 960px Material shows a search button instead, and the field opens
     over the page, so the box itself must take no room in the row. */
  .md-header__inner .md-search { flex: none; width: 0; margin: 0; }
}
@media screen and (min-width: 960px) and (max-width: 1219px) {
  .md-header__inner .md-search {
    flex: 0 1 auto;
    width: min(20rem, 42vw);
    min-width: 0;
    margin-left: auto;
    margin-right: 0;
  }
}
@media screen and (max-width: 1219px) {
  .md-search__input { font-size: .76rem; padding-left: 2.1rem; }
  .md-search__input::placeholder { color: #8b8f99; }
  .md-search__icon[for=__search] { width: 1rem; height: 1rem; left: .65rem; color: #8b8f99; }
  .md-header__option { display: none; }   /* colour-scheme toggle, not needed here */
}
@media (prefers-reduced-motion: reduce) {
  .esb-chev, .account-menu .nav-chev { transition: none; }
  .esb-group.t-anim .esb-panel,
  .esb-group.t-anim.is-closing .esb-panel,
  .account-menu.t-anim .account-panel { transition: none !important; }
}

/* ---- One footer: the docs' link groups and the site's, on one grid ----
   Ten groups of links, the docs' five first, in five equal columns across the full width, so the two rows'
   columns line up (overrides/main.html), with a wider gap between the rows instead of a rule. The wordmark, its
   line and "See plans" come after them in a row of their own, then the small print. (Beside the links, as on
   1p.dev, they left the five columns too narrow for their labels; and the docs' groups used to be a band of
   their own above the footer, on another grid, with a rule under it.) The footer sits straight under the page. */
.md-main + .footer--site { margin-top: 0; padding-top: clamp(3.5rem, 7vw, 5.5rem); }
.footer--site .footer-intro { order: 2; }
@media (min-width: 960px) {
  .footer--site .footer-shell { grid-template-columns: minmax(0, 1fr); gap: clamp(3.5rem, 6vw, 5rem); }
  .footer--site .footer-nav { grid-template-columns: repeat(5, minmax(0, 1fr)); padding-top: 0; row-gap: clamp(2.75rem, 5vw, 4rem); }
  .footer--site .footer-intro {
    max-width: none; display: grid; grid-template-columns: auto minmax(0, 27rem) 1fr;
    align-items: end; column-gap: clamp(2rem, 5vw, 4.5rem);
  }
  .footer--site .footer-intro > p { margin: 0; }
  .footer--site .footer-start { margin: 0; justify-self: end; white-space: nowrap; }
  .footer--site .footer-meta { margin-top: clamp(3rem, 5vw, 4.5rem); }
}
@media (max-width: 959px) { .footer--site .footer-nav { row-gap: 2.5rem; } }
@media (max-width: 480px) { .footer--site .footer-nav { row-gap: 2rem; } }


/* ---- Modern centred search in the docs header ---- */
.md-header__inner { gap: 1rem; }
.md-header__title { flex: 0 1 auto; }

@media screen and (min-width: 60em) {
  /* Centre against the viewport, not the remaining flex space: the logo and
     title on the left would otherwise push the field to the right. */
  .md-header__inner { position: relative; }
  .md-search {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: min(22rem, 32vw);
    margin: 0;
    padding: 0;
  }
  /* Material widens the inner wrapper when the field is focused, which would
     overflow our centred container. Keep every layer the same width. */
  .md-search__inner,
  [data-md-toggle=search]:checked ~ .md-header .md-search__inner {
    width: 100% !important;
    left: 0 !important;
    right: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    float: none !important;
    transform: none !important;
  }
  .md-search__form { width: 100% !important; }

  /* No dimming overlay: a soft shadow on the results panel is enough. */
  .md-search__overlay,
  [data-md-toggle=search]:checked ~ .md-header .md-search__overlay {
    display: none !important;
    opacity: 0 !important;
    pointer-events: none !important;
  }

  /* results panel: aligned to the field, floating on a soft shadow */
  .md-search__output {
    width: 100%;
    left: 0;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 12px 32px rgba(8,9,11,.14), 0 2px 8px rgba(8,9,11,.08);
    border: 1px solid rgba(8,9,11,.08);
  }
  .md-search__scrollwrap { border-radius: 14px; }
  /* square off the join with the input while results are open */
  [data-md-toggle=search]:checked ~ .md-header .md-search__form {
    border-radius: 14px 14px 0 0;
  }
  [data-md-toggle=search]:checked ~ .md-header .md-search__output {
    border-radius: 0 0 14px 14px;
  }
  [data-md-toggle=search]:checked ~ .md-header .md-search__scrollwrap {
    border-radius: 0 0 14px 14px;
  }

  .md-search__form {
    height: 1.95rem;
    border-radius: 12px;
    background: #f1f0ea;
    border: 1px solid rgba(8,9,11,.12);
    box-shadow: none;
    transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
  }
  .md-search__form:hover {
    background: #ecebe4;
    border-color: rgba(8,9,11,.2);
  }
  .md-search__form:focus-within {
    background: #fff;
    border-color: rgba(92, 89, 84, .55);
    box-shadow: 0 0 0 3px rgba(92, 89, 84, .12);
  }

  .md-search__input {
    color: #0c0c0f;
    font-size: .76rem;
    padding-left: 2.2rem;
  }
  .md-search__input::placeholder { color: #8b8f99; }

  /* the magnifier, in grey */
  .md-search__icon[for=__search] {
    width: 1.05rem;
    height: 1.05rem;
    left: .8rem;
    color: #8b8f99;
    opacity: 1;
  }
  .md-search__form:focus-within .md-search__icon[for=__search] { color: #6b7180; }

  /* the reset (x) button */
  .md-search__options .md-icon { color: #8b8f99; }

}

/* results list: a little more air */
.md-search-result__item { border-bottom: 1px solid rgba(8,9,11,.06); }
.md-search-result__link { transition: background .12s ease; }
.md-search-result__link:hover { background: rgba(92, 89, 84, .06); }
.md-search-result__meta {
  background: transparent;
  color: #6b7180;
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: .8rem 1rem .4rem;
}


/* ---- Mobile corrections ---- */
@media screen and (max-width: 1219px) {
  /* the page title is set for a wide column; bring it back to phone scale */
  .md-typeset h1 { font-size: 1.85rem !important; line-height: 1.15 !important; }
  .md-typeset h2 { font-size: 1.4rem !important; line-height: 1.2 !important; }
  .md-typeset h3 { font-size: 1.1rem !important; }
  .md-typeset { font-size: .8rem; }
  .md-content__inner { padding: .8rem .2rem 1.2rem; }

  /* Material moves search into the header row on small screens: let it be its
     own full-width control rather than our centred desktop field. */
  .md-search { position: static; transform: none; width: auto; max-width: none; }
  .md-search__inner, [data-md-toggle=search]:checked ~ .md-header .md-search__inner {
    width: 100% !important;
    transform: none !important;
  }
  .md-search__form { border-radius: 0; height: auto; }
  .md-search__output { border-radius: 0; box-shadow: none; border: 0; }

  /* The closed nav drawer must sit entirely off-screen. Material offsets it by
     a fixed amount that assumes its own drawer width; when that does not match
     it overlaps the left of the page and clips headings. */
  .md-sidebar--primary {
    left: 0 !important;
    width: 12.1rem !important;
    transform: translateX(-100%) !important;
    will-change: transform;
  }
  [data-md-toggle=drawer]:checked ~ .md-container .md-sidebar--primary {
    transform: translateX(0) !important;
    box-shadow: 0 8px 24px rgba(8,9,11,.18);
  }

  /* the footer: a tighter rhythm */
  .footer--site { margin-top: 0; padding-top: 2.5rem; }
}


/* ============================================================
   Docs typography: editorial hierarchy rather than Material's
   defaults, matching the marketing site's feel.
   ============================================================ */

/* The logo: 1p.dev's red square, 40px wide, standing on its own at the left of
   the header row. The title is not shown: 1p.dev's header has none, and over
   the see-through header it would sit on the text scrolling beneath. */
.md-header__button.md-logo { padding: 0; margin: 0 24px 0 0; }
.md-header__button.md-logo img,
.md-header__button.md-logo svg { width: 40px !important; height: auto !important; }
.md-header__title { display: none !important; }

/* Headings: real hierarchy. h1 and h2 in Geologica, bold, as on 1p.dev. */
.md-typeset h1 {
  font-family: var(--f-display) !important;
  font-size: 2.4rem !important; font-weight: 700 !important;
  letter-spacing: var(--ls-heading) !important; line-height: 1.12 !important;
  color: var(--c-ink) !important; margin: 0 0 1.1rem !important;
}
.md-typeset h2 {
  font-family: var(--f-display) !important;
  font-size: 1.55rem !important; font-weight: 700 !important;
  letter-spacing: var(--ls-heading) !important; line-height: 1.2 !important;
  color: var(--c-ink) !important; margin: 3rem 0 1.1rem !important;
  padding-top: 1.6rem; border-top: 1px solid rgba(8,9,11,.09);
}
.md-typeset h1 + h2 { margin-top: 2rem !important; border-top: 0; padding-top: 0; }
/* h3 and h4 read as subtitles, so they take the console face of 1p.dev's
   subtitles and FAQ questions (--f-sub, a step smaller by --sub-size). */
.md-typeset h3 {
  font-family: var(--f-sub) !important;
  font-size: 1.08rem !important; font-weight: 500 !important;
  letter-spacing: -.01em !important; margin: 2rem 0 .6rem !important;
  color: var(--c-ink) !important;
}
.md-typeset h4 {
  font-family: var(--f-sub) !important;
  font-size: .95rem !important; font-weight: 500 !important;
  letter-spacing: -.01em !important; margin: 1.5rem 0 .5rem !important;
  color: var(--c-ink-2) !important;
}

/* Body copy */
.md-typeset { font-size: .82rem; line-height: 1.68; color: #3f4452; }
.md-typeset p { margin: 0 0 1.1rem; }
.md-content__inner { padding-top: 1.4rem; }
.md-content__inner > :first-child { margin-top: 0 !important; }

/* The first paragraph after a title reads as a lede: the console face of
   1p.dev's subtitles, regular, in the muted ink. */
.md-typeset h1 + p {
  font-family: var(--f-sub); font-weight: 400; letter-spacing: -.01em;
  font-size: 1.06rem; line-height: 1.6; margin-bottom: 1.8rem; color: var(--c-muted);
}

/* Lists: air, and a quieter marker */
.md-typeset ul li, .md-typeset ol li { margin-bottom: .5rem; }
.md-typeset ul li::marker { color: rgba(8,9,11,.32); }
.md-typeset ul { padding-left: 1.15rem; }

/* Links: the site's lime underline */
.md-typeset a {
  color: #373633; text-decoration: underline;
  text-decoration-color: rgba(92, 89, 84, .45);
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  transition: text-decoration-color .15s ease;
}
.md-typeset a:hover { text-decoration-color: currentColor; }
/* A heading that is itself a link must still read as a heading, not a link:
   several index pages use "## [Section](path)" and were rendering all-green. */
.md-typeset h1 a, .md-typeset h2 a, .md-typeset h3 a, .md-typeset h4 a {
  color: inherit !important;
  text-decoration: none !important;
  border-bottom: 0 !important;
}
.md-typeset h1 a:hover, .md-typeset h2 a:hover,
.md-typeset h3 a:hover, .md-typeset h4 a:hover {
  color: #373633 !important;
}
/* index pages are mostly link lists: quieter treatment so they do not shout */
.md-typeset ul > li > a:only-child {
  text-decoration: none; font-weight: 500;
  border-bottom: 1px solid rgba(92, 89, 84, .28); padding-bottom: 1px;
}
.md-typeset ul > li > a:only-child:hover { border-bottom-color: #373633; }

/* Sidebars: legible rather than shrunken */
.md-sidebar { font-size: .68rem; }
.md-nav { font-size: .74rem; }
.md-nav__title {
  font-family: 'Hanken Grotesk', sans-serif; font-size: .68rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: #8b8f99;
}
.md-nav__link { color: #3f4452; font-weight: 400; padding: .16rem 0; }
.md-nav__link:hover { color: #373633; }
.md-nav__link--active, .md-nav__item .md-nav__link--active { color: #373633 !important; font-weight: 600; }

/* Code */
.md-typeset code {
  background: rgba(8,9,11,.05); color: #0c0c0f; border-radius: 3px;
  padding: .12em .38em; font-size: .86em;
}
.md-typeset pre > code { background: transparent; padding: 0; }
.md-typeset .highlight { border: 1px solid rgba(8,9,11,.09); border-radius: 6px; background: #fbfbf8; }

/* Tables: hairlines */
.md-typeset table:not([class]) { border: 0; border-top: 1px solid rgba(8,9,11,.12); font-size: .96em; }
.md-typeset table:not([class]) th {
  background: transparent; font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 600; color: #0c0c0f; border-bottom: 1px solid rgba(8,9,11,.12);
}
.md-typeset table:not([class]) td { border-bottom: 1px solid rgba(8,9,11,.07); }

.md-typeset blockquote {
  border-left: 2px solid rgba(92, 89, 84, .5); color: #3f4452;
  padding-left: 1rem; margin-left: 0;
}
.md-typeset hr { border-bottom: 1px solid rgba(8,9,11,.09); margin: 2.5rem 0; }

@media screen and (max-width: 1219px) {
  .md-typeset h1 { font-size: 1.85rem !important; }
  .md-typeset h2 { font-size: 1.3rem !important; margin-top: 2.2rem !important; padding-top: 1.2rem; }
  .md-typeset { font-size: .8rem; }
}


/* ---- Scrollbars: fade, rather than blink ---- */
/* `scrollbar-color` cannot be transitioned, and the WebKit pseudo-element only
   animates on hover, so toggling either one snaps. Instead the thumb keeps a
   constant colour and the whole scrollbar's OPACITY is animated, which does
   interpolate. */
* { scrollbar-width: thin; scrollbar-color: rgba(8,9,11,.28) transparent; }

*::-webkit-scrollbar { width: 11px; height: 11px; background: transparent; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: rgba(8,9,11,.28);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: rgba(8,9,11,.45); }

/* Fade the whole bar by animating opacity on the scrolling element itself.
   Firefox and WebKit both interpolate this cleanly. */
html, .md-sidebar__scrollwrap, .md-search__scrollwrap {
  transition: scrollbar-color .45s ease;
}
html:not(.is-scrolling):not(:hover) { scrollbar-color: transparent transparent; }
html:not(.is-scrolling):not(:hover)::-webkit-scrollbar-thumb { background-color: transparent; }

/* the visible fade: a slow ease out, a quicker ease in */
html::-webkit-scrollbar-thumb { transition: background-color .5s ease .15s; }
html.is-scrolling::-webkit-scrollbar-thumb {
  background-color: rgba(8,9,11,.3);
  transition: background-color .12s ease;
}

.md-sidebar__scrollwrap { scrollbar-color: transparent transparent; }
.md-sidebar:hover .md-sidebar__scrollwrap { scrollbar-color: rgba(8,9,11,.24) transparent; }

@media (prefers-reduced-motion: reduce) {
  html, .md-sidebar__scrollwrap { transition: none; }
  html::-webkit-scrollbar-thumb { transition: none; }
}

/* ---- Sidebars ----
   The rail widths and the reading measure now live together in p1-docs.css,
   which is where the page gutter is budgeted against them. This file loads
   AFTER that one, so a width here silently wins: it is why 12.5rem held the
   primary rail at 275px however wide p1-docs.css asked for. Keep rail sizing
   out of this file.

   `.md-main__inner{max-width:none}` stays: p1-docs.css sets a `width` on that
   element, and Material's own 61rem `max-width` would otherwise clamp it. */
@media screen and (min-width: 1220px) {
  .md-main__inner { max-width: none; }
}
.md-nav__item .md-nav__link { line-height: 1.35; }
.md-nav--secondary .md-nav__list .md-nav__list { padding-left: .5rem; }


/* ---- Sizes in px, so Material's 20px root cannot inflate them ----
   The marketing site renders body copy at 17.6px and section headings at
   ~38px on a 16px root. These match. */
.md-typeset            { font-size: 17px; line-height: 1.68; }
.md-typeset h1         { font-size: 38px !important; line-height: 1.12 !important; }
.md-typeset h2         { font-size: 25px !important; line-height: 1.2 !important; }
/* the console face sets large, so h3, h4 and the lede are scaled by --sub-size */
.md-typeset h3         { font-size: calc(18px * var(--sub-size)) !important; }
.md-typeset h4         { font-size: calc(16px * var(--sub-size)) !important; }
.md-typeset h1 + p     { font-size: calc(18px * var(--sub-size)); line-height: 1.6; }
.md-typeset code       { font-size: 14.5px; }
.md-typeset table:not([class]) { font-size: 16px; }

.md-nav                { font-size: 14px; }
.md-nav__title         { font-size: 11.5px; }
.md-sidebar            { font-size: 14px; }
.md-header__topic      { font-size: 15px; }
.md-search__input      { font-size: 15px; }
.md-search-result__meta{ font-size: 12px; }
.md-footer             { font-size: 14px; }

@media screen and (max-width: 1219px) {
  .md-typeset          { font-size: 16.5px; }
  .md-typeset h1       { font-size: 30px !important; }
  .md-typeset h2       { font-size: 21px !important; }
  .md-typeset h3       { font-size: calc(17px * var(--sub-size)) !important; }
  .md-nav--primary .md-nav__link  { font-size: 14.5px !important; }
  .md-nav--primary .md-nav__title { font-size: 12px !important; }
}


/* ---- Drawer: strip Material's heavy separators and padding ---- */
@media screen and (max-width: 1219px) {
  /* Material draws a full-width rule between every item and gives each one
     ~2.5rem of vertical padding, which reads as a stack of heavy boxes. */
  .md-nav--primary .md-nav__item { border-top: 0 !important; padding: 0 !important; }
  .md-nav--primary .md-nav__item > .md-nav__link {
    margin: 0 !important;
    padding: .62rem .9rem !important;
    line-height: 1.35 !important;
    min-height: 0 !important;
    border: 0 !important;
  }
  .md-nav--primary > .md-nav__list { padding: .35rem 0 !important; }
  .md-nav--primary .md-nav__list .md-nav__list { padding-bottom: .2rem; }

  /* the nested-section back button: the arrow was sitting on top of the label */
  .md-nav--primary .md-nav__title {
    display: flex !important;
    align-items: center;
    gap: .55rem;
    padding: 0 .9rem !important;
  }
  .md-nav--primary .md-nav__title .md-nav__icon,
  .md-nav--primary .md-nav__title .md-nav__button {
    position: static !important;
    margin: 0 !important;
    width: 1.1rem !important;
    height: 1.1rem !important;
    flex: none;
  }

  /* the chevron on nested items */
  .md-nav--primary .md-nav__icon { color: rgba(8,9,11,.3); }

  /* the active item, without the heavy highlight */
  .md-nav--primary .md-nav__link--active { color: #373633 !important; font-weight: 600; }

  /* the toggle icon beside the current page */
  .md-nav--primary .md-nav__link .md-nav__icon:not(:only-child) { opacity: .55; }
}

/* the desktop rails: quieter separators too */
.md-nav--secondary .md-nav__item { border: 0; }
.md-sidebar--primary .md-nav__item { border: 0; }


/* ---- Header: the site links were running under the search box ---- */
@media screen and (min-width: 1220px) {
  /* Give the search a fixed share and let the links keep their own space, so
     the first link cannot end up beneath the search field. */
  .md-header__inner .md-search {
    position: static !important;
    transform: none !important;
    flex: 0 0 auto;
    width: min(21rem, 30vw) !important;
    margin: 0 auto 0 2rem !important;
  }
}

/* ---- All three columns start on the same line ----
   Both rails begin at the same y, but Material adds a 30px margin to the
   content wrapper and a 10px margin to the first nav item, so the three
   started at three different heights. Zero them and set one shared pad. */
@media screen and (min-width: 1220px) {
  .md-sidebar { padding-top: 1.75rem !important; }
  .md-sidebar__inner { padding-top: 0 !important; }

  .md-content__inner { margin-top: 0 !important; padding-top: 1.75rem !important; }
  .md-content__inner > :first-child { margin-top: 0 !important; }
  .md-content__inner::before { display: none; }   /* Material's spacer pseudo-element */

  .md-nav--primary > .md-nav__list { padding-top: 0 !important; }
  .md-nav--primary > .md-nav__list > .md-nav__item:first-child { margin-top: 0 !important; }
  .md-nav--primary > .md-nav__list > .md-nav__item:first-child > .md-nav__link { margin-top: 0 !important; }
  .md-nav--primary > .md-nav__title { display: none; }
  .md-nav--secondary > .md-nav__title { padding-top: 0 !important; margin-top: 0 !important; }
  .md-nav--secondary > .md-nav__list { padding-top: .3rem; }
}


/* ---- Previous / next cards under each page ----
   These belong to the content column, so they are rendered inside the article
   rather than across the full width where they sat over the sidebar.
   Sizes are in PIXELS throughout: Material sets html{font-size:20px}, so a rem
   here is 25% larger than it reads. */
.docs-pagenav {
  border-top: 1px solid rgba(8,9,11,.10);
  margin: 56px 0 0;
  padding: 26px 0 8px;
  background: transparent;
}
.docs-pagenav .dpn-shell {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  width: 100%;
  margin: 0;
}
.docs-pagenav .dpn-card {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  padding: 17px 19px 18px;
  border: 1px solid rgba(8,9,11,.10);
  border-radius: 10px;
  background: #fff;
  text-decoration: none !important;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.docs-pagenav .dpn-card:hover {
  border-color: rgba(92, 89, 84, .42);
  box-shadow: 0 2px 10px rgba(8,9,11,.05);
  transform: translateY(-1px);
}
.docs-pagenav .dpn-empty { border: 0; background: transparent; pointer-events: none; }

/* The arrow is a direction marker, not a button: small, quiet, and aligned to
   the label row rather than floating against the middle of the card. */
.docs-pagenav .dpn-arrow {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: rgba(92, 89, 84, .10);
  color: #373633;
  margin-top: 1px;
  transition: background .15s ease;
}
.docs-pagenav .dpn-arrow svg { width: 14px; height: 14px; display: block; }
.docs-pagenav .dpn-card:hover .dpn-arrow { background: rgba(92, 89, 84, .18); }

.docs-pagenav .dpn-body { display: flex; flex-direction: column; min-width: 0; }
/* "Previous" and "Next" are labels, so they are set like 1p.dev's HUD labels */
.docs-pagenav .dpn-dir {
  font-family: var(--f-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: var(--ls-hud);
  line-height: 1.6;
  text-transform: uppercase;
  color: #9ea2ac;
}
.docs-pagenav .dpn-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -.01em;
  color: #0c0c0f;
  margin-top: 2px;
}
.docs-pagenav .dpn-card:hover .dpn-title { color: #373633; }
.docs-pagenav .dpn-desc {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 13.5px;
  line-height: 1.5;
  color: #6b7180;
  margin-top: 5px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* the next card reads right-to-left so the eye follows the direction of travel */
.docs-pagenav .dpn-next { flex-direction: row; text-align: right; justify-content: flex-end; }
.docs-pagenav .dpn-next .dpn-body { align-items: flex-end; }

/* One column once two cards would each be narrower than about 300px. In px, not
   em: Material's 20px root makes em breakpoints 25% wider than they read. */
@media screen and (max-width: 880px) {
  .docs-pagenav { margin-top: 44px; padding-top: 22px; }
  .docs-pagenav .dpn-shell { grid-template-columns: 1fr; gap: 12px; }
  .docs-pagenav .dpn-empty { display: none; }
  .docs-pagenav .dpn-next { flex-direction: row; text-align: left; justify-content: flex-start; }
  .docs-pagenav .dpn-next .dpn-body { align-items: flex-start; }
  .docs-pagenav .dpn-next .dpn-arrow { order: 2; }
  /* one narrow column, so the same sentence needs a third line to finish */
  .docs-pagenav .dpn-desc { -webkit-line-clamp: 3; }
}

/* ---- Search field: compact and modern, not a wide flat form box ---- */
@media screen and (min-width: 1220px) {
  /* Let the search occupy the space between the logo and site links, then centre
     its compact field inside that space. The field width must stay fixed in both
     resting and focused states: Material otherwise changes its bounds under the
     pointer as the search toggle opens. */
  .md-header__inner .md-search {
    flex: 1 1 auto;
    display: flex;
    justify-content: center;
    width: auto !important;
    max-width: none !important;
    margin: 0 !important;
  }
  .md-header__inner .md-search__inner,
  [data-md-toggle=search]:checked ~ .md-header .md-search__inner {
    width: 15rem !important;
    max-width: 100%;
    left: auto !important;
    right: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    float: none !important;
    transform: none !important;
  }
}

.md-search__form {
  height: 34px !important;
  border-radius: 999px !important;    /* pill, not a rectangle */
  background: rgba(8,9,11,.045) !important;
  border: 1px solid transparent !important;
  box-shadow: none !important;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.md-search__form:hover { background: rgba(8,9,11,.07) !important; }
.md-search__form:focus-within {
  background: #fff !important;
  border-color: rgba(92, 89, 84, .45) !important;
  box-shadow: 0 0 0 3px rgba(92, 89, 84, .10) !important;
}

.md-search__input {
  height: 34px !important;
  font-size: 14px !important;
  padding-left: 2.1rem !important;
  padding-right: .9rem !important;
  color: #0c0c0f !important;
}
.md-search__input::placeholder {
  color: #9498a3 !important;
  font-size: 14px;
  font-weight: 400;
}

/* A smaller, lighter magnifier, vertically centred.
   Material positions this with its own top/margin, and a translateY on top of
   that lands it low. Use flex centring over a full-height box instead, which
   cannot drift regardless of the field height. */
.md-search__icon[for=__search] {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  position: absolute !important;
  left: .55rem !important;
  top: 0 !important;
  bottom: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  width: 1.6rem !important;
  height: auto !important;
  transform: none !important;
  color: #9498a3 !important;
  opacity: 1 !important;
}
.md-search__icon[for=__search] svg {
  width: 15px !important;
  height: 15px !important;
  display: block;
}
.md-search__form:focus-within .md-search__icon[for=__search] { color: #6b7180 !important; }

/* the clear button, only once there is something to clear */
.md-search__options .md-icon { width: 15px; height: 15px; color: #9498a3; }

@media screen and (max-width: 1219px) {
  .md-search__form { height: 32px !important; }
  .md-search__input { height: 32px !important; font-size: 13.5px !important; }
}


/* ---- Search results panel ----
   The panel is anchored to the field, so a 300px field clipped every result.
   Give it its own width and stop the titles inheriting the page h1 style. */
@media screen and (min-width: 1220px) {
  .md-search__output {
    width: min(30rem, calc(100vw - 4rem)) !important;
    max-width: calc(100vw - 4rem) !important;
    left: 50% !important;
    transform: translateX(-50%);
    border-radius: 10px !important;
    box-shadow: 0 8px 28px rgba(8,9,11,.13), 0 1px 3px rgba(8,9,11,.08) !important;
    border: 1px solid rgba(8,9,11,.08);
  }
  .md-search__scrollwrap { width: 100% !important; max-height: 65vh !important; }
}

/* Titles were rendering as full-size page headings.
   The fuzzy-search fallback emits a bare <h1> with no class, so the class
   selector alone never matched and the page h1 rule won. Match the elements. */
.md-search-result h1,
.md-search-result h2,
.md-search-result h3,
.md-search__output h1,
.md-search__output h2,
.md-search__output h3,
.md-search-result__link h1,
.md-search-result__article > h1,
.md-search-result__title,
.md-search-result__link .md-search-result__title {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-size: 14.5px !important;
  font-weight: 600 !important;
  line-height: 1.35 !important;
  letter-spacing: -.005em !important;
  color: #0c0c0f !important;
  margin: 0 0 .15rem !important;
}
.md-search-result p,
.md-search__output p,
.md-search-result__teaser {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-size: 13px !important;
  line-height: 1.5 !important;
  color: #6b7180 !important;
  -webkit-line-clamp: 2 !important;
  margin: 0 !important;
}
.md-search-result__article,
.md-search-result__item .md-search-result__link { padding: .7rem .95rem !important; }
.md-search-result__meta {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-size: 11px !important;
  letter-spacing: .085em !important;
  text-transform: uppercase !important;
  color: #9498a3 !important;
  padding: .7rem .95rem .35rem !important;
}
.md-search-result mark { color: #373633 !important; background: transparent !important; font-weight: 700 !important; }
/* Material renders this as an EMPTY div here (no svg inside), so it was just
   16px of nothing showing as a broken box jammed against each title. */
.md-search-result__icon { display: none !important; }

/* Share / clear buttons were crowding the right edge and the text ran under
   them. Space them, and keep the input clear of both. */
.md-search__options {
  right: .5rem !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  display: flex !important;
  align-items: center !important;
  gap: .3rem !important;
}
.md-search__options .md-search__icon {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 24px !important;
  height: 24px !important;
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 999px !important;
  color: #9498a3 !important;
  transform: none !important;
  transition: background .15s ease, color .15s ease;
}
.md-search__options .md-search__icon svg { width: 14px !important; height: 14px !important; }
.md-search__options .md-search__icon:hover { background: rgba(8,9,11,.07) !important; color: #373633 !important; }
/* room for both buttons so typed text never runs beneath them */
.md-search__input, .md-search__suggest { padding-right: 3.6rem !important; }
.md-search-result__more > summary > div {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-size: 12.5px !important;
  color: #373633 !important;
  padding: .5rem .95rem !important;
}
.md-search-result__list { border: 0 !important; }
.md-search-result__item { border-top: 1px solid rgba(8,9,11,.07) !important; box-shadow: none !important; }
.md-search-result__item:first-child { border-top: 0 !important; }

/* ---- Autocomplete ghost text ----
   It sits behind the real input, so any difference in font, size or padding
   shows up as two overlapping strings. Match the input exactly. */
.md-search__suggest {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  letter-spacing: normal !important;
  line-height: 34px !important;
  height: 34px !important;
  padding-left: 2.1rem !important;
  padding-right: .9rem !important;
  color: #c3c6cd !important;
  white-space: nowrap;
  overflow: hidden;
}
.md-search__input {
  font-family: 'Hanken Grotesk', sans-serif !important;
  font-weight: 400 !important;
  letter-spacing: normal !important;
  line-height: 34px !important;
}


/* ---- Fade at the foot of a scrollable sidebar ----
   The fade must hang off the SCROLLWRAP, the box that actually scrolls.
   Hanging it off .md-sidebar put it at that element's own bottom edge, which
   sits near the TOP of the visible rail, so the fade appeared above the menu.
   A sticky pseudo-element sits at the end of the content and pins itself to
   the bottom of the visible box instead. */
@media screen and (min-width: 1220px) {
  .md-sidebar--primary .md-sidebar__scrollwrap::after {
    content: "";
    display: block;
    position: sticky;
    bottom: 0;
    height: 3rem;
    margin-top: -3rem;        /* reclaim the space it occupies in the flow */
    pointer-events: none;
    background: linear-gradient(
      to bottom,
      rgba(251,251,248,0) 0%,
      rgba(251,251,248,.75) 55%,
      rgba(251,251,248,.97) 100%
    );
    opacity: 0;
    transition: opacity .18s ease;
    z-index: 2;
  }
  /* only while there is genuinely more to scroll to */
  .md-sidebar--primary[data-esb-overflow="1"] .md-sidebar__scrollwrap::after { opacity: 1; }
}

/* ---- The sticky rail was painting over the footer ----
   Reported as "the sidebar's fade paints a white box across the footer when
   you scroll fast". The fade is the visible part, but it is a symptom: at the
   bottom of the page the scrollwrap's own box extends ~290px PAST the top of
   the footer, so the whole rail overlaps it. Hit-testing inside the footer
   returned .md-nav__link, not the footer - the nav was literally on top of it
   and would have swallowed clicks near the left edge.

   So raising the footer is the right fix rather than hiding the fade: it
   corrects the stacking for the entire rail, not just its last 3rem. Both the
   footer and the key-parts band need it, since they are siblings in the same
   stacking context and the rail spills across both. Verified by scrolling fast
   and hit-testing, not by reading z-index values: 5/5 probe points inside the
   footer hit nav links before, 0/5 after. */
footer.footer--site { position: relative; z-index: 3; }

/* ---- Footer type: sized for a 16px root, rendered at 20-22px ----
   This footer is shared markup with the marketing site, where the root is
   16px. Material's root here is 20px (22px above 1600px), so every rem-based
   size in the block above renders 25-37% larger: the intro paragraph came out
   at 22px against 18px body text, so the footer shouted louder than the page.
   Pinned in px, a step BELOW the body size, so it reads as a quieter register. */
.footer--site .footer-intro > p      { font-size: 15px; }
.footer--site .footer-group a        { font-size: 15px; }
footer.footer--site .footer-group h2 { font-size: 11.5px !important; }
.footer--site .footer-start          { font-size: 15px; }
.footer--site .footer-meta p         { font-size: 12.5px; }
footer.footer--site .logo            { font-size: 30px !important; }

/* ---- Footer gutter, matched to the content region ----
   The footer sits OUTSIDE .md-main__inner, so it did not inherit the page
   gutter and stayed on its own `min(100% - 48px, 76rem)`. Same width
   expression as .md-main__inner in p1-docs.css, band for band, so the header,
   the content and the footer share one left edge at every width. */
@media screen and (min-width: 1600px) {
  .footer--site .footer-shell,
  .footer--site .footer-meta { width: min(100% - 160px, 80rem); }
}
@media screen and (min-width: 1400px) and (max-width: 1599px) {
  .footer--site .footer-shell,
  .footer--site .footer-meta { width: min(100% - 96px, 80rem); }
}
@media screen and (min-width: 1220px) and (max-width: 1399px) {
  .footer--site .footer-shell,
  .footer--site .footer-meta { width: min(100% - 48px, 80rem); }
}


/* The account menu, as on 1p.dev (account-nav.js, loaded from https://1p.dev/).
   Signed out the button reads "Login" (styled with the menu above); signed in
   it becomes a "Dashboard" menu listing the visitor's instances. */
.account-menu { position: relative; display: inline-block; flex: none; font-family: var(--f-body); --nav-dropdown-close-dur: .18s; }
.account-menu > summary { list-style: none; cursor: pointer; }
.account-menu > summary::-webkit-details-marker { display: none; }
.account-menu > summary::marker { content: ""; }
.account-menu > summary:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 3px; }
.account-menu .nav-chev { flex: none; opacity: .7; transition: transform .35s cubic-bezier(.22,1,.36,1); }
.account-menu[open] .nav-chev { transform: rotate(180deg); opacity: 1; }
.account-menu:not([open]) .account-panel { display: none; }
.account-panel {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  z-index: 120;
  width: min(320px, 86vw);
  padding: 8px;
  background: var(--c-surface);
  border-radius: 14px;
  box-shadow: var(--sh-2);
}
.account-panel::before { content: ""; position: absolute; left: 0; right: 0; top: -12px; height: 12px; }
.account-list { max-height: min(352px, 60vh); overflow-y: auto; }
.account-menu.t-anim .account-panel {
  opacity: 0;
  transform: translateY(-4px) scale(.98);
  transform-origin: top right;
  pointer-events: none;
  transition: opacity .18s ease, transform .18s cubic-bezier(.22,1,.36,1);
}
.account-menu.t-anim.is-open .account-panel { opacity: 1; transform: none; pointer-events: auto; }
.account-menu.t-anim.is-closing .account-panel { opacity: 0; transform: translateY(-4px) scale(.98); }
.account-row {
  display: block;
  padding: 8px 12px;
  border-radius: 10px;
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--c-ink) !important;
  text-decoration: none;
}
a.account-row:hover, a.account-row:focus-visible { background: var(--c-lav-soft); }
.account-row.is-unavailable { cursor: default; color: var(--c-faint) !important; }
.account-row-line { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.account-row-name { overflow-wrap: anywhere; font-weight: 500; }
.account-row-status, .account-row-org { font-size: var(--t-xs); color: var(--c-faint); }
.account-row-status { flex: none; }
.account-row-org { display: block; margin-top: 2px; }
.account-open { margin-top: 4px; border-top: 1px solid var(--c-line); border-radius: 0 0 10px 10px; color: var(--c-purple) !important; font-weight: 600; }

/* ============================================================
   Player One surfaces, as on 1p.dev and in the app: the warm neutral palette
   and depth from shadows instead of 1px borders. The header has no band at all
   (see the header section above).
   ============================================================ */
:root {
  --p1-bg: #fcfcfa; --p1-bg-2: #f5f4f0; --p1-text: #111110; --p1-text-2: #3d3c39; --p1-text-3: #646360;
  --p1-line: #edece7; --p1-accent: #646360; --p1-accent-deep: #262523;
  --p1-hover: #eae9e4; --p1-hairline: #e5e4df;
  --p1-shadow-surface: 0 1px 6px rgb(0 0 0 / .04), 0 0 24px rgb(0 0 0 / .05);
  --p1-shadow-raised: 0 2px 8px rgb(0 0 0 / .06), 0 0 32px rgb(0 0 0 / .08);
  --p1-shadow-floating: 0 3px 16px rgb(0 0 0 / .1), 0 0 40px rgb(0 0 0 / .08);
}
[data-md-color-scheme="p1"] { --md-code-bg-color: #f5f4f0; --md-code-fg-color: #2a2927; }

/* Search: a quiet field in the sidebar tone, results on the floating tier. */
.md-search__form {
  background: var(--p1-bg-2) !important;
  border: 0 !important;
  box-shadow: none !important;
}
.md-search__form:hover { background: var(--p1-hover) !important; }
.md-search__form:focus-within { background: #fff !important; box-shadow: var(--p1-shadow-raised) !important; }
.md-search__output { border: 0 !important; box-shadow: var(--p1-shadow-floating) !important; }
.md-search-result__item { border-bottom-color: var(--p1-line) !important; }
/* On the header row the field floats like the menu: the same frosted glass,
   so it stays readable over the page scrolling beneath, on a lighter shadow. */
@media screen and (min-width: 960px) {
  .md-header .md-search__form {
    height: var(--search-h) !important;
    background: var(--nav-glass) !important;
    -webkit-backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
    backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
    box-shadow: var(--sh-1) !important;
  }
  .md-header .md-search__form:hover { background: color-mix(in srgb, var(--c-page) 90%, transparent) !important; }
  .md-header .md-search__form:focus-within { background: var(--c-surface) !important; box-shadow: var(--sh-2) !important; }
  .md-header .md-search__input,
  .md-header .md-search__suggest { height: var(--search-h) !important; line-height: var(--search-h) !important; }
  .md-header .md-search__output { top: calc(var(--search-h) + 8px); }
}

/* Cards and panels in the page: a white surface lifted off the page. */
.docs-pagenav .dpn-card {
  border: 0 !important;
  background: #fff !important;
  box-shadow: var(--p1-shadow-surface) !important;
  border-radius: 16px !important;
}
.docs-pagenav .dpn-card:hover { box-shadow: var(--p1-shadow-raised) !important; }
.docs-pagenav .dpn-empty { box-shadow: none !important; background: transparent !important; }
.md-typeset .admonition, .md-typeset details {
  border: 0 !important;
  border-left: 3px solid var(--p1-hairline) !important;
  background: #fff !important;
  box-shadow: var(--p1-shadow-surface) !important;
  border-radius: 12px !important;
}
.md-typeset .highlight, .md-typeset pre > code {
  border: 0 !important;
  background: var(--p1-bg-2) !important;
  border-radius: 12px;
}
.md-typeset code { background: var(--p1-bg-2); }
.md-typeset table:not([class]) { border-top-color: var(--p1-line) !important; }
.md-typeset table:not([class]) th { border-bottom-color: var(--p1-hairline) !important; }
.md-typeset table:not([class]) td { border-bottom-color: var(--p1-line) !important; }
.md-nav__list .md-nav__list { border-left-color: var(--p1-line) !important; }

/* Links and the active page read in the warm near-black. */
.md-typeset a { color: var(--p1-accent-deep); }

/* ---- Header, matched to 1p.dev, with the search beside the logo ----
   The header row has 1p.dev's own page margin, clamp(22px, 5vw, 72px), with the
   logo 10px into it and the site menu's pill ending on it, so the logo and the
   menu stay exactly where they are when a visitor moves between 1p.dev and the
   docs. The search follows the logo on the left. Once the page scrolls it folds
   to a round frosted button the size of the Login button, and opens again when
   it is clicked (or focused), or when the page is back at the top. The script
   that sets html.p1-docs-scrolled is in overrides/main.html. Last in this file,
   so it wins over the earlier header and search rules. */
@media screen and (min-width: 1220px) {
  .md-header > .md-header__inner {
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 clamp(22px, 5vw, 72px) !important;
    gap: 0 !important;
  }
  .md-header .md-header__button.md-logo { margin: 0 0 0 -10px !important; padding: 0 !important; }
  .md-header__inner .md-search {
    position: static !important;
    transform: none !important;
    flex: 0 0 auto !important;
    display: block !important;
    width: auto !important;
    margin: 0 0 0 24px !important;
  }
  .md-header__inner .esb-shell { margin-left: auto !important; }
  /* the results open from the field's left edge, not centred on it (it is at the left of the page now) */
  .md-header__inner .md-search__output { left: 0 !important; transform: none !important; }

  .md-header__inner .md-search__inner {
    transition: width .28s cubic-bezier(.2, .7, .2, 1);
  }
  .md-header__inner .md-search__form {
    transition: background .2s ease, border-color .2s ease, box-shadow .2s ease, height .28s cubic-bezier(.2, .7, .2, 1) !important;
  }
  .md-header__inner .md-search__input { transition: opacity .18s ease; }

  /* folded: scrolled, and the search not open */
  html.p1-docs-scrolled [data-md-toggle=search]:not(:checked) ~ .md-header .md-search__inner { width: 42px !important; }
  html.p1-docs-scrolled [data-md-toggle=search]:not(:checked) ~ .md-header .md-search__form:not(:focus-within) {
    height: 42px !important;
    border-color: transparent !important;
    background: var(--nav-glass) !important;
    -webkit-backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
    backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
    box-shadow: var(--sh-2) !important;
    cursor: pointer;
  }
  html.p1-docs-scrolled [data-md-toggle=search]:not(:checked) ~ .md-header .md-search__form:not(:focus-within) .md-search__input {
    height: 42px !important;
    opacity: 0;
    cursor: pointer;
  }
  html.p1-docs-scrolled [data-md-toggle=search]:not(:checked) ~ .md-header .md-search__form:not(:focus-within) .md-search__icon[for=__search] {
    left: 0 !important;
    width: 42px !important;
    color: var(--c-ink, #1b1f27) !important;
    pointer-events: none;   /* a click goes to the field under it, which opens the search and takes the cursor */
  }
  html.p1-docs-scrolled [data-md-toggle=search]:not(:checked) ~ .md-header .md-search__options { display: none !important; }
}
/* narrower, the logo sits 10px into the page margin too, as on 1p.dev */
@media screen and (max-width: 1219px) {
  .md-header .md-header__button.md-logo { margin-left: -10px !important; }
}
@media screen and (min-width: 1220px) and (prefers-reduced-motion: reduce) {
  .md-header__inner .md-search__inner,
  .md-header__inner .md-search__form,
  .md-header__inner .md-search__input { transition: none !important; }
}

/* ---- The search panel: only once there is something to show, and with the menus' nub ----
   Material opens the results panel as soon as the field takes the cursor, with "Type to start searching" in it.
   Now it stays shut until something is typed, and then shows the matches (or says there are none). It hangs
   under the field as the site menu's dropdowns hang under the pill, with the same small nub on top, here pointing
   up at the field's magnifier (site.css and the esb-panel rules above). The nub sits behind the results, so only
   its point shows above the panel. Where the search opens over the whole page (narrow screens), none of this. */
@media screen and (min-width: 60em) {
  .md-header .md-search__inner:has(.md-search__input:placeholder-shown) .md-search__output { display: none !important; }
  .md-header .md-search__output { overflow: visible !important; }
  .md-header .md-search__scrollwrap { position: relative; border-radius: inherit !important; }
  .md-header .md-search__output::before {
    content: ""; position: absolute; top: -5px; left: 23px; width: 10px; height: 10px;
    border-radius: 2px 0 0 0; background: var(--md-default-bg-color); rotate: 45deg;
    box-shadow: -2px -2px 4px -2px rgba(27, 31, 39, .12); pointer-events: none;
  }
}

/* ---- The search results: rows like the menus' dropdowns ----
   Each match is a rounded row inset from the panel's edge, lit on hover (and on the arrow keys) as the dropdowns'
   links are, and a thin line, inset too, parts one page's matches from the next, so a lit row never covers it.
   Two things used to spoil it: the pages' own h2 style reached in here (its rule and the 1.6rem above it drew a
   divider through every section's match), and both the link and the article inside it were padded, which
   doubled the space round each row. The earlier result rules above still set the fonts. */
.md-search-result__list { padding: 0 8px 8px !important; }
.md-search-result__meta { padding: 12px 20px 6px !important; }
.md-search-result__item,
.md-search-result__item:first-child { border: 0 !important; box-shadow: none !important; }
.md-search-result__item + .md-search-result__item { position: relative; margin-top: 9px; }
.md-search-result__item + .md-search-result__item::before {
  content: ""; position: absolute; left: 12px; right: 12px; top: -5px; border-top: 1px solid var(--p1-line);
}
.md-search-result__item .md-search-result__link { display: block; padding: 8px 12px !important; border-radius: 10px; }
.md-search-result__article { padding: 0 !important; }
.md-search-result__link:hover,
.md-search-result__link:focus,
.md-search-result__more > summary > div:hover { background: var(--c-lav-soft) !important; }
.md-search-result__article > h1,
.md-search-result__article > h2,
.md-search-result__article > h3 { padding: 0 !important; border: 0 !important; margin: 0 !important; }
.md-search-result__article > h2,
.md-search-result__article > h3 { font-size: 13.5px !important; color: var(--c-ink-2) !important; }
.md-search-result__article > p { margin-top: 2px !important; display: -webkit-box !important; -webkit-box-orient: vertical; -webkit-line-clamp: 2 !important; overflow: hidden; }
.md-search-result__article > p ~ p { display: none !important; }   /* (a long page's teaser ran on, paragraph after paragraph) */
.md-search-result__more > summary > div { padding: 6px 12px !important; border-radius: 10px; }


/* ---- Page to page, with the rest of 1p.dev ----
   The docs are on 1p.dev itself (at /docs/), so going between them and the other pages can be a view transition:
   the page cross-fades while the logo and the site menu's pill, which are named the same here as on 1p.dev
   (site.css, "page to page"), stay where they are. Between docs pages Material's instant navigation swaps the
   content and the header never leaves. None for reduced motion */
@view-transition { navigation: auto; }
/* touch screens: the page never slides sideways and a double tap does not zoom it, as on 1p.dev (site.css) */
@media (hover: none) and (pointer: coarse) {
  html, body { overflow-x: clip; }
  html { touch-action: manipulation; }
}
/* (No scrollbar-gutter: stable here, unlike 1p.dev. With it on the docs' root, Chrome took 1vw as either 14.4px or
   14.3px at 1440px, the scrollbar left in or taken out, and changed its mind at every hover: every size given in
   vw moved by a fraction, and the page trembled a pixel or two as the pointer crossed the sidebar or left the
   page. Without it, 1vw is the same here as on 1p.dev, and every docs page scrolls, so it is as wide as theirs.) */
.md-header .md-header__button.md-logo { view-transition-name: p1-logo; }
.esb-shell { view-transition-name: p1-menu; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
