/* The identity cluster, and the wiki label.
 *
 * Its own stylesheet because it is the one thing all three bars share, and the
 * two areas do not share a stylesheet: the public site loads styles.css, the
 * admin and the editor load admin.css. Defining the cluster in both is how the
 * three copies drifted in the first place, so it lives here once and every
 * layout links it. See src/chrome.js for the markup.
 *
 * THE TYPE TIERS. A bar has three, and they are what make it read in order:
 *
 *   brand        the wordmark
 *   navigation   14px / 600 — where you can go
 *   utilities    12px / 500, muted — who you are, settings, theme
 *
 * Utilities used to be 13px / 600 against navigation's 14px / 600: one pixel
 * and no weight apart, so Password read as importantly as Pages. A step down is
 * most of what makes a bar feel ordered.
 */

/* Room for the scrollbar whether or not there is one.
 *
 * Without this the gutter appears with the scrollbar and goes with it, so the
 * viewport is about fifteen pixels narrower on a page that scrolls than on one
 * that does not — and every bar under it, the whole header included, steps
 * sideways by that much. It happens on the way in as well: a long list is
 * short until the rest of it has been parsed, so the bar is drawn, the
 * scrollbar arrives, and the bar moves. Reserving the gutter always costs
 * fifteen pixels on the pages that do not need it and buys a header that is
 * in the same place on every page of the wiki.
 *
 * Both areas, from the one stylesheet they share: it is the same header.
 */
html { scrollbar-gutter: stable; }

/* One strut for the whole row.
   The items are centred as BOXES, which is not the same as their text sharing a
   line: measured, the boxes all sat at y=41 while the text in them sat at 40.2,
   41, 40.2 and 41.5 — a 1.3px spread, enough to see. Three causes, all fixed by
   making every box the same shape rather than by nudging anything:
     · two items carried a 1px bottom border and no top one, so centring the box
       pushed their text half a pixel up;
     · the items had three different line-heights (18.6, 12 and 15), so each
       one's text sat differently inside its own centred box;
     · the sign-out FORM inherited the bar's 15px font, giving its line a 15px
       strut that its own 12px button then sat on top of.
   One font-size and one line-height for everything in here, and symmetric
   borders below, and the three go away together. */
.chrome-account {
  display: flex; align-items: center; gap: 16px;
  font-size: 12px; line-height: 1;
}

/* Every utility in the cluster is one tier: same size, same weight, same
   underline-on-hover. Written once so they cannot come apart again. */
.chrome-leave,
.chrome-pass,
.chrome-out button {
  font: inherit;
  font-size: 12px; font-weight: 500; line-height: 1;
  color: var(--soft);
  background: transparent; padding: 0;
  /* The hover underline is a border, so the box needs the same border top and
     bottom — otherwise the box is 1px taller at the bottom and centring lifts
     the text off the row's line. Only the bottom one is ever coloured. */
  border: 1px solid transparent; border-left: 0; border-right: 0;
  cursor: pointer; white-space: nowrap;
  transition: border-color .12s ease, color .12s ease;
}
.chrome-leave:hover,
.chrome-pass:hover,
.chrome-out button:hover { color: var(--ink); border-bottom-color: currentColor; }
/* The form is a flex item like any other, and its own strut has to match what
   is inside it — inherited, it was the bar's 15px against the button's 12. */
.chrome-out { display: inline; margin: 0; font-size: 12px; line-height: 1; }

/* Who you are is the quietest thing in the cluster — it is a fact, not an
   action, and nothing in it is clickable. */
.chrome-who {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--faint); white-space: nowrap; line-height: 1;
}

/* Role tags: 1px box, no fill — an admin reads heavier than an editor. Shown
   wherever the email is shown, because it is the one place that can answer
   "why can't I do this?". */
.role {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .1em;
  padding: 2px 6px; border: 1px solid var(--hair); color: var(--soft); line-height: 1.3;
}
.role-admin { border-color: var(--rule); color: var(--ink); }
/* A reader writes nothing, so it reads lighter still — dashed, not solid. */
.role-reader { border-style: dashed; color: var(--faint); }

/* Which wiki this page belongs to. It sits in the slot beside the wordmark that
   the admin bar uses for its switch — the same question, in the same place — and
   it is cut from one of that switch's own cells: 32px tall inside a 2px rule,
   13px/700, 14px of padding. One cell, not the pair: the editor states where you
   are, it does not offer the other side.

   The metrics are the point of writing them down. The label was once a small tag
   built from the role badge instead — 21px against the switch's 36 — so the one
   solid shape in the bar resized as you opened an editor, which reads as the
   wordmark beside it moving. Measured both. A box of the switch's own size does
   not do that, wherever it sits.

   Keep these values in step with .wiki-switch a in admin.css; the two sheets
   never load together, so neither can reference the other. */
