/* The app shell, layered on css/style.css the way home.css is layered for the homepage.
 *
 * It adds the furniture the analyzer got when it became a port of the iPhone app: the menu
 * button, the four tabs (a bar at the foot on a phone, a rail down the side on a desk), the
 * pages, the ways-in card and the session rows. It reads style.css's own semantic tokens
 * and defines none of its own colours, so the light theme at the foot of that file carries
 * this one with it.
 *
 * Nothing here is a figure. The two session figures, the trend charts and the share card
 * are drawn in the presentation tokens and are untouched by this file.
 */

/* ------------------------------------------------------------------- one banner */

/* At most one banner at a time. The page can raise three — a new version, Chrome's
   install offer, and js/install.js's iOS home-screen hint — and nothing stopped two of
   them stacking over the topbar. They sit in priority order in the document, so the
   first visible one wins and every later one stands down until it is the only one left. */
.update-banner:not([hidden]) ~ .update-banner:not([hidden]) { display: none; }

/* ----------------------------------------------------------------- the menu button */

.menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
  color: var(--ink-2);
  font: inherit;
  cursor: pointer;
}

.menu-btn:hover { color: var(--ink); }

/* Three rules, drawn rather than typed: a glyph in a font is a character that may not be
   there, and `line.3.horizontal` is the phone's own mark for this button. */
.menu-glyph {
  width: 16px;
  height: 11px;
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  position: relative;
}

.menu-glyph::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  margin-top: -1px;
  border-top: 2px solid currentColor;
}

/* ------------------------------------------------------------------- the app menu
 *
 * Jan, 19 September 2026, on a screenshot of this sheet open on a phone: *"Unclear this is
 * drop down."* It was a `<dialog>` with a bare list in it — no padding, rows in body type,
 * the build line loose between the last row and Close — so it read as the browser's own
 * action sheet rather than as the app's menu. It is the phone's menu now: a row is an icon
 * and a word, the one divider falls where reading ends and operating begins, and the build
 * line is a footer under a hairline. The rows themselves are untouched, and
 * web/tools/verify_app_shell.py holds them to docs/copy/app-shell.json.
 */

.app-menu { max-width: 21rem; }

/* The SHEET takes the focus when it opens, not its first row: `showModal()` focuses the
   first focusable child otherwise, and a menu that opens with a ring around row one reads
   as a form. A container is not a control, so it wears no ring of its own. */
.menu-sheet { gap: 0; padding: 12px; }

.menu-sheet:focus,
.menu-sheet:focus-visible { outline: none; }

.menu-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-rows button {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--tap);
  padding: 10px 10px;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--ink);
  font: 500 15px/1.2 var(--sans);
  text-align: left;
  cursor: pointer;
}

.menu-rows button:hover { background: var(--surface-2); }

/* Drawn, not typed: the phone's own symbols (`AppMenuRow.symbolName` — hand.wave, book,
   gearshape, questionmark.circle, envelope) as line icons, in the row's quiet ink so the
   word stays the thing being read. */
.menu-icon {
  flex: 0 0 auto;
  width: 21px;
  height: 21px;
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.menu-rows button:hover .menu-icon { stroke: var(--ink-2); }

/* One divider, and it falls where reading ends and operating begins — the phone's own
   `opensAfterDivider`, which is true for Settings and nothing else. */
.menu-rows .after-divider {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line-soft);
}

.menu-build {
  margin: 10px 0 0;
  padding: 10px 10px 0;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-3);
  font: 11.5px/1.4 var(--mono);
}

.app-menu .ask-actions { margin-top: 8px; }

/* -------------------------------------------------------------------- the four tabs
 *
 * Jan, 19 September 2026, on a phone screenshot: *"Navigation / tabs don't look nice."*
 * Four grey words, the chosen one inside a blue box the bar clipped, and a white band
 * under the row the height of the bar again. It is an iOS tab bar now:
 *
 *   a glyph over an 11 px label     the phone's own symbols (water.waves, trophy,
 *                                   chart.xyaxis.line, bag), drawn as line icons;
 *   colour marks the chosen tab     ink and the brand's own stroke, no box and no outline,
 *                                   so nothing can be clipped by the bar's edge;
 *   the inset is paid once          the BAR carries env(safe-area-inset-bottom) and the
 *                                   buttons carry none, so the bar is its content plus the
 *                                   home-indicator strip and nothing else.
 */

