/* ==========================================================================
   Pharos Cloud help - skin

   Aligned to the Pharos Brand Identity Guide v1.1. Colours and type come from
   the guide; anything outside it is marked DEVIATION with a reason.

   Brief remains: a reference tool used under pressure. Someone in a plant room,
   or remote-diagnosing at six in the evening, matching a status string on their
   screen against what we wrote. Legibility and scannability over polish.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens - Brand Palette

   Guide p.14. The five brand colours, then Cloud's product palette:
   primary Pharos Light Grey, secondary Pharos Grey / White / Pharos Blue.

   Contrast ratios on white, measured:
     Pharos Blue       #0080ff    3.80:1   large text and UI only, NOT body
     Pharos Light Grey #dadada    1.40:1   surfaces and rules only
     Pharos Grey       #575a5b    6.96:1   passes AA for body
     Express Grey      #1e2124   16.18:1   near-black
   -------------------------------------------------------------------------- */

:root {
  /* Brand Palette, verbatim from the guide */
  --ph-blue:        #0080ff;   /* Pharos Blue,       Process Blue C */
  --ph-grey-light:  #dadada;   /* Pharos Light Grey, Cool Gray 1 C  */
  --ph-grey:        #575a5b;   /* Pharos Grey,       425 C          */
  --ph-grey-dark:   #1e2124;   /* Express Grey,      419 C          */
  --ph-white:       #ffffff;

  /* Tints of Pharos Light Grey over white. The guide sanctions tinting - the
     Designer product palette lists a 40% tint of Light Grey explicitly. */
  --ph-wash:        #f0f0f0;   /* 40% tint - code, search field, admonitions   */
  --ph-line-soft:   #ebebeb;   /* 55% tint - inner table rules                 */
  --ph-line:        #dadada;   /* 100%     - hairlines, borders                */

  /* DEVIATION: a darkened Pharos Blue for small text.
     Pharos Blue is 3.80:1 on white, which fails WCAG AA for body text - and
     white on Pharos Blue is also 3.80:1, so white text on a blue chip fails
     too. This is the same hue at lower lightness, 6.02:1, used ONLY where blue
     carries or backs small text. Full-strength Pharos Blue is used everywhere
     it is decorative: rules, active markers, large text. */
  --ph-blue-text:   #0061c2;

  /* Ink. Express Grey as near-black for primary text: it is a Brand Palette
     colour, and Cloud's own Pharos Grey secondary is reserved below for
     genuinely secondary text, which is what it reads as. */
  --ph-ink:         #1e2124;   /* body and headings          16.18:1 */
  --ph-ink-soft:    #575a5b;   /* captions, nav, eyebrows     6.96:1 */
  --ph-ink-faint:   #8a8d8e;   /* DECORATIVE ONLY - 3.86:1, never text */

  /* --------------------------------------------------------------------
     Type - guide p.16

     Open Sans is the primary typeface, "for all digital and print
     applications". Arial is the sanctioned fallback "where only system
     fonts are available", so it heads the fallback stack rather than a
     generic sans.

     DEVIATION: a monospace stack. The guide specifies no mono, because it
     is a logo and identity guide and does not address code. Code cannot be
     set in a proportional face. A neutral system stack is used rather than
     a third branded face, so the brand voice stays Open Sans - the same
     reasoning the guide applies to Arial.
     -------------------------------------------------------------------- */
  --ph-sans: 'Open Sans', Arial, Helvetica, sans-serif;
  --ph-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas,
             'Liberation Mono', monospace;

  /* Type scale - guide p.16. Body copy = Y, S Heading = 1.25Y, L = 2Y, XL = 3Y.
     Expressed as calc so the brand ratios stay visible in the code.

     NOTE: the guide prints "S Heading = Y x 0.25", which cannot be right - the
     sample shows S larger than body copy. Read as 1.25Y. Worth confirming with
     marketing, it looks like a dropped digit. */
  --ph-y:   0.8rem;                        /* body copy          14.4px */
  --ph-s:   calc(var(--ph-y) * 1.25);      /* S Heading          18.0px */
  --ph-l:   calc(var(--ph-y) * 2);         /* L Heading          28.8px */
  --ph-xl:  calc(var(--ph-y) * 3);         /* XL Heading         43.2px */

  /* Map Material's variables onto ours so stock components inherit.

     Note: Material composes its stack as
       --md-text-font-family: var(--md-text-font, _), -apple-system, ...
     so the hook is --md-text-font, the font NAME. Setting
     --md-text-font-family directly does nothing - Material's own :root
     definition still wins and you silently get the system fallback. */
  --md-text-font: 'Open Sans';
  --md-code-font: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, 'Liberation Mono';
  --md-text-font-family: var(--ph-sans);
  --md-code-font-family: var(--ph-mono);
  --md-default-fg-color: var(--ph-ink);
  --md-default-fg-color--light: var(--ph-ink-soft);
  --md-default-fg-color--lighter: var(--ph-ink-faint);
  --md-default-bg-color: var(--ph-white);
  --md-primary-fg-color: var(--ph-white);
  --md-primary-bg-color: var(--ph-ink);
  --md-accent-fg-color: var(--ph-blue-text);
  --md-typeset-a-color: var(--ph-blue-text);
}

/* --------------------------------------------------------------------------
   1b. Overriding Material's palette

   Material sets its colour variables on BODY attributes -
   <body data-md-color-scheme="default" data-md-color-primary="white" ...> -
   and [data-md-color-scheme=default] outranks :root. So declaring these in
   :root above silently loses: body text stays Material's 87% black and links
   inherit whatever the named palette chose, which measured 1.40:1 here.

   body[data-md-color-scheme] is specificity 0,1,1 and wins cleanly.
   -------------------------------------------------------------------------- */

body[data-md-color-scheme],
body[data-md-color-primary],
body[data-md-color-accent] {
  --md-default-fg-color:          var(--ph-ink);
  --md-default-fg-color--light:   var(--ph-ink-soft);
  --md-default-fg-color--lighter: var(--ph-ink-faint);
  --md-default-fg-color--lightest: var(--ph-line);
  --md-default-bg-color:          var(--ph-white);

  --md-typeset-color:             var(--ph-ink);
  --md-typeset-a-color:           var(--ph-blue-text);
  --md-typeset-mark-color:        rgba(0, 128, 255, 0.24);
  --md-typeset-del-color:         rgba(168, 50, 42, 0.15);
  --md-typeset-ins-color:         rgba(0, 128, 255, 0.15);

  --md-accent-fg-color:           var(--ph-blue-text);
  --md-accent-fg-color--transparent: rgba(0, 128, 255, 0.1);
  --md-primary-fg-color:          var(--ph-white);
  --md-primary-bg-color:          var(--ph-ink);
  --md-primary-bg-color--light:   var(--ph-ink-soft);

  --md-code-fg-color:             var(--ph-ink);
  --md-code-bg-color:             var(--ph-wash);

  --md-footer-fg-color:           var(--ph-ink);
  --md-footer-fg-color--light:    var(--ph-ink-soft);
  --md-footer-bg-color:           var(--ph-white);
  --md-footer-bg-color--dark:     var(--ph-white);
}