.wiki-label { display: inline-flex; align-items: stretch; flex: none; }
.wiki-cell {
  display: flex; align-items: center; padding: 0 14px; height: 32px;
  font-size: 13px; font-weight: 700; white-space: nowrap;
  /* The rule is on the CELL, as it is on the switch's, so the box is 32px tall
     in both bars. Carried by the container instead, it was 32 plus two borders
     — the same box, four pixels taller than the one it is meant to match. */
  color: var(--ink); border: 2px solid var(--rule);
}
/* Filled on the internal side, plain on the public one — one box, two states
   nobody can confuse. */
.wiki-cell-on { background: var(--ink); border-color: var(--ink); color: var(--bg); }

/* --- The menu -------------------------------------------------------------- *
 * One button and a panel, holding whatever a bar cannot keep on screen. Shared
 * by all four bars — the admin chrome, the editor's bar, and the two site
 * headers — because the public site loads none of the admin's stylesheets and a
 * second menu that merely resembled this one is exactly how the three copies of
 * the identity cluster drifted apart.
 *
 * It is hidden until a surface asks for it. WHEN to fold is each bar's own
 * question, answered where its contents stop fitting: the admin bar at 1060, the
 * team wiki's header at 800, navigation at 700. WHAT it looks like is one
 * answer, and it lives here, outside any media query — that was the bug the last
 * round: the display rule moved to a wider breakpoint and the appearance stayed
 * behind in the phone block, so between the two the bar showed a bare
 * disclosure triangle with both icons stacked under it and a panel that would
 * not shut.
 *
 * The panel is absolutely positioned, so every header that turns the menu on
 * must be a positioned box (see .site-header / .admin-header / .editor-topbar).
 * -------------------------------------------------------------------------- */
.chrome-menu { display: none; }

/* The button's label, for anyone who cannot see the icon. It has to live here,
   with the component: defined only in admin.css, the team wiki's own header —
   which loads none of that sheet — rendered the word "Menu" in the bar beside a
   squashed icon. Seen in a screenshot, on the first fold. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.chrome-menu-btn {
  /* A grid rather than a flex row so the two icons can share one cell and cross
     over in place. Swapped with `display`, they changed between frames — the one
     hard cut left in a bar that otherwise moves at .12s. The label is
     position:absolute (.sr-only) and so takes no cell. */
  display: grid; place-items: center;
  width: 44px; height: 44px; margin: -9px -10px -9px 0; /* 44px touch target, same optical box */
  cursor: pointer; list-style: none; color: var(--ink);
}
.chrome-menu-btn::-webkit-details-marker { display: none; }
.chrome-menu-btn svg {
  grid-area: 1 / 1; width: 22px; height: 22px;
  transition: opacity .18s cubic-bezier(.4, 0, .2, 1),
              transform .24s cubic-bezier(.4, 0, .2, 1);
}
/* A quarter turn each, in the same direction, so the bars appear to rotate INTO
   the cross rather than one fading out under the other. */
.chrome-menu-btn .menu-cross { opacity: 0; transform: rotate(-90deg); }
.chrome-menu[open] .menu-bars { opacity: 0; transform: rotate(90deg); }
.chrome-menu[open] .menu-cross { opacity: 1; transform: rotate(0); }

/* The panel hangs off the header, so it covers the page rather than shoving it
   down the screen. Above the admin's sticky filter bar (z-index 30).
   A box under the button, not a full-bleed shelf: at 1000px across that shelf
   would be a metre of empty rule with three rows adrift in it. It goes full
   width on a phone, where the screen IS the width of the menu.
   `top: 100%` is against the PADDING edge, so the panel lands on the header's
   own rule and takes it as its top edge — which is why border-top is 0. Offset
   past it instead, the rule shows as a black bar between the two and the panel
   reads as a separate thing stuck underneath.

   The geometry is on the panel itself and not on the open state, because both
   states have to describe the same box for there to be anything to animate
   between. Shut means shut is now said in the `display: none` here: relying on
   how the browser hides a closed <details> does not survive contact with a panel
   that has styling of its own — measured, it stood permanently open.

   It opens as a wipe: the box is clipped to nothing at its top edge and the clip
   travels down, so the bottom rule is drawn downwards across the rows rather
   than the panel sliding or growing. Rules are how this design divides things,
   so a rule in motion is the one gesture that is already in the language.
   The wipe does all of it, with no fade underneath. A fade was tried and taken
   out: the panel begins at zero height, so there is no hard edge for one to
   soften, and while it ran the page showed straight through the panel — at 60ms
   a button behind it was legible through three rows of the menu.

   `display` is in the transition with `allow-discrete`, and @starting-style
   gives the entry a from-state — that pair is what lets a `display: none`
   element animate both ways with no JavaScript, which the whole control depends
   on. A browser without them ignores both and the menu simply appears, as it
   did before. */
