/* Dosi docs — theming on top of Material.
   Kept in sync with docs/zh/assets/extra.css (CI enforces byte equality). */

/* ---------------------------------------------------------------- palette */
/* mkdocs.yml sets primary/accent to `custom`, so Material leaves these alone
   and the values below win in both schemes. Change the four ramps to rebrand. */

/* Brand: #402DF3. The light/dark ramps below are derived from it; the dark
   scheme deliberately lightens it (#402DF3 on Material's slate background is
   only ~2:1, well under AA — #6E5FF6 clears 4.5:1). */

:root,
[data-md-color-scheme="default"] {
  --md-primary-fg-color:          #402df3;
  --md-primary-fg-color--light:   #6e5ff6;
  --md-primary-fg-color--dark:    #2c1dc4;
  --md-primary-bg-color:          #ffffff;
  --md-primary-bg-color--light:   #ffffffb3;

  --md-accent-fg-color:           #5a46ff;
  --md-accent-fg-color--transparent: #402df31a;

  --md-typeset-a-color:           #402df3;   /* 7.3:1 on white */

  /* Neutrals carry a trace of the brand hue so surfaces don't read as grey. */
  --md-default-bg-color:          #ffffff;
  --dosi-surface:                 #f6f6fc;
  --dosi-border:                  #e4e3f2;
  --dosi-muted:                   #61607a;
}

[data-md-color-scheme="slate"] {
  --md-primary-fg-color:          #6e5ff6;
  --md-primary-fg-color--light:   #9b8cff;
  --md-primary-fg-color--dark:    #4a38d9;

  --md-accent-fg-color:           #8b7cff;
  --md-accent-fg-color--transparent: #6e5ff626;

  --md-typeset-a-color:           #9b8cff;   /* 4.6:1 on slate */

  --md-hue: 248;                    /* shifts Material's slate toward the brand */
  --dosi-surface:                 #21212e;
  --dosi-border:                  #33334a;
  --dosi-muted:                   #a5a4bd;
}

/* ------------------------------------------------------------ typography */
/* theme.font loads Inter / JetBrains Mono. Latin comes from those; CJK falls
   through to the platform's own UI face — loading a webfont for Chinese would
   cost megabytes, and every target OS ships a good one. Listing them
   explicitly (rather than letting the browser guess) is what keeps the
   Latin/CJK baseline and weight from drifting on the zh site. */

:root {
  --md-text-font-family:
    var(--md-text-font, _),
    "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei",
    "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei",
    -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
}

.md-typeset {
  font-feature-settings: "kern", "liga", "cv05";
  letter-spacing: -0.003em;
}

.md-typeset h1 {
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--md-default-fg-color);
}

.md-typeset h2 {
  font-weight: 650;
  letter-spacing: -0.015em;
  margin-top: 2.2em;
}