html { font-size: 112.5%; }                /* 18px, so --ph-y lands on 14.4px */

.md-typeset { font-size: var(--ph-y); line-height: 1.7; }

/* --------------------------------------------------------------------------
   2. Header

   White, hairline, no shadow. Pharos Blue is an accent, never a header fill -
   which also keeps the logo's own blue from competing with a blue bar.
   -------------------------------------------------------------------------- */

.md-header {
  background: var(--ph-white);
  color: var(--ph-ink);
  box-shadow: none;
  border-bottom: 1px solid var(--ph-line);
}

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

/* Site name hidden - the logo carries the wordmark. */
.md-header__topic:first-child { display: none; }

.md-header__title {
  font-family: var(--ph-sans);
  font-weight: 600;
  font-size: var(--ph-y);
  letter-spacing: 0;
  margin-left: 0.6rem;
}

.md-logo { padding: 0.3rem; }

/* Sized to its own aspect ratio, so a wordmark is not squashed. The guide
   requires clear space of half the logo height on all sides (p.8); the padding
   here is that space. */
.md-logo img, .md-logo svg { width: auto; height: 1.3rem; }

.md-search__form {
  background: var(--ph-wash);
  border: 1px solid var(--ph-line);
  border-radius: 2px;
  box-shadow: none;
  height: 1.7rem;
}
.md-search__form:hover { background: var(--ph-white); border-color: var(--ph-ink-faint); }
.md-search__input { font-size: 0.72rem; }
.md-search__input::placeholder { color: var(--ph-ink-soft); }
.md-search__output { border-radius: 2px; }
[data-md-toggle=search]:checked ~ .md-header .md-search__form { background: var(--ph-white); }

/* --------------------------------------------------------------------------
   3. Left navigation

   Everything navigational lives here, page headings included (toc.integrate),
   so it has to stay quiet at depth: indentation and hairlines carry hierarchy,
   not colour. Pharos Blue appears only on the active item.
   -------------------------------------------------------------------------- */

.md-sidebar--primary { width: 12.4rem; }
.md-sidebar--secondary { display: none; }

.md-nav { font-size: 0.72rem; }

/* Hidden everywhere. It duplicates the logo and site name already in the
   header, and on the mobile drawer the overlay click still closes it
   independently of this label's own toggle function - nothing is lost. */
.md-nav__title { display: none; }

/* Section headers. Deliberately NOT a small-caps eyebrow any more - that read
   as a different capitalisation convention from a plain nav entry like
   "Welcome", which sits at top level with no section wrapper. Same size and
   case as any other nav link; bold plus the spacing below marks it as a new
   group. */
.md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container > a.md-nav__link,
.md-nav--primary > .md-nav__list > .md-nav__item--section > label.md-nav__link,
.md-nav--primary > .md-nav__list > .md-nav__item--section > a.md-nav__link {
  font-weight: 700;
  color: var(--ph-ink-soft);
  margin: 0;
  padding: 0 0.6rem;
  cursor: pointer;
}

/* Welcome sits at the same top-level rank as the section headers above,
   despite not being one (it's a lone page, not a group) - bolded to match
   their weight without picking up their margin/padding, which would tighten
   its spacing relative to the other leaf links below it. */
.md-nav--primary > .md-nav__list > .md-nav__item:not(.md-nav__item--section) > a.md-nav__link,
.md-nav--primary > .md-nav__list > .md-nav__item:not(.md-nav__item--section) > a.md-nav__link.md-nav__link--active {
  font-weight: 700;
}

.md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container {
  margin: 1.1rem 0 0.15rem;
  padding: 0;
}

.md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container > a.md-nav__link:hover {
  color: var(--ph-blue-text);
}

.md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container > a.md-nav__link--active {
  color: var(--ph-ink);
  box-shadow: inset 2px 0 0 var(--ph-blue);
}

.md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container > label.md-nav__link {
  display: none;
}

.md-nav__link {
  color: var(--ph-ink-soft);
  padding: 0.17rem 0.6rem;
  border-radius: 0;
  transition: color 90ms;
}

.md-nav__link:hover,
.md-nav__link:focus { color: var(--ph-blue-text); }

/* Active page: a Pharos Blue left rule rather than a filled pill. Reads as a
   marker in a margin, which is what it is. */
.md-nav__item .md-nav__link--active,
.md-nav__item .md-nav__link--active:hover {
  color: var(--ph-ink);
  font-weight: 600;
  background: transparent;
  box-shadow: inset 2px 0 0 var(--ph-blue);
}

.md-nav--primary .md-nav .md-nav .md-nav__list,
.md-nav__item--nested > .md-nav > .md-nav__list {
  border-left: 1px solid var(--ph-line-soft);
  margin-left: 0.75rem;
}

.md-nav--primary .md-nav .md-nav .md-nav__link { color: var(--ph-ink-soft); font-size: 0.7rem; }
.md-nav--primary .md-nav .md-nav .md-nav__link:hover { color: var(--ph-blue-text); }
.md-nav--primary .md-nav .md-nav .md-nav__link--active { color: var(--ph-ink); font-weight: 600; }

/* --------------------------------------------------------------------------
   4. Content and the brand type scale

   Weights follow the guide's own type-scale sample (p.17), where XL is bold and
   L is noticeably lighter. That is what keeps a 2Y section head from dominating
   a dense reference page.
   -------------------------------------------------------------------------- */

.md-content { max-width: none; }
.md-content__inner { margin: 0 1.2rem 2.4rem; padding-top: 1.4rem; max-width: 44rem; }
.md-content__inner > :last-child { margin-bottom: 0; }

/* XL Heading - 3Y, Bold */
.md-typeset h1 {
  font-family: var(--ph-sans);
  font-weight: 700;
  font-size: var(--ph-xl);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--ph-ink);
  margin: 0 0 1.1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--ph-line);
}

/* L Heading - 2Y, Regular. Set 300 for the guide's lighter look if preferred. */
.md-typeset h2 {
  font-family: var(--ph-sans);
  font-weight: 400;
  font-size: var(--ph-l);
  line-height: 1.2;
  letter-spacing: -0.012em;
  margin: 2.4rem 0 0.7rem;
  color: var(--ph-ink);
}