.chrome-menu-panel {
  display: none;
  position: absolute; top: 100%; right: 0; left: auto; z-index: 40;
  width: 320px; max-width: 100%;
  background: var(--bg); border: 2px solid var(--rule); border-top: 0;
  padding: 0 20px 16px;
  clip-path: inset(0 0 100% 0);
  transition: clip-path .24s cubic-bezier(.4, 0, .2, 1),
              display .24s allow-discrete;
}
.chrome-menu[open] > .chrome-menu-panel {
  display: block;
  clip-path: inset(0 0 0 0);
}
@starting-style {
  .chrome-menu[open] > .chrome-menu-panel { clip-path: inset(0 0 100% 0); }
}

/* ...and one more thing has to be held open for the CLOSE to play.
   A closed <details> in Chromium does not merely hide its contents: it sets
   content-visibility on the UA's ::details-content box, and nothing inside a
   content-visibility:hidden subtree animates at all. So the closing wipe was
   skipped outright — measured, the open produced 16 interpolated frames and the
   close produced one. Our own `display` transition cannot help, because the
   subtree is gone before it is consulted.
   Transitioning content-visibility discretely holds that flip for the length of
   the wipe, so the panel gets to draw its own exit. The selector is unknown to
   browsers without it, which drop these two rules and keep the instant close
   they already had. */
.chrome-menu::details-content {
  content-visibility: hidden;
  transition: content-visibility .24s allow-discrete;
}
.chrome-menu[open]::details-content { content-visibility: visible; }

/* Motion is the decoration here, not the control: with it off the menu still
   opens and shuts, instantly. Stated for the component rather than left to each
   sheet's blanket rule, since chrome.css is loaded by pages that have neither. */
@media (prefers-reduced-motion: reduce) {
  .chrome-menu-panel, .chrome-menu-btn svg { transition: none; }
  .chrome-menu::details-content { transition: none; }
}

/* Everything in it becomes a row with a hairline above it — the same list
   language the rest of the wiki speaks.
   The rows are the cluster's OWN children. The cluster is one element now, so
   styling the wrapper's children styled the wrapper and left the five items
   inside it in the flex row they wear in the bar: "Password Log out" side by
   side under a hairline belonging to neither. */
.chrome-menu-panel .chrome-account {
  /* A grid rather than a column so its last row can hold two things: who you
     are, and the theme control at the far end of it. Both are statements about
     the session rather than places to go, and neither is worth a row of its own
     at the foot of a menu.
     Cells stretch rather than centre. Centred, the two halves of that row were
     different heights and each carried its own top border, so the hairline came
     out in two pieces two pixels apart — a visible step. Stretched, both cells
     span the row and their borders land on one line; the content inside each is
     what gets centred. */
  display: grid; grid-template-columns: 1fr auto; align-items: stretch; gap: 0; width: auto;
}
.chrome-menu-panel .chrome-account > * {
  display: block; width: 100%; text-align: left;
  padding: 13px 0; border-top: 0; border-bottom: 1px solid var(--hair);
  grid-column: 1 / -1; /* a full-width row, unless placed otherwise below */
}
/* The rows rule BELOW themselves, not above. Ruling above meant the first row
   drew a hairline 1px under the bar's own 2px rule — two lines five pixels
   apart, which is what made the open menu read as a torn-off fragment rather
   than as the header continuing downwards. Ruling below, the panel's top edge is
   the bar's rule and nothing competes with it.
   Which row is first changes with the surface — the admin leads with its nav,
   the team wiki with the cluster, and between 700 and 1060 the admin's nav is in
   the panel but hidden — so there is no reliable `:first-child` to exempt. There
   is a reliable LAST row: the two that are ordered to the end of the grid. */
.chrome-menu-panel .chrome-who,
.chrome-menu-panel .theme-toggle { border-bottom: 0; }
/* The last row, made of the two that are ordered to the end of the grid. */
.chrome-menu-panel .chrome-who {
  display: flex; align-items: center; order: 1; grid-column: 1; width: auto;
}
.chrome-menu-panel .theme-toggle {
  order: 2; grid-column: 2; width: auto; justify-self: stretch;
  /* Its own box fills the row's height, so the mark is centred within it rather
     than sitting wherever the button's baseline fell. */
  display: flex; align-items: center; justify-content: flex-end;
  /* Sized to a finger, not to the glyph: on its own the mark is 14px across. */
  min-width: 44px;
}

/* On a phone the panel stops being a box under the button and becomes a shelf:
   edge to edge, with only the bottom rule left to close it. The screen down here
   IS the width of the menu, and a 320px box floating over the text reads as a
   fragment rather than as the header opening. */
@media (max-width: 700px) {
  .chrome-menu-panel {
    left: 0; right: 0; width: auto;
    border: 0; border-bottom: 2px solid var(--rule);
  }
}