.md-typeset h3 {
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* CJK text needs a little more leading than Latin to stay comfortable. */
html[lang="zh"] .md-typeset {
  line-height: 1.75;
}

/* ---------------------------------------------------------------- layout */
/* Material's default 61rem content grid is tight for the wide tables in
   connectors.md / window-extension.md. */

.md-grid {
  max-width: 74rem;
}

/* The wider grid is for the big tables in connectors.md / window-extension.md.
   Prose must not follow it out to a 110-character measure — most visible on
   the landing page, which hides both sidebars. Block-level children only, so
   tables, code and card grids keep the full width. Material sets
   html{font-size:125%}, so 1rem is 20px here and 40rem is ~800px. */
.md-typeset > p,
.md-typeset > ul,
.md-typeset > ol,
.md-typeset > blockquote {
  max-width: 40rem;
}

/* Header chrome: deep navy in both schemes. A full-bleed #402DF3 slab was too
   much saturated colour above every page; #0B1542 carries the same brand
   family at reading weight (17.8:1 against white). The brand violet itself is
   only 2.4:1 on that navy, so header accents use the lightened --dosi-on-navy
   instead. */

:root {
  --dosi-navy: #0b1542;
  --dosi-on-navy: #8b7cff;
}

.md-header,
.md-tabs {
  background-color: var(--dosi-navy);
  color: #ffffff;
}

.md-header {
  box-shadow: none;
}

.md-header__title,
.md-header__button,
.md-tabs__link,
.md-header__source {
  color: #ffffff;
}

.md-header__topic:first-child {
  font-weight: 700;
  letter-spacing: -0.01em;
}

.md-tabs__link {
  opacity: 0.7;
}

.md-tabs__link:hover,
.md-tabs__link--active {
  opacity: 1;
  color: #ffffff;
}

.md-tabs__item--active .md-tabs__link {
  box-shadow: inset 0 -2px 0 0 var(--dosi-on-navy);
}

/* Search sits on the navy, so it gets a translucent well rather than the
   page's light surface. */
.md-search__form {
  background-color: #ffffff1a;
  border: 1px solid #ffffff26;
}

.md-search__form:hover {
  background-color: #ffffff26;
  border-color: var(--dosi-on-navy);
}

.md-search__input::placeholder,
.md-search__icon {
  color: #ffffffb3;
}

.md-search__input {
  color: #ffffff;
}

.md-nav__title {
  font-weight: 600;
}

.md-sidebar--primary .md-nav__link,
.md-sidebar--secondary .md-nav__link {
  padding: 0.15rem 0;
}

/* ----------------------------------------------------------- code blocks */

.md-typeset pre > code {
  border-radius: 0.4rem;
}

.md-typeset .highlight,
.md-typeset pre {
  border-radius: 0.4rem;
}

.md-typeset code {
  border-radius: 0.25rem;
}

.md-typeset :not(pre) > code {
  background-color: var(--dosi-surface);
  border: 1px solid var(--dosi-border);
  padding: 0.1em 0.35em;
}

/* ----------------------------------------------------------------- tables */

.md-typeset table:not([class]) {
  border: 1px solid var(--dosi-border);
  border-radius: 0.4rem;
  overflow: hidden;
}

.md-typeset table:not([class]) th {
  background-color: var(--dosi-surface);
  font-weight: 600;
}

/* ------------------------------------------------------------ grid cards */

.md-typeset .grid.cards > ul > li {
  border: 1px solid var(--dosi-border);
  border-radius: 0.5rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.md-typeset .grid.cards > ul > li:hover {
  border-color: var(--md-accent-fg-color);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.07);
  transform: translateY(-2px);
}

.md-typeset .grid.cards > ul > li > hr {
  margin: 0.6em 0;
  border-color: var(--dosi-border);
}

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

/* Centred headline block over a wide diagram. The diagram is ~2:1 and dense
   with labels, so it cannot live in a half-width hero column — and a
   left-aligned text block above a full-width image leaves a dead right half.
   Centring the copy is what makes the two blocks read as one unit. */
.dosi-hero {
  margin: 2rem 0 2.25rem;
  text-align: center;
}

.dosi-hero > h1 {
  /* The tagline stays English on both sites, so it is never a CJK line. */
  font-family: var(--md-text-font, _), sans-serif;
  font-size: 2.6rem;
  line-height: 1.12;
  margin: 0 0 0.6rem;
  text-wrap: balance;
}

/* Three tiers: the English tagline, the positioning line, then the mechanism.
   The subtitle carries no trailing full stop — it reads as a tagline, and the
   Chinese convention is no 。 on headings and taglines. */
.dosi-hero__sub {
  font-size: 1.02rem;
  line-height: 1.45;
  font-weight: 600;
  color: var(--md-default-fg-color);
  margin: 0 auto 0.7rem;
  max-width: 34rem;
  letter-spacing: -0.005em;
}

.dosi-hero__lede {
  font-size: 0.82rem;
  line-height: 1.7;
  color: var(--dosi-muted);
  margin: 0 auto 1.8rem;
  max-width: 32rem;
}

.dosi-hero__actions .md-button {
  margin: 0 0.4rem 0.5rem 0;
}

/* Material styles every <figure> as `width: fit-content; margin: auto`; the
   `.md-typeset` prefix is what outranks it, not decoration.
   The diagram ships on an opaque white canvas, so in dark mode it would be a
   bare white slab — the card frame makes that read as deliberate. */
.md-typeset .dosi-figure {
  width: 100%;
  max-width: 58rem;          /* narrower than the grid, so it reads as a plate */
  margin: 0 auto 3rem;
  background-color: #ffffff;
  border: 1px solid var(--dosi-border);
  border-radius: 0.6rem;
  padding: 1.25rem;
}

.md-typeset .dosi-figure img {
  width: 100%;
  height: auto;
  display: block;
}

@media screen and (max-width: 76.234375em) {
  .dosi-hero > h1 {
    font-size: 2.1rem;
  }
  .dosi-hero__sub,
  .dosi-hero__lede {
    max-width: none;
  }
}

/* A quiet band behind the "see it in 30 seconds" transcript so the landing
   page has more than one visual weight. */

.dosi-showcase {
  background-color: var(--dosi-surface);
  border: 1px solid var(--dosi-border);
  border-radius: 0.6rem;
  padding: 1.2rem 1.4rem 0.4rem;
  margin: 1.2rem 0 2rem;
}

.dosi-showcase > .highlight:last-child {
  margin-bottom: 1.2rem;
}

/* --------------------------------------------------------------- details */

/* Keep the capability check marks aligned in tables. */
.md-typeset table td .twemoji svg {
  vertical-align: -0.125em;
}

.md-typeset .mermaid {
  text-align: center;
}

.md-footer {
  margin-top: 2rem;
}