/* S Heading - 1.25Y, Semibold */
.md-typeset h3 {
  font-family: var(--ph-sans);
  font-weight: 600;
  font-size: var(--ph-s);
  line-height: 1.3;
  margin: 1.8rem 0 0.45rem;
  color: var(--ph-ink);
}

/* Body weight, Semibold - a run-in label. This help has many field lists.
   The guide's fourth level down is body copy, so this stays at Y. */
.md-typeset h4 {
  font-family: var(--ph-sans);
  font-size: var(--ph-y);
  font-weight: 600;
  color: var(--ph-ink);
  margin: 1.2rem 0 0.25rem;
}

.md-typeset p { margin: 0 0 0.9rem; }

/* Links in the darkened blue, since full-strength Pharos Blue fails contrast at
   body size. The underline means colour is never the sole signal. */
.md-typeset a {
  color: var(--ph-blue-text);
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 128, 255, 0.35);
}
.md-typeset a:hover { color: var(--ph-blue-text); border-bottom-color: var(--ph-blue); }

.md-typeset ul, .md-typeset ol { margin-bottom: 0.95rem; }
.md-typeset li { margin-bottom: 0.28rem; }
.md-typeset ul li::marker { color: var(--ph-blue); }
.md-typeset ol li::marker { color: var(--ph-ink-soft); font-variant-numeric: tabular-nums; }

/* Two hover zones, not one: hovering the title reveals the mark in a dark
   grey (still just "something is here"), and only hovering the mark itself
   goes to Pharos Blue (the "you can act on this specifically" cue). The two
   rules below are equal specificity, so the blue one MUST stay declared
   after the grey one - it is the more specific *intent* of the two, and
   relies on source order to win when both match at once (the mark is always
   inside the hovered title). No border-bottom: it is a mark, not a link. */
.md-typeset .headerlink {
  font-size: 0.6em;
  color: var(--ph-line);
  border-bottom: none;
  vertical-align: middle;
  transition: color 90ms;
}
.md-typeset :hover > .headerlink { color: var(--ph-ink-soft); }
.md-typeset .headerlink:hover { color: var(--ph-blue); }

/* "Copied" confirmation for the heading permalink, from copy-heading-link.js.
   Same quiet chip language as .ph-ui in section 5 below - a piece of UI
   feedback, not a link or a heading. Faded in/out by JS toggling the
   --show class; the timing lives here, not in a JS animation loop. */
.ph-copied {
  display: inline-block;
  margin-left: 0.4em;
  font-family: var(--ph-sans);
  font-size: 0.62rem;
  color: var(--ph-ink-soft);
  background: var(--ph-wash);
  border-radius: 4px;
  padding: 0.05em 0.45em;
  vertical-align: middle;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 150ms ease, transform 150ms ease;
  pointer-events: none;
}
.ph-copied--show { opacity: 1; transform: translateY(0); }

/* --------------------------------------------------------------------------
   5. Literal UI strings

   The signature. Anything the reader must match character-for-character against
   the Cloud screen, set apart from our own prose. Mono in a quiet grey chip -
   deliberately not blue and not underlined, so it reads as "a piece of UI"
   rather than a link. (Previously a Pharos Blue underline; that read too much
   like a hyperlink on the same page as real ones - see review feedback.)
   -------------------------------------------------------------------------- */

.ph-ui {
  font-family: var(--ph-mono);
  font-size: 0.86em;
  font-weight: 500;
  color: var(--ph-ink);
  background: var(--ph-wash);
  border-radius: 4px;
  padding: 0.05em 0.35em;
  white-space: nowrap;
}

.md-typeset h1 .ph-ui,
.md-typeset h2 .ph-ui,
.md-typeset h3 .ph-ui { background: none; font-size: 0.9em; }

/* ---- 5b. Tier-scoped table rows ---------------------------------------
   A div would split the table, so a row is marked by putting the marker
   inside its cells and hiding the whole row from there.
   -------------------------------------------------------------------- */

tr:has([data-pharos-tier="portal"]) { display: none; }
:root[data-tier="portal"] tr:has([data-pharos-tier="portal"]) { display: table-row; }

/* --------------------------------------------------------------------------
   6. Requirement chips - firmware and hardware gates
   -------------------------------------------------------------------------- */

.ph-req {
  display: inline-block;
  font-family: var(--ph-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ph-ink);
  background: var(--ph-wash);
  border: 1px solid var(--ph-line);
  border-radius: 2px;
  padding: 0.02rem 0.3rem;
  white-space: nowrap;
  vertical-align: 0.06em;
}

.ph-req--fw { border-left: 2px solid var(--ph-blue); }

/* --------------------------------------------------------------------------
   7. Tables - hairlines, no zebra, tabular numerals
   -------------------------------------------------------------------------- */

.md-typeset table:not([class]) {
  font-size: 0.74rem;
  border: none;
  border-top: 1px solid var(--ph-line);
  border-bottom: 1px solid var(--ph-line);
  box-shadow: none;
  border-radius: 0;
  font-variant-numeric: tabular-nums;
}

.md-typeset table:not([class]) th {
  background: transparent;
  color: var(--ph-ink-soft);
  font-size: 0.61rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--ph-line);
  padding: 0.45rem 0.7rem 0.35rem;
  vertical-align: bottom;
}

.md-typeset table:not([class]) td {
  border-top: 1px solid var(--ph-line-soft);
  padding: 0.45rem 0.7rem;
  vertical-align: top;
}

.md-typeset table:not([class]) tr:first-child td { border-top: none; }
.md-typeset table:not([class]) tbody tr:hover { background: var(--ph-wash); }

/* --------------------------------------------------------------------------
   8. Admonitions - flat left-rule blocks, matching the tier blocks

   SPECIFICITY NOTE: Material styles these as `.md-typeset .admonition.note`
   (0,3,1) and sets `border-color` on all four sides. A rule written as
   `.md-typeset .note` (0,2,1) loses, silently, and you get Material's stock
   palette instead - note #448aff, tip #00bfa5 teal, danger #ff1744,
   example #7c4dff purple. None of those is a Pharos colour. Matching Material's
   selector exactly wins on load order, since this file comes after theirs.

   Escalation is by WEIGHT, not hue, so it stays inside the Brand Palette:

     note        Pharos Grey rule, grey label       a calm aside
     important   Pharos Blue rule, filled label     the loudest brand-legal level
     warning     amber                              DEVIATION, see below
     danger      red                                DEVIATION, see below
   -------------------------------------------------------------------------- */

