/* ============================================================================
 * topbar — a thin shelf beside an ink column
 * ============================================================================
 *
 * The other half of a sidebar-chromed page: the column says where everything
 * is, and this holds whatever the page needs across the top of the rest.
 *
 * IT HAS NO CONTENTS OF ITS OWN. The host writes them — a `searchbar` on the
 * documentation, a row of editing tools in HQ — and the shelf supplies the
 * ground, the height and the triad that closes it.
 *
 * ---- Using it --------------------------------------------------------------
 *
 *   <link rel="stylesheet" href="/shared/components/topbar/topbar.css">
 *
 *   <div class="topbar">
 *     …whatever goes in it…
 *     <div class="navbar-accent"><span></span><span></span><span></span></div>
 *   </div>
 *
 * There is no HTML include, because an include cannot take contents. The bar is
 * four lines of markup and the host owns them, exactly as it owns the column's.
 *
 * The host supplies one number: how far from the left edge the bar starts,
 * because only the host knows what sits beside it. See README.md.
 *
 * ---- Why it lines up with the column ---------------------------------------
 *
 * ITS HEIGHT IS NOT A NUMBER OF ITS OWN. The bar closes — triad and all — on
 * exactly the line where the column beside it stops being a masthead and starts
 * being a list, so the two halves of the chrome begin their content on the same
 * row. That line is sidenav's, published by sidenav.css as --sidenav-top,
 * --sidenav-mark-h and --sidenav-mark-gap, and summed here.
 *
 * Written as a sum rather than as the 68px it resolves to, because a literal is
 * a promise someone breaks the first time the wordmark changes size, and the
 * failure is a few pixels of misalignment nobody files.
 *
 * ---- Layer -----------------------------------------------------------------
 *
 * `component`, as every shared component is. The order is declared once in
 * brand.css (brand, site, component, page), so this outranks a site's own
 * layout and is outranked by the page hosting it, wherever the <link> sits.
 * ========================================================================== */
@layer component {

:root {
  --topbar-accent-h: 4px;   /* the triad's height — brand.css .navbar-accent */
  --topbar-h: calc(var(--sidenav-top) + var(--sidenav-mark-h)
                   + var(--sidenav-mark-gap) + var(--topbar-accent-h));
  /* The bar's content box: what --topbar-h has left once the padding above and
     below it comes out. Occupants are STATED against this rather than left to
     stretch, because a stretched height is not a number a child can compute a
     width from — a square built that way takes its width from its glyph and
     stops being square. */
  --topbar-field-h: calc(var(--topbar-h) - 2 * var(--sidenav-top)
                         - var(--topbar-accent-h));
}

/* Light, not ink: the column beside it is the page's one ink surface, and a
 * second one abutting it would read as a single L-shaped slab rather than as two
 * pieces of chrome. A --panel shelf with an ink underline sits ON the grey desk
 * the way every other Drift card does.
 *
 * `position: fixed` is the component's, not the host's, unlike the column's
 * pinning — a searchbar's dimming depends on this element forming a stacking
 * context, and fixed positioning is what creates one. Only --topbar-left is the
 * host's, because only the host knows what sits to the left of the bar. */
.topbar {
  position: fixed;
  top: 0;
  left: var(--topbar-left, 0px);
  right: 0;
  height: var(--topbar-h);
  /* Under a pinned column's 998. They do not overlap, but the column is the
     more important surface if a future width ever makes them. */
  z-index: 997;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--panel);
  /* ONE number on all four sides, and it is the column's own top padding.
     Two things fall out of that. What the bar holds starts on exactly the line
     the wordmark does across the gutter, because both are --sidenav-top from the
     top of the page. And the gap above, below and to the left of it is that same
     measurement, so the contents read as inset in their bar rather than as
     pushed to one side of it — a left pad derived from the prose column instead
     would run to three figures at a wide viewport and agree with an edge no
     reader can see.
     The bottom carries the triad's height on top of that number, so the air
     between the contents and the triad matches the air above them: the triad is
     a band the bar ends WITH, not padding its contents can sit in. */
  padding: var(--sidenav-top) var(--sidenav-top)
           calc(var(--sidenav-top) + var(--topbar-accent-h));
}

