/* 🔴 ONE source for the topbar's height. It was written as a literal `56px`
   here and then again, by hand, in every rule that had to fill the space
   under it — `#page-practice`, the drawer's own header row, the graph
   canvases. Shortening the bar (Seth, 2026-08-23: "vertically it should be
   more scrunched up") meant finding all of them, which is the whole argument
   for the token. Anything sizing itself against the bar reads this. */
:root {
  --dd-topbar-h: 44px;
}

.topbar {
  /* 🔴 GRID, not flex, and that is the whole trick. `justify-content:
     space-between` over three children centres the middle one only when the
     two outer ones happen to be the same width — they never are, and the tab
     strip drifted with the level pill's digit count. Two `1fr` columns are
     EQUAL by definition, so the `auto` column between them is centred on the
     viewport. Seth, 2026-08-23: "exactly centered". Columns cannot overlap
     either, which `position: absolute` centring would have allowed. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 18px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  height: var(--dd-topbar-h);
  /* 🔴 STICKY IS ALSO WHAT ANCHORS THE NOTCH. A sticky box is a POSITIONED box,
     so it is the containing block for `#practice-notch`, which hangs off this
     bar's bottom edge as an absolutely-positioned tab (Seth, 2026-08-27 —
     styles/practice/notch-menu.css). The notch is a DIRECT child of this
     element for exactly that reason, so nothing in between can re-anchor it;
     dropping `position: sticky` here, though, hands it to the viewport and the
     clock detaches from the bar. */
  position: sticky;
  top: 0;
  z-index: 50;
}

/* The two outer cells. Real elements rather than bare children because a grid
   places CHILDREN into cells, and the left cell holds two controls (the
   hamburger and the level pill).

   🔴 `min-width: auto`, AND IT USED TO BE 0. The 0 was written so "a wide pill
   shrinks its own column instead of stealing width from the centred strip",
   which is not what it did: `min-width: 0` waives a grid item's automatic
   minimum, so these two `1fr` tracks were free to size BELOW their contents
   and the contents simply overflowed them. Nothing shrank, because neither the
   level pill nor the account control can — both are `white-space: nowrap`.

   It went unnoticed while the middle cell was small. The concept pill
   (styles/concept-pill.css) asks for a third of the viewport, and in ADVANCED
   mode — where the ten-button tab strip shares that cell — the auto column
   then took 1269 of 1440px at Seth's own window size: the left track collapsed
   to 62px with the level pill hanging 8px past its edge and under the strip,
   and the account control was pushed flush to the right margin. Measured, not
   inferred.

   `auto` restores the automatic minimum, so each side track is at least as
   wide as what is in it, both stay `1fr` (equal, so the middle is still
   centred on the viewport), and the middle cell gets what is left. The concept
   pill is `flex: 0 1 33vw` precisely so it is the thing that gives way — it
   settles at ~29vw in advanced mode and the full third in basic mode, which is
   the default. */
.topbar-side {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: auto;
}

/* 🔴 EVERY CELL IS PLACED BY NUMBER, and that is not tidiness — it is the fix
   for the bug Seth reported on 2026-08-24 ("put the cog icon in the top right
   rather than the middle").

   The three children used to be placed by AUTO-FLOW: first child to column 1,
   second to column 2, third to column 3. That is correct only while all three
   children are laid out. `.tabs` is `display: none` in basic mode
   (styles/learn-about.css), and a `display: none` grid item is not laid out at
   all — so it took NO cell, the right-hand side flowed into column 2, and the
   account control sat dead centre. Measured on the live app at 1440px: its box
   was x=700..730, with the viewport's midpoint at 720.

   Explicit `grid-column` is immune to that. The middle cell collapses to zero
   width when nothing in it is displayed, the two `1fr` columns stay equal, and
   the right cell is the right cell either way. */
.topbar-side--left {
  grid-column: 1;
}

/* THE MIDDLE CELL. It holds the tab strip (advanced mode only) and the concept
   pill (styles/concept-pill.css), centred as one group.

   🔴 THE CLOCK IS NOT ONE OF THEM ANY MORE. `#practice-notch` was in flow
   beside the strip between 2026-08-24 and 2026-08-27; it is a notch hanging
   under the bar now, positioned against `.topbar`, whose direct child it is.
   Nothing of it is in this cell, so this cell centres what is left. The
   comment that used to say the clock lived here is why this one exists.

   In basic mode the strip is hidden and the concept pill is alone in the
   middle; in advanced mode they share the cell with a 14px gap. */
.topbar-mid {
  align-items: center;
  display: flex;
  gap: 14px;
  grid-column: 2;
  justify-content: center;
  min-width: 0;
}