.md-typeset .admonition,
.md-typeset details {
  font-size: 0.76rem;
  border: 1px solid var(--ph-line);
  border-left: 3px solid var(--ph-grey);
  border-radius: 2px;
  box-shadow: none;
  background: var(--ph-wash);
  margin: 1.2rem 0;
  padding: 0.1rem 0.85rem;
}

/* [dir] leads the selector list because Material sets padding-left: 2rem via
   [dir=ltr] .md-typeset .admonition-title - the gutter for the icon. The icon is
   hidden below, but without matching that specificity the 36px gutter stays and
   every label sits indented into empty space. [dir] ties on specificity and wins
   on load order, and covers RTL too. */
[dir] .md-typeset .admonition-title,
[dir] .md-typeset summary,
.md-typeset .admonition-title,
.md-typeset summary {
  font-family: var(--ph-sans);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ph-ink-soft);
  background: transparent !important;
  border: none;
  margin: 0.65rem 0 0.3rem;
  padding: 0;
}

/* No icons - the uppercase label carries it. The ::after is Material's disclosure
   chevron on <details>, so it must NOT be blanket-removed or a collapsible section
   renders with nothing to show it can be opened. Killed only on admonition titles,
   which have no disclosure behaviour. */
.md-typeset .admonition-title::before,
.md-typeset summary::before,
.md-typeset .admonition-title::after { display: none; }
.md-typeset details > summary { padding-right: 0.6rem; }

/* Material's :focus-within halo is #448aff regardless of type, so kill it across
   the board rather than per type. The focus indicator lives on the focusable
   element, not on its container. */
.md-typeset .admonition:focus-within,
.md-typeset details:focus-within { box-shadow: none; }

/* ---- Everything Material colours off-brand, folded back to the calm aside.
        Listed explicitly so a stock rainbow type cannot leak in unnoticed. ---- */

.md-typeset .admonition.note,      .md-typeset details.note,
.md-typeset .admonition.abstract,  .md-typeset details.abstract,
.md-typeset .admonition.summary,   .md-typeset details.summary,
.md-typeset .admonition.tldr,      .md-typeset details.tldr,
.md-typeset .admonition.info,      .md-typeset details.info,
.md-typeset .admonition.todo,      .md-typeset details.todo,
.md-typeset .admonition.tip,       .md-typeset details.tip,
.md-typeset .admonition.hint,      .md-typeset details.hint,
.md-typeset .admonition.success,   .md-typeset details.success,
.md-typeset .admonition.check,     .md-typeset details.check,
.md-typeset .admonition.done,      .md-typeset details.done,
.md-typeset .admonition.question,  .md-typeset details.question,
.md-typeset .admonition.help,      .md-typeset details.help,
.md-typeset .admonition.faq,       .md-typeset details.faq,
.md-typeset .admonition.example,   .md-typeset details.example,
.md-typeset .admonition.quote,     .md-typeset details.quote,
.md-typeset .admonition.cite,      .md-typeset details.cite,
.md-typeset .admonition.bug,       .md-typeset details.bug {
  border-color: var(--ph-line);
  border-left-color: var(--ph-grey);
}

/* ---- IMPORTANT - the loudest level available inside the brand palette.

        Pharos Blue rule at 3px plus a filled label. White on full-strength
        Pharos Blue measures only 3.80:1, so the label is filled with the
        darkened blue to clear AA at this size. ---- */

.md-typeset .admonition.important, .md-typeset details.important {
  border-color: var(--ph-line);
  border-left-color: var(--ph-blue);
  border-left-width: 3px;
  background: var(--ph-wash);
}

.md-typeset .admonition.important > .admonition-title,
.md-typeset details.important > summary {
  display: inline-block;
  color: var(--ph-white);
  background: var(--ph-blue-text) !important;
  /* Negative left margin equal to the chip's own padding, so the GLYPHS line up
     with the body text while the fill still surrounds them. The -0.08em on the
     right trims the trailing space letter-spacing adds after the last letter;
     without it the chip reads right-heavy. */
  padding: 0.1rem calc(0.45rem - 0.08em) 0.1rem 0.45rem;
  border-radius: 2px;
  margin: 0.7rem 0 0.45rem -0.45rem;
}

/* ---- DEVIATIONS: the Brand Palette carries no semantic colours, and a warning
        has to look like a warning. Held to the minimum that reads as caution and
        danger. Worth running past marketing. ---- */

.md-typeset .admonition.warning,   .md-typeset details.warning,
.md-typeset .admonition.caution,   .md-typeset details.caution,
.md-typeset .admonition.attention, .md-typeset details.attention {
  border-color: var(--ph-line);
  border-left-color: #b8860b;
}

.md-typeset .admonition.danger,  .md-typeset details.danger,
.md-typeset .admonition.error,   .md-typeset details.error,
.md-typeset .admonition.failure, .md-typeset details.failure,
.md-typeset .admonition.fail,    .md-typeset details.fail,
.md-typeset .admonition.missing, .md-typeset details.missing {
  border-color: var(--ph-line);
  border-left-color: #a8322a;
}

/* ---- Placeholder notices stay off-brand deliberately: they must be impossible
        to mistake for shipping content. They go with the prototype. ---- */

.md-typeset .admonition.placeholder {
  border-color: #f0dcd9;
  border-left-color: #a8322a;
  background: #fdf4f3;
}
.md-typeset .admonition.placeholder > .admonition-title { color: #8f2b24; }

/* --------------------------------------------------------------------------
   9. Code
   -------------------------------------------------------------------------- */

.md-typeset code {
  font-size: 0.85em;
  background: var(--ph-wash);
  border: 1px solid var(--ph-line-soft);
  border-radius: 2px;
  padding: 0.05em 0.28em;
  color: var(--ph-ink);
}

.md-typeset pre > code { border: none; border-radius: 0; }
.md-typeset .highlight { font-size: 0.74rem; }
.md-typeset pre { border-radius: 2px; }
.md-typeset .highlight > pre > code { background: var(--ph-wash); }

.md-typeset kbd {
  font-family: var(--ph-mono);
  font-size: 0.78em;
  background: var(--ph-white);
  border: 1px solid var(--ph-line);
  border-bottom-width: 2px;
  border-radius: 2px;
  box-shadow: none;
  color: var(--ph-ink);
}

/* --------------------------------------------------------------------------
   10. Figures

   Screenshots get a frame, because Cloud's UI is largely white and would
   otherwise bleed into the page. Add {.plain} in Markdown to opt out - logos,
   marks, and diagrams that carry their own whitespace.
   -------------------------------------------------------------------------- */

.md-typeset img { max-width: 100%; }

.md-typeset img:not(.plain),
.md-typeset figure > img:not(.plain) {
  border: 1px solid var(--ph-line);
  border-radius: 2px;
}

.md-typeset figure { margin: 1.4rem 0; }

.md-typeset figcaption {
  font-size: 0.68rem;
  color: var(--ph-ink-soft);
  text-align: left;
  margin-top: 0.4rem;
  max-width: none;
}

/* Click to view full-size, from docs/javascripts/image-lightbox.js. Same
   `:not(.plain)` split as the frame above - a logo or diagram opted out of
   the screenshot treatment doesn't need enlarging either. */
.md-typeset img:not(.plain) { cursor: zoom-in; }

.ph-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5vh 5vw;
  /* var(--ph-ink) as an opaque scrim - this palette has no dark theme to
     clash with, so a plain rgba is simpler than a custom property. */
  background: rgba(30, 33, 36, 0.85);
  opacity: 0;
  visibility: hidden;
  transition: opacity 150ms ease;
  cursor: zoom-out;
}