/* The bar's bottom edge, and the column's partner across the gutter. Absolute
   rather than a flex child so it spans the bar's full width, ignoring the
   padding that insets the contents. */
.topbar .navbar-accent {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--topbar-accent-h);
}

/* WHAT THE SHELF TELLS ITS OCCUPANT. A searchbar defaults both of these and
   works in any host; in a bar it needs the bar's own numbers, or it sizes itself
   to a guess and drops its results panel across the bar's underline instead of
   below it. Stated here, because these are facts about the shelf. */
.topbar .searchbar {
  --searchbar-h: var(--topbar-field-h);
  --searchbar-drop: calc(var(--topbar-h) - var(--sidenav-top) + 8px);

  /* THE FIELD STARTS ON THE GREEN. Its left edge — the left edge of the mark,
     which is the first thing in it — lands one topbar padding into the last
     third of the triad below, so the bar's own inset is what separates them and
     the shelf reads as measured against the band it closes on.
     Derived rather than dialled in. The accent is three `flex: 1` spans, so
     green begins at exactly two thirds of the bar's WIDTH; a flex item's left
     edge is the padding plus its own margin, so that margin must be (2/3)W. A
     percentage margin resolves against the CONTENT box, which is W - 2P, and
     (2/3)(W - 2P) + (4/3)P is identically (2/3)W — hence the second term. Both
     numbers come from --sidenav-top, so the bar cannot be re-padded into
     disagreeing with its own accent. */
  margin-left: calc(200% / 3 + var(--sidenav-top) * 4 / 3);
}

/* A navmenu on the shelf sits at the bar's left inset, and is taken OUT OF FLOW
   to get there.
   That is the load-bearing part. A flex margin measures from where the previous
   item ended, so the search field's own margin — which pins its left edge to the
   accent's last third — would start counting from the end of this row instead of
   from the bar, and the alignment would move every time a menu label changed.
   Absolute keeps the two independent: this one is placed from the left edge, the
   field from the accent, and neither is a function of the other.
   The row spans the bar's content height, so its links sit on the same line as
   the field and the switch. */
.topbar .navmenu {
  position: absolute;
  left: var(--sidenav-top);
  top: var(--sidenav-top);
  height: var(--topbar-field-h);
  /* Where the bar's bottom edge is, from the top of a trigger: the air under the
     content, plus the triad the bar ends with, plus the gap the searchbar's own
     panel leaves. Summed from the shelf's numbers rather than written as the
     24px it resolves to. */
  --navmenu-drop: calc(100% + var(--sidenav-top) + var(--topbar-accent-h) + 8px);
}

/* A latchbox on the shelf stands to the bar's own field height, so a switch and
   the search field close on the same line.
   `margin-left: auto` keeps it against the bar's right inset even when the field
   beside it stops growing at its own 520px cap. Order matters and is the spec's:
   flexible lengths resolve first, so the field grows, and only what is left over
   goes to this margin. That is what makes the two ends independent — the field's
   left edge is pinned to the accent, this one's right edge to the bar's padding,
   and neither drags the other. */
.topbar .latchbox {
  --latchbox-h: var(--topbar-field-h);
  margin-left: auto;
  flex: none;
}

/* ---- Narrow ----------------------------------------------------------------
 * Nothing sits beside the bar any more — a column this wide is most of a phone,
 * so the host puts it back in flow — and the bar spans the width. The vertical
 * padding is the desktop bar's, so its contents keep their height: with no
 * padding a square occupant stretches to the whole bar and becomes a block as
 * tall as the field beside it is long. Only the side padding changes, to a
 * thumb's margin. */
@media (max-width: 900px) {
  .topbar {
    left: 0;
    padding: var(--sidenav-top) 16px
             calc(var(--sidenav-top) + var(--topbar-accent-h));
  }
  /* The field goes back to the left and takes the bar. Starting it on the green
     spends two thirds of the width on empty shelf, which is a fair trade for
     alignment on a desktop and leaves a phone with a search box too small to
     type a word into. The alignment is the thing that yields, because it is the
     thing nobody can see once the bar is 390px wide. */
  .topbar .searchbar { margin-left: 0; }
}

} /* @layer component */