.topbar-side--right {
  grid-column: 3;
  justify-content: flex-end;
  /* The anchor for #account-menu, which hangs under the control at the right
     edge of this cell. Nothing else in here is positioned. */
  position: relative;
}

/* `.topbar-cog` USED TO BE HERE — a 30px square with a gear in it, and the only
   control on the right edge. It was replaced on 2026-08-24 by a labelled
   account control with a caret and a drop-down menu; the rules live in
   styles/account-menu.css, which is loaded after this file. Deleted rather than
   left behind: a stylesheet full of selectors that match nothing is how the
   next person reading this concludes the cog is still somewhere. */

/* `.logo` is GONE (2026-08-23). It was the brand line, then an empty flex
   spacer that survived it; the grid's own columns do that job now, and an
   empty element in the middle cell would have displaced the tab strip. */
.tabs {
  display: flex;
  gap: 0;
  height: 100%;
  /* No `margin-*: auto`. Both edges used to be tried — held left against the
     brand, then right against nothing — and neither is centring: the strip's
     position moved with whatever sat beside it. The grid's middle column is
     the position now, and the strip fills it. */
  /* Ten tabs at 13px still outrun a ~1100px viewport before nav-drawer.js
     takes over at 900px, so the strip scrolls rather than wrapping the bar
     to two lines. */
  /* The row is `align-items: center`, so the strip has to opt back into the
     bar's full height — the active `border-bottom` sits on the bar's bottom
     edge, not floating mid-row. */
  align-self: stretch;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar {
  display: none;
}

.tab {
  background: none;
  border: none;
  /* Never wrap or shrink. .tabs scrolls horizontally on narrow screens, so a
     tab that breaks mid-label just makes the topbar four lines tall instead
     — which is what "Why This App Exists" did at 390px. */
  flex: 0 0 auto;
  white-space: nowrap;
  /* 🔴 BACK TO THE ORIGINAL SIZE. Shortening the bar to 44px took the labels
     down with it — 13px/13px — and Seth read the result as small (2026-08-23:
     "the text looks really small for the tabs ... the exact size it was
     before, but a bit more like the style"). So the METRICS are the pre-44px
     ones (14px type, 20px a side) and only the STYLE is new: symmetric
     padding, nothing but the label inside the button, the underline square
     under it.

     The "ten tabs would be 400px of padding" worry that justified 13px was
     counting tabs that are not there. Basic mode shows five — Why This App
     Exists, How to use it, Placement test, Account, Practice — because
     Knowledge Graph, Course content and Notebooks are advanced-only and
     Split Tool and Targeted Practice are `hidden`. Five at these metrics is
     ~640px, comfortably inside the grid's middle column before nav-drawer.js
     takes the strip out of the bar at 900px.

     The padding is SYMMETRIC and there is nothing else inside the button,
     which is what makes the active underline sit square under the label: it
     used to span the label while a sibling ⓘ hung off the right, so the line
     read as offset to the left (Seth, 2026-08-23). */
  padding: 0 20px;
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  height: 100%;
  display: flex;
  align-items: center;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}

.tab[hidden] {
  display: none !important;
}

.tab:hover {
  color: var(--text);
}

.tab.active {
  color: var(--white);
  border-bottom-color: var(--accent-text);
}

/* 🔴 A LOCKED TAB MUST LOOK LOCKED. Practice is disabled for as long as a
   placement test is running (practice/diagnostic-page.js `setPracticeLock`),
   because the two share one workspace and one `currentQuestion` — Practice
   mid-test would show the probe.

   There was no `:disabled` rule anywhere in this app the last time a tab was
   disabled, and that is the whole reason that attempt was ripped out: the tab
   rendered exactly like its neighbours and simply ate the click, which reads as
   a broken app rather than a rule. Dimmed, with the pointer cursor gone and
   hover doing nothing, so the refusal is visible before it is tested. The
   `title` carrying the REASON is written by the JS, not here. */
.tab:disabled {
  color: var(--muted-dim);
  cursor: default;
  opacity: 0.55;
}

.tab:disabled:hover {
  color: var(--muted-dim);
}

.page {
  padding: 60px 20px 100px;
}

.container {
  max-width: 720px;
  margin: 0 auto;
}

.page h1 {
  margin: 0 0 12px;
  font-size: 32px;
  font-weight: 700;
  color: var(--white);
}

.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 10px 24px;
  font-size: 12px;
  color: var(--muted);
  display: flex;
  gap: 10px;
  align-items: center;
  background: var(--surface);
  border-top: 1px solid var(--border);
}