.ph-lightbox--open { opacity: 1; visibility: visible; }

.ph-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 2px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
}

/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */

.md-footer { background: var(--ph-white); border-top: 1px solid var(--ph-line); }
.md-footer-meta { background: var(--ph-white); }
.md-footer__inner { padding: 0.5rem 0; }

.md-footer__link { color: var(--ph-ink-soft); opacity: 1; padding-top: 1rem; }
.md-footer__link:hover { color: var(--ph-blue-text); }
.md-footer__title { font-size: var(--ph-y); }
.md-footer__direction {
  font-size: 0.61rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ph-ink-soft);
}

.md-copyright,
.md-copyright__highlight { color: var(--ph-ink-soft); font-size: 0.64rem; }

.md-footer-meta__inner { padding: 0.5rem 0.8rem; }

/* A visible last-reviewed date, so a reader can tell whether what they are
   reading is current. The 2022 help carried no date anywhere, which is a large
   part of why nobody noticed it had drifted. */
.ph-stamp {
  font-family: var(--ph-mono);
  font-size: 0.62rem;
  color: var(--ph-ink-soft);
  margin-top: 0.15rem;
}
.ph-stamp b { font-weight: 600; color: var(--ph-ink); }

/* Build-number tooltip: which Cloud release the help text was checked against.
   CSS-only (no JS) - a span cannot take :hover on its own for touch/keyboard,
   hence tabindex to pick up :focus too. Positioned above the trigger, not
   below, since the stamp sits at the very bottom of the page and a
   below-anchored tooltip would run off the viewport. */
.ph-stamp__version { position: relative; display: inline-block; }
.ph-stamp__tooltip {
  position: absolute;
  bottom: 100%;
  left: 0;
  margin-bottom: 0.35rem;
  padding: 0.4rem 0.6rem;
  width: max-content;
  max-width: 15rem;
  font-family: var(--ph-sans);
  font-size: 0.64rem;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ph-ink);
  background: var(--ph-white);
  border: 1px solid var(--ph-line);
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 120ms ease, transform 120ms ease;
  pointer-events: none;
  z-index: 1;
}
.ph-stamp__tooltip code {
  font-family: var(--ph-mono);
  font-size: 0.95em;
  color: var(--ph-ink);
  background: var(--ph-wash);
  border-radius: 3px;
  padding: 0.05em 0.3em;
}
.ph-stamp__version:hover .ph-stamp__tooltip,
.ph-stamp__version:focus .ph-stamp__tooltip,
.ph-stamp__version:focus-within .ph-stamp__tooltip {
  opacity: 1;
  transform: translateY(0);
}

/* Footer link. The selector has to be this long because Material sets
     html .md-footer-meta.md-typeset a { color: var(--md-footer-fg-color--light) }
   at specificity (0,2,2). A bare .ph-support is (0,1,0) and loses silently - the
   link renders in Pharos Grey and looks like plain text rather than something you
   can click. */
html .md-footer-meta.md-typeset a.ph-support {
  /* Sans, not the mono inherited from .ph-stamp. The build number and date are
     data and belong in mono; this is a prose label. */
  font-family: var(--ph-sans);
  font-size: 0.64rem;
  color: var(--ph-blue-text);
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 128, 255, 0.35);
}

html .md-footer-meta.md-typeset a.ph-support:hover,
html .md-footer-meta.md-typeset a.ph-support:focus {
  color: var(--ph-blue);
  border-bottom-color: var(--ph-blue);
}

/* --------------------------------------------------------------------------
   12. Quality floor
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--ph-blue);
  outline-offset: 2px;
}

@media screen and (max-width: 76.1875em) {
  .md-nav--primary > .md-nav__list > .md-nav__item--section > .md-nav__container { margin-top: 0.9rem; }
  .md-content__inner { margin: 0 0.9rem 2rem; }
}

@media screen and (max-width: 44.9375em) {
  /* The brand scale at 3Y is a lot on a phone. Shrink Y and the whole scale
     follows, keeping the guide's ratios intact. */
  :root { --ph-y: 0.78rem; }
  html { font-size: 106%; }
}