.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  background: var(--surface-1);
  border-top: 1px solid var(--line);
  /* The one place the inset is paid. A button that pays it too is the white band. */
  padding: 0 0 env(safe-area-inset-bottom);
}

.tabbar button {
  flex: 1 1 0;
  min-width: 0;
  /* `min-height: var(--tap)` from the phone block in style.css would add 44 px to a box
     that is already taller than a thumb. The content is the height. */
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 7px 4px 8px;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--ink-3);
  font: 500 11px/1.15 var(--sans);
  cursor: pointer;
}

.tab-glyph {
  position: relative;
  display: block;
  width: 24px;
  height: 24px;
}

.tab-glyph svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tab-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Colour, and nothing that can be cut off by an edge. */
.tabbar button[aria-current="page"] { color: var(--series-1); }

.tabbar button[aria-current="page"] .tab-label { font-weight: 600; }

/* The count rides the glyph, the way a badge does on a phone. */
.tabbar .count {
  position: absolute;
  top: -3px;
  left: 62%;
  min-width: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--series-1);
  color: #fff;
  font: 600 10px/16px var(--sans);
  text-align: center;
}

/* The bar covers the foot of the document, so the document ends above it. */
main { padding-bottom: calc(var(--tap) + 34px + env(safe-area-inset-bottom)); }

/* A rail down the side once there is width for one, which is what the phone's tab bar
   becomes on an iPad. The page moves over by the rail's width and the footer with it. */
@media (min-width: 860px) {
  .tabbar {
    top: 0;
    right: auto;
    bottom: 0;
    width: 190px;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    border-top: 0;
    border-right: 1px solid var(--line);
    /* Top-aligned, under the topbar, the way an iPad sidebar sits. Centred down a
       full-height column read as a leftover sidebar rather than as the phone's tab bar. */
    padding: calc(var(--topbar-h, 69px) + 12px) 12px 12px;
  }

  .tabbar button {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    border-radius: var(--radius);
    text-align: left;
    padding: 10px 12px;
    font-size: 0.95rem;
  }

  .tabbar button[aria-current="page"] {
    background: var(--surface-2);
    color: var(--ink);
  }

  .tabbar button[aria-current="page"] .tab-glyph { color: var(--series-1); }

  .tab-glyph { width: 20px; height: 20px; }

  body > header,
  body > main,
  body > footer { margin-left: 190px; }

  main { padding-bottom: 24px; }
}

/* ------------------------------------------------------------------ the app header
 *
 * One bar, the way the phone has one toolbar (docs/web-design-review.md, 3 and 15). The
 * name is a wordmark rather than the page's title: the title is the tab root's, one screen
 * down, and it is the page's <h1>.
 */

/* The bar reads left to right: the menu, then the mark and the name, then whatever the
   engine has to say. `space-between` left the wordmark floating in the middle of a wide
   window, which is a place a brand sits only on a marketing page. */
.app-topbar { justify-content: flex-start; }

.app-topbar .topbar-right { margin-inline-start: auto; display: flex; align-items: center; gap: 10px; }

.brand-name {
  font: 650 18px/1.2 var(--sans);
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--ink);
}

/* ------------------------------------------------------------------------- pages */

/* ONE TYPE SCALE FOR THREE JOBS, split into two (docs/web-design-review.md, finding 10).
   `h2` is the section eyebrow — 15 px, uppercase, letterspaced — and every panel on a
   session keeps it. A tab root's own name is not a section label: it is the top of the
   page, so it is the page's <h1> at the size the phone gives a large title, in sentence
   case, with nothing above it but the mark. */
.page-title {
  font-size: 21px;
  font-weight: 650;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
}

.crumb { margin: 0 0 8px; }

.help-section + .help-section { margin-top: 20px; }

.help-topic { margin: 12px 0 0; }

.help-topic h4 { margin: 0 0 2px; }

.release + .release {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}

.release h3 { margin: 0 0 2px; }

.release ul { margin: 8px 0 0; padding-left: 1.1em; }

/* ------------------------------------------------------------------- the ways in */

.ways-title { margin: 0 0 12px; font-size: 1rem; }

.ways-in {
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}

.way {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 0;
  border-top: 1px solid var(--line-soft);
}

.way:first-child { border-top: 0; }

.way .drop-icon { flex: 0 0 auto; width: 32px; height: 32px; }

.way-body { flex: 1 1 auto; min-width: 0; }

.way-title { margin: 0; font-weight: 600; }

.way-line,
.way-act { margin: 2px 0 0; color: var(--ink-3); font-size: 0.9rem; }

/* A door a browser cannot open is shown, not hidden: its own line says why (pattern G).
   Recessive, because the three doors above it are the ones to take here. */
.way.elsewhere .way-title { font-weight: 500; }

.way.elsewhere { opacity: 0.78; }

/* With sessions in the library the card is a drop target again and nothing else: the list
   below it is the answer to "how do they get in", and the reader has already had it. */
.dropzone.compact .ways-title,
.dropzone.compact .way:not([data-way="drop"]),
.dropzone.compact .drop-peek,
.dropzone.compact .drop-what { display: none; }

/* --------------------------------------------------------------- the session rows */

.lib-list { list-style: none; margin: 0; padding: 0; }

.lib-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 0;
  border-top: 1px solid var(--line-soft);
}

.lib-row:first-child { border-top: 0; }

/* The whole row opens the session, which is what a row does on the phone and what these
   rows never did — the four buttons beside it stay buttons of their own. */