@media print {
  .md-sidebar, .md-header, .md-footer__inner { display: none; }
  .md-typeset a { border-bottom: none; }
  /* Background fills are unreliable in print, so fall back to a border - still
     reads as a distinct chip without depending on ink coverage. */
  .ph-ui { background: none; border: 1px solid var(--ph-grey); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --------------------------------------------------------------------------
   13. Sidebar safety net

   Material manages the primary sidebar's height in JavaScript. If that fails to
   run, the sidebar sits at height 0 with unconstrained content and the nav
   paints down over the footer. Capping the scrollwrap means the worst case is an
   internally scrolling nav rather than a broken page. Inert when Material's own
   sizing is working.
   -------------------------------------------------------------------------- */

@media screen and (min-width: 76.25em) {
  .md-sidebar--primary .md-sidebar__scrollwrap { max-height: calc(100vh - 7rem); }
}

/* --------------------------------------------------------------------------
   14. Font family assertion

   Material's font variables are composed rather than plain, and a future
   Material release could change how. Asserting the family on the roots that
   matter means the brand typeface cannot silently fall back to system sans.
   -------------------------------------------------------------------------- */

body,
input, button, select, textarea,
.md-typeset,
.md-nav, .md-header, .md-footer, .md-search { font-family: var(--ph-sans); }

.md-typeset code, .md-typeset pre, .md-typeset kbd,
.ph-ui, .ph-req, .ph-stamp { font-family: var(--ph-mono); }

/* --------------------------------------------------------------------------
   15. Disclosure control for long procedures

       ## Adding a device from Designer

       One line of orientation.

       ??? procedure "Expand to see more"
           1. ...

   The heading stays a real heading, so it still appears in the left nav. The
   collapsible holds only the steps, and its summary is therefore a CONTROL, not a
   heading - small, light, and coloured like an interactive element. Styling it at
   heading size made it compete with the h2 directly above it.
   -------------------------------------------------------------------------- */

.md-typeset details.procedure,
.md-typeset details.procedure:focus-within {
  border: none;
  border-radius: 0;
  background: transparent;
  padding: 0;
  margin: 0.5rem 0 1.3rem;

  /* Material draws a focus halo on the WHOLE block:
       .md-typeset details:focus-within { box-shadow: 0 0 0 .2rem #448aff1a }
     Two problems. It is #448aff, Material's default blue, not a Pharos colour. And
     :focus-within cannot tell a mouse click from a keyboard Tab, so expanding a
     section by clicking leaves a pale halo sitting there until focus moves - which
     is what reads as a stuck "selected" state.

     Suppressing it loses nothing: the focus indicator belongs on the summary, the
     element actually focused, and that is handled by :focus-visible below - which
     does distinguish mouse from keyboard. */
  box-shadow: none;
}

.md-typeset details.procedure > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.34rem;
  font-family: var(--ph-sans);
  font-size: var(--ph-y);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ph-blue-text);
  background: transparent !important;
  margin: 0;
  padding: 0;
  cursor: pointer;
  list-style: none;

  /* A summary is a control, so its label should not be selectable text. Left
     selectable, clicking to toggle picks a word on double-click and the whole
     label on any slight drag, leaving a selection highlight behind - which reads
     as a rendering fault in both Firefox and Chrome. Buttons do not behave that
     way, and neither should this. */
  -webkit-user-select: none;
  user-select: none;
}

.md-typeset details.procedure > summary::-webkit-details-marker { display: none; }

/* Chevron sits immediately after the text as a flex item, so it tracks a short
   label instead of floating off at the right-hand edge of the column.

   position and right MUST be reset: Material sets
   [dir=ltr] .md-typeset summary:after { right: .4rem } on an absolutely
   positioned pseudo-element. That ties this rule's specificity, and since it
   declares properties this rule did not, the chevron stayed absolute and landed
   on top of the last character of the label. */
.md-typeset details.procedure > summary::after {
  content: '';
  position: static;
  right: auto;
  left: auto;
  top: auto;
  bottom: auto;
  flex: none;
  width: 0.34rem;
  height: 0.34rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-0.12em) rotate(45deg);
  transition: transform 140ms ease;
  background: none;
  mask: none;
  -webkit-mask: none;
}

.md-typeset details.procedure[open] > summary::after {
  transform: translateY(0.06em) rotate(-135deg);
}

.md-typeset details.procedure > summary:hover { color: var(--ph-blue); }

.md-typeset details.procedure > summary:focus-visible {
  outline: 2px solid var(--ph-blue);
  outline-offset: 3px;
  border-radius: 1px;
}

/* Open content is inset and hung off a hairline, so it reads as belonging to the
   control that revealed it rather than as a new top-level section. */
.md-typeset details.procedure[open] > summary { margin-bottom: 0.5rem; }

.md-typeset details.procedure > summary ~ * {
  margin-left: 0;
  padding-left: 0.9rem;
  border-left: 1px solid var(--ph-line-soft);
}

.md-typeset details.procedure > :last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .md-typeset details.procedure > summary::after { transition: none; }
}

/* --------------------------------------------------------------------------
   16. Image path labels - AUTHORING BUILD ONLY

   Added by scripts/img_paths.py, which no-ops unless extra.authoring_tools is
   set. The published build never sees any of this.

   Overlaid on the bottom-left of the image, because a screenshot of Cloud is
   mostly white and a label below it competes with the caption space. Real text,
   not a ::after, so the path can be selected and copied - which is the point.
   -------------------------------------------------------------------------- */

.ph-imgpath {
  position: relative;
  display: inline-block;
  max-width: 100%;
  line-height: 0;            /* kill the inline-block descender gap */
}

.ph-imgpath__label {
  position: absolute;
  left: 0;
  bottom: 0;
  max-width: 100%;
  box-sizing: border-box;
  padding: 0.1rem 0.34rem;
  font-family: var(--ph-mono);
  font-size: 0.58rem;
  line-height: 1.5;
  letter-spacing: 0;
  color: #fff;
  background: rgba(30, 33, 36, 0.82);   /* Express Grey at 82% - legible over white UI */
  border-top-right-radius: 2px;
  /* Wrap rather than truncate. An ellipsis eats the END of the string, which is
     the filename - the one part you actually need to find the file. On a narrow
     screenshot this becomes two lines, which is a fair price for a dev aid. */
  white-space: normal;
  word-break: break-all;
  user-select: all;          /* one click selects the whole path */
  cursor: text;
  pointer-events: auto;
}

/* Dim until hovered, so the labels do not fight the screenshots while reading. */
.ph-imgpath__label { opacity: 0.55; transition: opacity 100ms; }
.ph-imgpath:hover .ph-imgpath__label { opacity: 1; }

/* Below the image instead of over it - swap these two rules if you prefer. */
/*
.ph-imgpath__label {
  position: static;
  display: block;
  background: none;
  color: var(--ph-ink-soft);
  opacity: 1;
  padding: 0.25rem 0 0;
}
*/

@media print { .ph-imgpath__label { display: none; } }

/* --------------------------------------------------------------------------
   17. Device scope

   Rendered by scripts/device_scope.py from a `devices:` frontmatter key. Sits
   under the h1 and says which kinds of device a tab applies to.

   Laid out as a delimited strip - lead-in, dot separators, a closing hairline -
   so it reads as a distinct band of metadata rather than as body prose. The
   loudness is taken out of the type instead: sentence case, normal weight, no
   letterspacing, and links that only underline on hover.

   Colour stays --ph-ink-soft. At 6.96:1 that is the palette's floor for text;
   --ph-ink-faint is 3.86:1 and fails AA.
   -------------------------------------------------------------------------- */

/* Two stacked rules read as a band. Where a scope strip follows the h1, suppress
   the h1's own border and let the strip's rule close the title block, so the
   strip belongs to the title rather than sitting in its own compartment. */
.md-typeset h1:has(+ .ph-scope) {
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 0.5rem;
}

.md-typeset .ph-scope {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.28rem 0.5rem;
  margin: 0 0 1.4rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--ph-line);
  font-size: 0.69rem;
  line-height: 1.5;
  color: var(--ph-ink-soft);
}

.ph-scope__lead {
  font-size: inherit;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: inherit;
}

/* Dot separator between items, drawn rather than typed so it stays optically
   centred whatever the surrounding type size. */
.md-typeset .ph-scope__item + .ph-scope__item::before {
  content: '';
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ph-line);
  vertical-align: 0.2em;
  margin-right: 0.55rem;
  margin-left: -0.12rem;
}

.md-typeset .ph-scope a {
  color: inherit;
  text-decoration: none;
  border-bottom: none;
}

.md-typeset .ph-scope a:hover {
  color: var(--ph-blue-text);
  border-bottom: 1px solid var(--ph-blue);
}

.md-typeset .ph-scope__item--all a { color: inherit; }

@media print { .md-typeset .ph-scope { border-bottom-color: var(--ph-line); } }

/* --------------------------------------------------------------------------
   18. Content tabs

   Material's default content tabs are a row of labels with a sliding underline
   under the active one. That is the same pattern as the Pharos Cloud device tab
   bar (Overview / Triggers / Status / Fixtures / ...), so on pages carrying
   screenshots of that bar the doc tabs read as more product chrome rather than
   as a control the reader can operate.

   These are restyled as a segmented control instead: an enclosed track with the
   active segment raised onto the page background. Unambiguously a widget, and
   not something the product itself has anywhere.

   Three things have to be undone to get there.

   The sliding indicator, a :before on .tabbed-labels positioned with
   --md-indicator-x / --md-indicator-width, added only under .js.

   The active-label styling, which Material emits as long
   input:nth-child(N):checked ~ .tabbed-labels > :nth-child(N) chains rather
   than a class or aria-selected. The chains below cover six tabs; a seventh
   would silently lose its active styling rather than break.

   The link underline. Material's JS rewrites each label at runtime to
   <label><a href="#__tabbed_1_1"></a></label> and adds .tabbed-labels--linked.
   Those anchors then inherit section 4's global underline, putting a Pharos
   Blue rule under every tab name. It is not in the served HTML, so it only
   appears once the page has scripted.
   -------------------------------------------------------------------------- */

.md-typeset .tabbed-set {
  margin: 1.4rem 0;
}

/* The track. .tabbed-set is a flex container, so the track has to be told not
   to stretch across it. */
.md-typeset .tabbed-labels {
  display: inline-flex;
  flex: 0 0 auto;
  align-self: flex-start;
  gap: 2px;
  box-shadow: none;
  background: var(--ph-wash);
  border: 1px solid var(--ph-line-soft);
  border-radius: 7px;
  padding: 3px;
  margin-bottom: 0.9rem;
  overflow: visible;
}

.js .md-typeset .tabbed-labels:before,
.md-typeset .tabbed-labels:before {
  display: none;
}

/* The segments. */
.md-typeset .tabbed-labels > label {
  flex: none;
  padding: 0.26rem 0.8rem;
  border-radius: 5px;
  font-size: 0.66rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--ph-ink-soft);
  transition: background-color 120ms, color 120ms;
}

.md-typeset .tabbed-labels > label:hover {
  color: var(--ph-ink);
}

/* The injected anchor is the label, not a link. It takes no colour, no
   underline and no hover of its own. */
.md-typeset .tabbed-labels > label > a,
.md-typeset .tabbed-labels > label > a:hover,
.md-typeset .tabbed-labels > label > a:focus {
  color: inherit;
  border-bottom: none;
  text-decoration: none;
}