.lib-open {
  flex: 1 1 18rem;
  display: block;
  min-width: 0;
  padding: 4px 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.lib-open > span { display: block; }

.row-title { font-weight: 600; }

.row-when { color: var(--ink-3); font-size: 0.92rem; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }

.row-note { color: var(--ink-3); font-size: 0.8rem; }

/* THREE CELLS THAT CANNOT TOUCH (Jan, 19 September 2026: *"68 %10  13.47 kn"* over
   *"foil   jibesbest 2 s"* on a 400 px screen — a value against its neighbour's word).
   The row was a flex box with a gap, and `.lib-open > span { display: block }` one rule
   above it is more specific, so the box was never flex and the gap never applied. It is a
   grid of three equal columns now, qualified by the row so it cannot lose again, with the
   gutter between the cells rather than between the words. Three cells, as `RowMetric`'s
   `defaultTriple` gives the phone. */
.lib-row .row-metrics {
  margin-top: 6px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px 12px;
  max-width: 24rem;
}

/* A number over its word, which is what makes the row readable without decoding a glyph
   (pattern H). The word is `RowMetric.label`'s, character for character. */
.rm { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }

.rm b,
.rm i { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.rm b { font-variant-numeric: tabular-nums; }

.rm i { color: var(--ink-3); font-size: 0.75rem; font-style: normal; }

.row-foot {
  margin-top: 6px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 0.82rem;
}

.row-km { color: var(--ink-3); font-variant-numeric: tabular-nums; }

.lib-row-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* The outcome tally, in the ladder's own inks, each number carrying its word. It wraps
   rather than overflows: "12 flew · 3 touchdowns · 5 fell in" is wider than the old
   "touch" and "fell", and a half-width tile on a phone may not hold it (pattern N). */
.tally { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 0 4px; }

.tally > span { display: inline-flex; align-items: baseline; gap: 3px; }

.tally i { font-style: normal; font-size: 0.75rem; }

.tally b { color: var(--ink-3); font-weight: 400; }
/* A pair cell's word rides in its number's ink, one weight lighter and smaller. */
.tally small { font-size: 0.6em; font-weight: 500; }

.tally .flew { color: var(--good-text, var(--good)); }

.tally .touchdown { color: var(--warn-text, var(--warn)); }

.tally .fell { color: var(--bad-text, var(--bad)); }
/* The clean jibes: the star and the number in the clean ink, never the ladder's green. */
.tally .clean { color: var(--clean-text, var(--wf-clean-jibe)); }
/* A glide-out: its own neutral ring, the map's hollow mark — never the flew check. */
.pill.glide_out { color: var(--ink-2); }
.tally .glide { color: var(--ink-2); }
.tally .star::before { content: "★"; margin-right: 2px; }
.tally .ring::before { content: "○"; margin-right: 2px; }
.tile .b { font: 600 15px/1.3 var(--sans); font-variant-numeric: tabular-nums; }

/* The example-only Records and Trends: the line's two doors, side by side, wrapping on a
   phone (js/trends.js, rider review I1). */
.doors { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* The file door is a <label class="btn">, and style.css sizes only button.small-btn: the
   label gets the same small size, so the two doors stand at one height. */
.doors .btn.small-btn { font-size: 12px; padding: 5px 9px; }

/* -------------------------------------------------------------- gear, spots, welcome */

.spot-list,
.gear-list { list-style: none; margin: 8px 0 0; padding: 0; }

.spot-list li,
.gear-list li {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
  padding: 8px 0;
  border-top: 1px solid var(--line-soft);
}

.spot-list li:first-child,
.gear-list li:first-child { border-top: 0; }

.spot-name { font-weight: 600; }

.gear-list label { display: flex; flex: 1 1 100%; gap: 10px; align-items: baseline; }

.gear-list input { flex: 1 1 10rem; min-width: 0; }

.welcome { max-width: 34rem; }

.welcome-headline { margin: 0 0 6px; font-size: 1.15rem; font-weight: 600; }

.welcome-promise { margin: 0 0 12px; color: var(--ink-2); }

.guide-routes { list-style: none; margin: 8px 0 0; padding: 0; }

.guide-routes li {
  padding: 8px 0;
  border-top: 1px solid var(--line-soft);
}

.guide-routes li:first-child { border-top: 0; }

.guide-routes .way-line { display: block; }

/* r3-w1:begin the ported screens — gear, deleted sessions, backup, the range, watch vs phone */

/* A block with no data behind it is not on the page at all (docs/presentation.md, missing
   is absent). It cannot use `hidden`: js/sections.js owns that attribute on every panel
   the session switcher governs, and would put the block back on the next chip press. */
.is-absent { display: none !important; }

/* A panel with nothing drawn in it yet is not a panel. The quiver renders from IndexedDB,
   which can be slow and, in a locked-down browser, never answers at all; until it does,
   its card is an empty bordered box on the page. Missing is absent here too. */
#gear-quiver-panel:has(#gear-quiver:empty) { display: none; }

/* A labelled field inside a sheet. The same shape `.rider-name` gives the one field the
   rider prompt has, named for the sheets rather than for that one prompt. */
.ask-field {
  display: grid; gap: 5px; font: 600 11px/1 var(--sans);
  text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3);
}

.ask-field input { width: 100%; }

.ask-check { display: flex; gap: 8px; align-items: center; }

/* The gear card on Log, and the quiver on Gear & spots. A row is a label and the name
   beside it; past a phone's width the pair stacks, because the name is the half being
   read. */
.gear-row { display: flex; gap: 10px; align-items: baseline; padding: 6px 0; }

.gear-row > span:first-child { flex: 0 0 5rem; color: var(--ink-3); }

.gear-row select { flex: 1 1 8rem; min-width: 0; }

@media (max-width: 30rem) {
  .gear-row { flex-wrap: wrap; }
  .gear-row > span:first-child { flex-basis: 100%; }
}

.quiver-list { list-style: none; margin: 6px 0 10px; padding: 0; }

.quiver-list li {
  display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid var(--line-soft);
}

.quiver-list li:first-child { border-top: 0; }

.quiver-name { font-weight: 600; }

.quiver-list .dim { flex: 1 1 6rem; }

/* The tombstones, and what a picked backup turns out to hold. Both are lists of rows with
   one action each, so they share the shape the library rows already established. */
.stone-list { list-style: none; margin: 6px 0 10px; padding: 0; }

.stone-list li {
  display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid var(--line-soft);
}

.stone-list li:first-child { border-top: 0; }

.stone-title { font-weight: 600; flex: 1 1 10rem; }

/* The range over the charts: the three spells the phone offers, then the two dates. */
.trend-range { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }

.trend-range .seg-btn[aria-pressed="true"] { font-weight: 600; }

/* A segment is one line high, so its words do not wrap: the narrow spelling takes over
   before they would (docs/web-design-review.md, finding 14). */
.trend-range .seg-btn { white-space: nowrap; }

.seg-narrow { display: none; }

@media (max-width: 30rem) {
  .trend-range .seg-wide { display: none; }
  .trend-range .seg-narrow { display: inline; }
}

/* Four columns of numbers, as on the phone. The table scrolls sideways rather than
   squeezing the metric name to nothing. */
.divergence-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }

.divergence-table th {
  text-align: right; font: 600 11px/1.4 var(--sans); color: var(--ink-3);
  text-transform: lowercase; padding: 4px 6px;
}

.divergence-table th:first-child, .divergence-table td:first-child { text-align: left; }

.divergence-table td { padding: 6px; border-top: 1px solid var(--line-soft); text-align: right; }

.divergence-table td.delta { color: var(--warn, #e0913f); }

/* r3-w1:end */
/* r3-w3:begin — THE TURN PAGE, THE FLIGHT-END PAGE AND THE SPOT CHIP.
   The page is a <dialog> of the site's own `.ask` family, wide rather than narrow because
   the drawing and its three strips are one column of instruments read top to bottom. */

.turn-page { width: min(680px, calc(100vw - 24px)); }

.turn-page .ask-form { max-height: min(92vh, 900px); overflow-y: auto; }

.tp-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
}

.tp-head h2 { margin: 0; }

.tp-head p { margin: 2px 0 0; }

.tp-nav { display: flex; gap: 6px; align-items: center; }

.tp-nav button[disabled] { opacity: 0.4; }

.tp-controls { display: grid; gap: 8px; }

.tp-switch { display: flex; gap: 8px; align-items: center; font-size: 13px; }

/* The drawing and the strips are each a figure at the container's own width, which is what
   keeps the type on them at the size it was tuned at (js/viz.js `figureWidth`). */
.tp-figure { position: relative; }

.tp-strip { margin-top: 6px; }

.tp-canvas { display: block; width: 100%; height: auto; }

/* The reading under the playhead, top left of the drawing. Absent until something is
   scrubbed, so it never competes with the drawing's own marks. */
.tp-callout {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 4px 8px;
  border-radius: 8px;
  background: var(--panel, #22221f);
  color: var(--ink-2);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.tp-numbers {
  margin-top: 12px;
  padding: 12px;
  border-radius: 12px;
  background: var(--line-soft);
}

.tp-speeds { margin: 0; font-variant-numeric: tabular-nums; }

.tp-speeds b { font-size: 19px; font-weight: 600; }

.tp-speeds span { color: var(--ink-3); font-size: 11px; }

.tp-held { margin: 6px 0 10px; font-size: 13px; font-weight: 500; }

.tp-grid {
  display: grid;
  gap: 6px 16px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.tp-cell { display: flex; gap: 6px; align-items: baseline; }

.tp-cell span { color: var(--ink-3); font-size: 11px; }

.tp-cell b { font-weight: 500; font-variant-numeric: tabular-nums; }

.tp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0; }

.tp-chip {
  display: inline-flex;
  gap: 5px;
  align-items: center;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--line-soft);
  color: var(--ink-2);
  font-size: 11px;
}

.tp-chip i { width: 7px; height: 7px; border-radius: 50%; }

.tp-coach { margin: 12px 0 0; color: var(--ink-2); font-size: 13px; }

.tp-footnote { margin-top: 12px; color: var(--ink-3); font-size: 11px; }

.tp-footnote p { margin: 0 0 6px; }

/* A row with a page behind it says so under the pointer. A course change has no page, so
   its row carries no promise of one. */
tbody tr.opens { cursor: pointer; }

tbody tr.opens:hover { background: var(--line-soft); }

/* The spot chip over Records and over Trends. */
.filter-bar:empty { display: none; }

.spot-chip {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 10px;
  color: var(--ink-3);
  font-size: 12px;
}

.spot-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* r3-w3:end */


/* r7-w5:begin — CONCISE OR EXTENSIVE, THE FOLDED HELP, AND THE NEW SETTINGS
   ---------------------------------------------------------------------------
   Jan, 20 September 2026, from his phone: "/app/#/help is way too long",
   "/app/#/settings is way too long, do we need all this?", "parts of /app/#/session are
   too long". The rule the three share is pattern K — a line says what you get, a `?`
   carries the mechanism — so the furniture below is a `?` and a fold, repeated. */

/* The `?` beside an explanation. Small, round, quiet, and the same shape as the glossary
   fold's own `?` one panel up, because they do the same thing. */
.explain-q {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--ink-2);
  font: 600 11px/1 var(--sans);
  vertical-align: -2px;
  cursor: pointer;
}

.explain-q:hover { border-color: var(--ink-3); color: var(--ink-2); }

/* The `?` a help topic is reached by, in the one ink every help door shares: the brand mint
   on dark, a deep green of the same family on paper (the phone's `ReadableInk.link`). */
.explain-q { color: var(--help-link); }
.explain-q:hover { color: var(--help-link); border-color: var(--help-link); }

/* The door that carries words (a Settings lead): the same `?` and the topic's title, on a
   line of its own under the sentence — the phone's `HelpTopicLink`. */
.explain-link {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 6px 0 0;
  padding: 0;
  min-height: 28px;
  border: 0;
  background: none;
  color: var(--help-link);
  font: 600 13px/1.3 var(--sans);
  text-align: left;
  cursor: pointer;
}

.explain-link:hover > span:last-child { text-decoration: underline; }

/* The extensive reading. It sits under the line it belongs to, indented off the line's own
   left edge so a reader can see where the answer to the `?` starts and stops. */
.explain-more {
  margin: 8px 0 0;
  padding-left: 10px;
  border-left: 2px solid var(--line-soft);
}

.explain-more > p { margin: 0 0 6px; }

.explain-more > p:last-child { margin-bottom: 0; }

.explain-summary { color: var(--ink-2); }

/* The switch itself, in Settings and in the menu sheet's footer. */
.detail-switch { margin-top: 12px; }

.detail-switch h2 { margin: 0 0 8px; }

.detail-switch .seg { width: max-content; }

.detail-switch p { margin: 8px 0 0; }

.menu-detail {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
}

.menu-detail-label { color: var(--ink-3); font-size: 12px; }

/* ------------------------------------------------------------------- the Help page */

/* Ten shut folds. The handle is the section's name and its page count, which is the
   contents entry a reference work owes its reader. */
details.help-section { border-top: 1px solid var(--line-soft); }

details.help-section > summary {
  display: flex;
  gap: 10px;
  align-items: baseline;
  justify-content: space-between;
  padding: 12px 0;
  cursor: pointer;
  list-style: none;
}

details.help-section > summary::-webkit-details-marker { display: none; }

.help-section-name { color: var(--ink); font-weight: 600; font-size: 14px; }

details.help-section[open] > summary { border-bottom: 1px solid var(--line-soft); }

.help-topic { padding: 14px 0; border-bottom: 1px solid var(--line-soft); }

.help-topic:last-child { border-bottom: 0; }

.help-topic h4 { margin: 0 0 4px; font-size: 14px; }

/* THE LADDER THE RIGHT WAY UP (finding 11): the summary was set smaller than the body it
   introduced. It is body size, in the stronger ink, over the prose. */
.help-topic .what { margin: 0 0 8px; color: var(--ink-2); font-size: 13.5px; }

.help-topic p { margin: 0 0 8px; }

/* A topic a deep link asked for says so for a beat, because a fold that merely scrolled
   leaves a reader guessing which of ten paragraphs he was sent to. */
.help-topic.found {
  background: var(--line-soft);
  box-shadow: 0 0 0 8px var(--line-soft);
  border-radius: 4px;
}

/* --------------------------------------------------------------------- Settings */

.settings-lead { margin: 0 0 12px; }

.data-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }

.wipe { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line-soft); }