/* The active segment, raised onto the page background. */
.md-typeset .tabbed-set > input:first-child:checked ~ .tabbed-labels > :first-child,
.md-typeset .tabbed-set > input:nth-child(2):checked ~ .tabbed-labels > :nth-child(2),
.md-typeset .tabbed-set > input:nth-child(3):checked ~ .tabbed-labels > :nth-child(3),
.md-typeset .tabbed-set > input:nth-child(4):checked ~ .tabbed-labels > :nth-child(4),
.md-typeset .tabbed-set > input:nth-child(5):checked ~ .tabbed-labels > :nth-child(5),
.md-typeset .tabbed-set > input:nth-child(6):checked ~ .tabbed-labels > :nth-child(6) {
  background: var(--md-default-bg-color, #fff);
  color: var(--ph-ink);
  border: 1px solid var(--ph-line);
  margin: -1px;
}

/* Keyboard focus, which the indicator used to carry. */
.md-typeset .tabbed-set > input.focus-visible ~ .tabbed-labels > label {
  outline: none;
}

.md-typeset .tabbed-set > input:first-child.focus-visible ~ .tabbed-labels > :first-child,
.md-typeset .tabbed-set > input:nth-child(2).focus-visible ~ .tabbed-labels > :nth-child(2),
.md-typeset .tabbed-set > input:nth-child(3).focus-visible ~ .tabbed-labels > :nth-child(3),
.md-typeset .tabbed-set > input:nth-child(4).focus-visible ~ .tabbed-labels > :nth-child(4),
.md-typeset .tabbed-set > input:nth-child(5).focus-visible ~ .tabbed-labels > :nth-child(5),
.md-typeset .tabbed-set > input:nth-child(6).focus-visible ~ .tabbed-labels > :nth-child(6) {
  box-shadow: 0 0 0 2px var(--ph-blue);
}

.md-typeset .tabbed-content > .tabbed-block > :first-child {
  margin-top: 0;
}

@media print {
  .md-typeset .tabbed-labels > label { color: var(--ph-ink); }
}

/* --------------------------------------------------------------------------
   19. Per-portal feature notice

   Rendered by scripts/feature_toggle.py from a `toggle_feature:` frontmatter
   key. Deliberately not a component of its own: it is a row inside the section
   17 scope strip, so type, colour and the closing hairline are the strip's and
   there is nothing here to keep in sync with it. On a page with no `devices:`
   key the hook builds the same `p.ph-scope` element and inserts it after the
   h1, so the h1 rule in section 17 hands the title block's hairline over
   exactly as it does for a real strip. That is what makes the notice behave the
   same in Overview, Sites, Devices, Portals, Reference and Troubleshooting.
   -------------------------------------------------------------------------- */

/* Its own line under the categories. 0.2rem on top of the strip's 0.28rem row
   gap - this is the one number to change if they want more air between them. */
.md-typeset .ph-scope__note {
  flex: 1 1 100%;
  margin-top: 0.2rem;
}

/* Section 5 of the tier stylesheet gives an inline scoped clause a wash and a
   dotted rule, which is right for a clause mid-sentence and wrong for a whole
   line. The notice opts out by attribute, so it stays clean whichever tier
   class it is given. */
.md-typeset .ph-scope__note[data-pharos-tier] {
  background: none;
  border-bottom: 0;
  padding-left: 0;
  padding-right: 0;
}

/* Where the notice is the only row, the strip's bottom padding belongs to the
   notice instead. A site owner has the notice hidden, and the strip then
   collapses to the hairline alone, so their title block is unchanged. */
.md-typeset .ph-scope--note-only { padding-bottom: 0; }

.md-typeset .ph-scope--note-only .ph-scope__note {
  margin-top: 0;
  padding-bottom: 0.6rem;
}

/* Section 17 takes link styling off the categories so they read as plain text.
   This one is a real link, so it takes the section 4 body-link treatment -
   softened underline at rest, full Pharos Blue on hover - rather than a third
   link style of its own. */
.md-typeset .ph-scope__note a {
  color: var(--ph-blue-text);
  border-bottom: 1px solid rgba(0, 128, 255, 0.35);
}

.md-typeset .ph-scope__note a:hover {
  color: var(--ph-blue-text);
  border-bottom-color: var(--ph-blue);
}

/* --------------------------------------------------------------------------
   20. Nav scrollbar

   Material hovers every scrollbar to --md-accent-fg-color, which here is the
   darkened Pharos Blue - the same colour as a link. In the nav that reads as a
   control the reader could operate rather than as chrome, so the sidebar keeps
   to greys and leaves the blue for things that are actually interactive.

   Selectors mirror Material's own so the cascade settles on source order rather
   than a specificity fight. Only the sidebar is changed; code blocks, search
   results and tooltips keep Material's behaviour.
   -------------------------------------------------------------------------- */

.md-sidebar__scrollwrap,
.md-sidebar__scrollwrap:hover,
.md-sidebar__scrollwrap:focus-within {
  scrollbar-color: var(--ph-line) transparent;
}

.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb,
.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb {
  background-color: var(--ph-line);
}

.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover,
.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover {
  background-color: var(--ph-ink-faint);
}

/* --------------------------------------------------------------------------
   21. FAQ disclosure bars

       ??? question "What connectivity does a device require?"
           Answer.

   Section 15 styles a `procedure` summary as a light inline CONTROL sitting
   under a real heading. A FAQ is the opposite case: the summary IS the item,
   there is no heading above it, and a reader scans a stack of them. So it is
   styled as a full-width bar with the label at sentence size.

   Three things section 8 does are wrong for that, and are undone here:

     - text-transform: uppercase (line 489). A question set in caps with 0.08em
       tracking is slow to scan, and a question mark after capitals reads as
       shouting rather than asking.

     - summary margin 0.65rem top / 0.3rem bottom (line 493). Asymmetric, which
       is right for a title with body text below it and wrong for a closed bar,
       where it drops the label below the optical centre. The block's padding is
       moved onto the summary instead, so top and bottom match AND the whole bar
       becomes the hit target rather than just the text.

     - the chevron. Material's is an absolutely positioned mask-image coloured
       from the admonition type's palette entry - #64dd17 for `question`, which
       is where the green comes from. Section 8 folds the BORDER colours back to
       brand but never touches ::after, so the green survives. Its `top` is also
       calibrated against Material's own summary metrics, which section 8 has
       already changed, so it no longer centres either.

       Replaced with the border-drawn chevron from section 15 - same 0.34rem
       square, same nudge values - which sidesteps both problems at once: it is
       a flex item, so it centres with align-items, and it takes its colour from
       a border rather than a masked background.

   SCOPE: `question` only. Material treats `help` and `faq` as aliases of it; if
   either gets used anywhere, add it to these selectors or it will render green.
   -------------------------------------------------------------------------- */

.md-typeset details.question,
.md-typeset details.question:focus-within {
  font-size: var(--ph-y);
  border: 1px solid var(--ph-line);
  border-left: 3px solid var(--ph-grey);
  border-radius: 2px;
  background: var(--ph-wash);
  box-shadow: none;

  /* Padding moves to the summary, so the bar is clickable edge to edge. */
  padding: 0;

  /* Section 8 sets 1.2rem, which reads as separate blocks. A FAQ is one list. */
  margin: 0.4rem 0;
}

/* [dir] leads for the same reason it does in section 8: Material sets
   padding-left on [dir=ltr] .md-typeset summary, and without matching that the
   icon gutter comes back. */
[dir] .md-typeset details.question > summary,
.md-typeset details.question > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;

  font-family: var(--ph-sans);
  font-size: var(--ph-y);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ph-ink);

  margin: 0;
  padding: 0.5rem 0.85rem;
  background: transparent !important;
  border: none;
  cursor: pointer;
  list-style: none;

  /* As section 15: a summary is a control, and its label should not be
     selectable text or a double-click leaves a selection highlight behind. */
  -webkit-user-select: none;
  user-select: none;
}

.md-typeset details.question > summary::-webkit-details-marker { display: none; }

/* position/right/left/top/bottom MUST all be reset - see section 15. Material's
   [dir=ltr] .md-typeset summary:after is absolutely positioned, and any property
   left undeclared here survives. */
.md-typeset details.question > summary::after {
  content: '';
  position: static;
  right: auto;
  left: auto;
  top: auto;
  bottom: auto;
  flex: none;
  width: 0.34rem;
  height: 0.34rem;
  border-right: 2px solid var(--ph-blue);
  border-bottom: 2px solid var(--ph-blue);

  /* A square with two borders rotated 45deg has its optical centre below its
     box centre, so it is nudged up when closed and down when open. */
  transform: translateY(-0.12em) rotate(45deg);
  transition: transform 140ms ease;
  background: none;
  mask: none;
  -webkit-mask: none;
}

.md-typeset details.question[open] > summary::after {
  transform: translateY(0.06em) rotate(-135deg);
}

.md-typeset details.question > summary:hover { color: var(--ph-blue-text); }

/* Inset, because the summary now fills the block - a positive offset would draw
   the outline outside the border. */
.md-typeset details.question > summary:focus-visible {
  outline: 2px solid var(--ph-blue);
  outline-offset: -2px;
  border-radius: 1px;
}

/* Open: a hairline under the bar separates the question from its answer without
   adding a second background. */
.md-typeset details.question[open] > summary {
  border-bottom: 1px solid var(--ph-line);
}

.md-typeset details.question > summary ~ * {
  margin-left: 0;
  padding-left: 0.85rem;
  padding-right: 0.85rem;
}

.md-typeset details.question > summary + * { margin-top: 0.7rem; }
.md-typeset details.question > :last-child { margin-bottom: 0.7rem; }

@media (prefers-reduced-motion: reduce) {
  .md-typeset details.question > summary::after { transition: none; }
}