/* The confirmation, on the page rather than in a browser dialog. It is indented and ruled
   so it reads as a question this app is asking, which is the whole reason it is here. */
.wipe-confirm {
  margin-top: 8px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.wipe-confirm > p { margin: 0 0 10px; }

.wipe-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }

/* The turn page's footnote: one line by default, eleven paragraphs when asked. */
.tp-footlead { margin: 0; }
/* r7-w5:end */

/* ------------------------------------------------------- the Turns tab's cards

   A card per turn, over the tally and the list — the iPhone's own order on this tab
   (docs/screens.md, Sessions · Turns). Buttons, because every one of them opens the turn
   page; a card for a course change is disabled and says so on its face rather than
   wearing a pointer that promises a page.

   The grid is auto-fit so the cards read as a strip on a laptop and as a column on a
   phone, with no breakpoint of their own. */
.turn-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
  margin: 0 0 16px;
}

.turn-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-1);
  color: var(--ink);
  font: inherit;
  cursor: default;
}

.turn-card.opens { cursor: pointer; }
.turn-card.opens:hover { background: var(--surface-2); }
.turn-card[disabled] { opacity: 0.6; }

.tc-head { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.tc-name { font-weight: 600; }
.tc-time { color: var(--ink-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.tc-verdict { display: flex; flex-wrap: wrap; gap: 6px; }
.tc-facts { color: var(--ink-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.tc-why { color: var(--ink-2); font-size: 12px; }

/* The star's own pill. It is never on the ladder's three inks: clean is the stricter
   reading of the same turn, not a fourth rung (docs/presentation/clean-jibe.md). */
.pill.clean { color: var(--ink); border-color: var(--line); font-weight: 700; }

/* ------------------------------------------------------- the Turns tab's tally

   The phone's `tallyStrip`: the share, what it is out of, the clean count under it, and
   one chip per rung. Its numbers move with the chips on Track; the caption above the
   table does not, because that one is the document's own reading of the whole afternoon. */
.turn-tally {
  padding: 12px;
  margin: 0 0 16px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--surface-1);
}

.tt-head { display: flex; align-items: baseline; gap: 10px; }
.tt-pct { font: 700 22px/1 var(--sans); font-variant-numeric: tabular-nums; }
.tt-words { display: flex; flex-direction: column; gap: 1px; }
.tt-label { font-weight: 600; font-size: 13px; }
.tt-sub, .tt-clean { color: var(--ink-3); font-size: 12px; }
.tt-empty { margin: 0; color: var(--ink-3); font-size: 13px; }
.tt-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.tt-chip { display: inline-flex; align-items: center; gap: 5px; }
.tt-n { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink-2); }

/* ---------------------------------------------------------------- the Share dialog

   Two segments and a row under them, the phone's own shape
   (ios/WingFoil/Features/Share/ShareComposerView.swift). The row is not a third segment,
   because reporting a number is not a way of sharing an afternoon. */
#share-switch { margin: 12px 0; }
#share-switch > #send-dev-fold { margin-top: 10px; }
#share-fit-pane p { margin: 8px 0; }

/* ------------------------------------------------------- The CleanJibe family

   A section of the welcome: four cards and a link under them. The card for the app the
   reader is in is the one with the ink: it is the only fact here the copy cannot carry,
   because the copy is the same on every shell. */
.family-intro { margin: 0 0 14px; font-weight: 600; }
.family-apps { display: grid; gap: 10px; margin-bottom: 16px; }
.family-app {
  padding: 10px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
}
.family-app.here { border-color: var(--line); background: var(--surface-1); }
.family-app-title { margin: 0 0 3px; display: flex; flex-wrap: wrap; gap: 8px;
                    align-items: baseline; font-weight: 600; font-size: 13.5px; }
.family-app-title .dim { font-weight: 400; font-size: 12px; }
.family-app p.muted { margin: 0; }
.family-app-title .beta-pill { font-size: 11px; font-weight: 700; }
.beta-features { margin: 0 0 12px; padding-left: 18px; }
.beta-features li { margin: 0 0 6px; }
