/* GENERATED from design/bottomBar/1..5-*.css and design/frost.css by design/syncDesign.mjs --write. Do not edit here: edit design/ and run --write. */
/* ======== BOTTOM BAR, PART 1 OF 6: design/bottomBar/structure.css ======== */
/* THE BOTTOM BAR, PART 1 OF 6: STRUCTURE. What the bar IS, whatever the screen: its parts, the glass pill, the tabs, the moving indicator, the subpage name and the states between them.
   Nothing in this file depends on the width of the screen, and nothing here places an icon (that is icons.css) or sizes the bar's layout (3 and 4 do).
   THE SIX FILES, in the order they are joined into each app's generated bottomNav.css (read design/bottomBar/README.md first):
     structure.css   the parts and their look (this file)          icons.css     every icon: its size, and where it stands on a phone and on a desktop
     phone.css       the layout under 700px, and under 360px       options.css   the opt-in variants: one page, no button
     desktop.css     the layout from 700px up                      6  THE FROST      the bottom blur: ../frost.css (one recipe for the bar and the desktop top pane)
   Edit a file here, run `node design/syncDesign.mjs --write`, deploy each app. An app loads its generated copy (app/bottomNav.css), never edits it, and may not write a rule for these
   selectors in its own stylesheet (the design check fails if it does). Spec and rationale: design/bottomNavBar.md. Behaviour: design/bottomBar/bottomNav.mjs. Colour, radius and the bar's
   height are the tokens in design/tokens.css.

   THE PARTS, outside in:
     .nav-row        the bar: fixed to the real bottom edge, a child of <body>, never of the app column
       .pill-nav-slot
         .pill-nav     THE PILL: the glass track. It never goes, in any state.
           .pill-tabs    the tabs: labels and the moving indicator. THEY are what fade out inside a subpage.
             .pill-indicator   the selected pill
             button            a tab
           .nav-title    the subpage's name, centred inside the pill, hidden at rest
       .nav-button     the one button at the right: opens a subpage, becomes a close button inside it

   GEOMETRY THAT HAS BITTEN BEFORE (so it is written down)
     - The pill is 48px high with 3px padding, so the tabs' scroller is 42px high and the indicator is 42px high at top:0 of THAT
       scroller. The indicator is positioned against .pill-tabs, not against the pill: an indicator at top:3px (right when it
       sat directly in the padded pill) sits 3px low once the tabs live in their own scroller (Muscle).
     - Tabs are 42px high, `gap:2px` apart, and never squeeze or abbreviate: the scroller scrolls instead.
     - The indicator sits under the labels (z-index 0 against their 1); it is a lighter capsule of the same glass, so the selected label stays --ink (nothing inverts). */

/* Hidden until login.js knows whether this visitor has a session (and by the `hidden` attribute: DadWad hides the bar when it has fewer than two tabs). */
html.authPending .nav-row, .nav-row[hidden] { display: none; }

.nav-row {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;                         /* the bar draws its frost with .bar-frost (../frost.css): no gradient, no blur of its own */
}
.pill-nav-slot { position: relative; min-width: 0; }

/* THE PILL'S SIZE. 48px high, the tabs 42px inside 3px of padding (the size it has always had), so the 64px band holds it with 8px above and below. */
:root { --pill-h: 48px; --tab-h: 42px; }

/* The pill: Apple's floating glass capsule. A light wash and a moderate blur over the page itself (the frost is cut away under it, see below) and a soft float shadow.
   THE EDGE: the quarter-pixel specular rim (owner, bright at the top left and bottom right) and, since LIQUID GLASS (design/liquidGlass.md): inset specular highlights, a glow just inside the rim and a diagonal
   sheen, all from the --lg-* tokens. Nothing solid: the track token is not used here. */
.pill-nav {
  position: relative;
  display: flex;
  align-items: center;
  height: var(--pill-h);
  padding: 3px;
  border-radius: 99px;
  background: var(--lg-fill);          /* LIQUID GLASS (design/liquidGlass.md): the lens, drawn: sheen, a bright specular edge, a glow inside the rim */
  -webkit-backdrop-filter: var(--lg-filter);
  backdrop-filter: var(--lg-filter);
  box-shadow: var(--lg-edge);
  font-family: var(--font-ui, system-ui, sans-serif);          /* Kanit, the one typeface: the bar and the top row's page pill read the shared token, never a system font */
}
@media (prefers-reduced-transparency: reduce) { .pill-nav { background: var(--surface-2); -webkit-backdrop-filter: none; backdrop-filter: none; } }          /* a person who asked for less transparency gets a solid pill (not yet honoured by Safari; free where it is) */
.top-cap::before, .pill-nav::before {   /* the rim is shared with the top bar's caps (design/topBar/topBar.css) */
  content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; padding: .25px; pointer-events: none;
  background: var(--glass-rim);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
}
/* The frost is drawn everywhere in the band EXCEPT under the pill. */
.nav-row .bar-frost > i, .nav-row .bar-frost::after { clip-path: var(--bar-hole, none); }
/* CHROME (the `engine-blink` class, bottomNav.mjs ENGINE): a blur layer with a clip-path loses its fade there (a hard-edged band instead of a soft one), so in Chrome the hole is a MASK layer instead:
   [the bleed's solid][the layer's fade, minus][the pill's stadium]. Same hole, same fade, nothing clipped. The tint (a plain background) keeps its clip-path, which Chrome handles. */
.engine-blink .nav-row .bar-frost > i {
  clip-path: none;
  mask-repeat: no-repeat; mask-size: 100% var(--frost-bleed), 100% calc(100% - var(--frost-bleed)), var(--bar-hole-size, 0 0); mask-position: var(--frost-solid-pos), var(--frost-grad-pos), var(--bar-hole-pos, 0 0);
  mask-image: linear-gradient(#000, #000), var(--frost-fade), var(--bar-hole-img, linear-gradient(transparent, transparent)); mask-composite: add, subtract, add;
  -webkit-mask-repeat: no-repeat; -webkit-mask-size: 100% var(--frost-bleed), 100% calc(100% - var(--frost-bleed)), var(--bar-hole-size, 0 0); -webkit-mask-position: var(--frost-solid-pos), var(--frost-grad-pos), var(--bar-hole-pos, 0 0);
  -webkit-mask-image: linear-gradient(#000, #000), var(--frost-fade), var(--bar-hole-img, linear-gradient(transparent, transparent)); -webkit-mask-composite: source-over, source-out, source-over;
}
/* ANDROID (`os-android`): the web page ends at the bar's bottom edge and the system's own navigation area sits below it, drawn in the page colour. The frost over the cards is lighter than that, so a seam
   showed ("a solid black strip"). A page cannot draw into that area, so the frost settles to the page colour at its bottom edge, fading out upward; not under the pill (the same hole). */
.os-android .nav-row .bar-frost::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: var(--frost-bleed); height: 30px; pointer-events: none;
  background: linear-gradient(to top, rgb(var(--bg-rgb)) 0, rgba(var(--bg-rgb), .9) 8px, rgba(var(--bg-rgb), 0) 100%); clip-path: var(--bar-hole, none);
}

/* The tabs: a real horizontal track, not equal compartments. Full labels, never abbreviated; overflow is the cue that it scrolls. (A tab's side padding is the layout's: phone.css, desktop.css.) */
.pill-tabs {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 6px;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  transition: opacity .3s ease;
}
.pill-tabs::-webkit-scrollbar { display: none; }
.pill-tabs button {
  position: relative;
  z-index: 1;
  flex: 1 0 auto;
  min-width: max-content;
  height: var(--tab-h);
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(var(--ink-rgb), .74);
  font: inherit;
  font-size: 14px;
  font-weight: 300;                         /* Kanit Light, the lightest weight that still reads at 14px (Thin and Ultralight break up on a phone); owner, chosen over Medium */
  letter-spacing: .03em;                    /* open tracking suits the Light weight */
  white-space: nowrap;
  scroll-snap-align: center;
  transition: color .3s ease, opacity .3s ease;
}
.pill-tabs button.active { color: var(--ink); }
.pill-indicator {
  position: absolute;
  top: 0; left: 0;
  height: var(--tab-h);
  z-index: 0;
  border-radius: 999px;
  /* The selected pill is a lighter capsule of the same glass with a small lift (iOS 26), no edge. The label on it is --ink at full strength; the others are dimmer. */
  background: var(--lg-lens-fill);          /* the selected tab is a drop of the same glass (liquid glass, design/liquidGlass.md): lighter, with its own specular edge and a small lift */
  box-shadow: var(--lg-lens-edge);
  transform: translateX(0);
  pointer-events: none;
  transition: transform .4s cubic-bezier(.25, 1, .5, 1), width .4s cubic-bezier(.25, 1, .5, 1), opacity .3s ease;
}
.pill-indicator.settling { transition: none; }

/* Inside a subpage the pill STAYS. Its tab labels fade out and stop taking taps (opacity AND pointer-events, never opacity alone), the HIGHLIGHT widens to fill the whole pill as if the entire pill were
   the selected tab (owner; bottomNav.mjs placeIndicator), and the name fades in on it, centred. Never fade .pill-nav itself (design/bottomNavBar.md rule 7). */
.nav-title {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
  font-weight: 300;
  white-space: nowrap;
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
/* NO BOUNCE IN AN EXPANDED PAGE (owner, after the sideways bounce: "also the top and bottom bouncy nature of these expanded ledgers"): while any destination is open the document's rubber band is off, at the top and the bottom (the sideways one is off in ledgerPage.css). A tab page keeps its normal bounce. */
html:has(.nav-row.in-subpage), html:has(.nav-row.in-subpage) body { overscroll-behavior-y: none; }
.nav-row.in-subpage .pill-tabs { pointer-events: none; overflow: hidden; }
.nav-row.in-subpage .pill-tabs button { opacity: 0; }
.nav-row.title-shown .nav-title { opacity: 1; }
/* A PAGED subpage: the name is the navigator (rule 8), so it takes taps and swipes. It is a target only while it is shown. */
.nav-row.title-shown.title-paged .nav-title { pointer-events: auto; cursor: pointer; touch-action: pan-y; padding: 12px 16px; }

.nav-row button:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.nav-row button:active:not(:disabled) { transform: scale(.97); }

@media (prefers-reduced-motion: reduce) {
  .nav-row *, .nav-row *::before, .nav-row *::after { transition: none !important; }
}

/* ======== BOTTOM BAR, PART 2 OF 6: design/bottomBar/phone.css ======== */
/* THE BOTTOM BAR, PART 2 OF 6: THE PHONE. The layout under 700px (a phone, or a narrow window), and the one extra step under 360px (the narrowest phones).
   Phone is the DEFAULT layout: these rules apply everywhere, and desktop.css overrides them from 700px up. Nothing here is about icons (icons.css).

   On a phone the bar is a centred strip, at most 440px wide: the pill (the glass track, 360px at most, free to shrink) and the button beside it. The side padding is the page gutter
   plus 8px, the top is 8px and the bottom is 8px plus the safe area (the bar pads for the safe area itself: it never relies on a parent's edge). The tabs have 7px each side.
   On a 390px phone the five labels do not all fit, and that is by design: the last tab is cut at the edge and the strip scrolls sideways (the cut edge is the hint). Never squeeze or abbreviate. */
.nav-row {
  max-width: min(440px, 100%);
  margin: 0 auto;
  gap: 12px;
  padding: 8px var(--page-gutter, 16px) calc(8px + env(safe-area-inset-bottom));
}
.pill-nav-slot { flex: 0 1 auto; width: min(360px, 100%); }
.pill-tabs button { padding: 0 7px; }

/* The narrowest phones (360px and under): tighter gap and gutter, roomier tabs at 13px so the labels still read. */
@media (max-width: 360px) {
  .nav-row { gap: 8px; padding-left: var(--page-gutter, 12px); padding-right: var(--page-gutter, 12px); }
  .pill-tabs button { padding: 0 12px; font-size: 13px; }
}

/* THE WINDOW MUST BE THE WHOLE SCREEN, or the bar floats above the bottom edge (owner: Wad's ledger "lifted up at the bottom", a blank strip under the bar). In an installed web app that was added to
   the Home Screen with a black-translucent status bar, iOS gives the page the whole screen ONLY while the document is taller than the short viewport (100svh); a page that is only a fixed overlay (Wad's
   ledger) leaves the document short, the window shrinks by the status bar's height, and everything fixed to the bottom, this bar included, is lifted by it (measured on the owner's iPhone with Snap).
   So the body is at least 100lvh tall, in an installed app only (in a browser tab lvh reaches behind the toolbar and would make a short page scroll). Where the
   status bar is plain `black` lvh equals svh and this changes nothing. The bar itself stays at bottom: 0, never placed by lvh. */
@media (display-mode: standalone) { html body { min-height: 100lvh; } }

/* ======== BOTTOM BAR, PART 3 OF 6: design/bottomBar/desktop.css ======== */
/* THE BOTTOM BAR, PART 3 OF 6: THE DESKTOP. The layout from 700px up (a desktop, a tablet, a wide window). It overrides phone.css and nothing else; icons are icons.css.

   On a desktop the bar goes full width: no max-width, no margin, 16px at each side. The pill is content-sized and CENTRED (the tabs do not stretch, 18px each side), at most 100vw minus
   the side padding minus 60px for the button, which stands at the far right (icons.css). */
@media (min-width: 700px) {
  .nav-row { max-width: none; margin: 0; padding-inline: 16px; }
  .pill-nav-slot { flex: 0 0 auto; width: auto; max-width: calc(100vw - 32px - 60px); }
  .pill-tabs button { flex: 0 0 auto; padding: 0 18px; }
}

/* ======== BOTTOM BAR, PART 4 OF 6: design/bottomBar/icons.css ======== */
/* THE BOTTOM BAR, PART 4 OF 6: ICONS. Every icon in the bar, its size and where it stands, on a phone and on a desktop. This is THE STANDARD for placing an icon in the bar; an app places none itself.

   THE RULE: an icon stands in a BOX the size of the button (48 x 48, 36 x 36 on the narrowest phones), centred in the 64px band (8px from the band's top), and the box sits
     phone         at the right of the pill, in the row (the pill and the box share the row, 12px apart)
     desktop       at the bar's FAR RIGHT edge, 16px from it, absolutely placed (the pill stays centred)
   Every icon that stands there stands in the SAME box at the SAME place, whichever icon it is: the Constitution book (22px) and the close cross (22px). A new icon takes the box and its place; it never gets a place of its own. The glyph is drawn in currentColor, 22px with a 1.3 stroke, no circle, no fill. */
.nav-button {
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
}
.nav-button svg { display: block; width: 22px; height: 22px; }

/* DESKTOP (700px up): the box leaves the row and stands at the far right edge, centred in the band. */
@media (min-width: 700px) {
  .nav-row .nav-button { position: absolute; right: 16px; top: 8px; }
}

/* THE NARROWEST PHONES (360px and under): the box is 36 x 36. */
@media (max-width: 360px) {
  .nav-row .nav-button { width: 36px; height: 36px; }
}

/* ======== BOTTOM BAR, PART 5 OF 6: design/bottomBar/options.css ======== */
/* THE BOTTOM BAR, PART 5 OF 6: THE OPT-IN VARIANTS. Each is off unless the app asks for it through mountBottomNav's config (design/bottomBar/bottomNav.mjs "ONE OPT-IN"), never through the app's own CSS.
   Their icons are icons.css; their width rules are phone.css and desktop.css.

   NO BUTTON, ONE PAGE (bottomNavBar.md rule 16). With no button beside it the pill is on the centre line (.nav-row centres its children); a bar of one page AND no button is only
   as wide as its label (with a button, one page is laid out like any other bar). */
.nav-row.nav-single .pill-nav-slot { width: auto; }
.nav-row.nav-single .pill-tabs button { padding: 0 30px; }

/* ======== BOTTOM BAR, PART 6 OF 6: THE FROST, design/frost.css ======== */
/* THE FROST: the one material at the edge of the screen, in one place (owner: "make this a shared resource, such that if one thing is changed, everything will get changed").
   Every bottom bar draws it (.bar-frost, the bar's first child) and every desktop top pane draws it (.top-blur, the first thing after <body>): the SAME recipe, the SAME dimensions, mirrored.
   - Four stacked blur layers (1, 2.5, 5 and 8px), each masked to a shorter reach than the one before, plus a tint of the theme's background easing out. Strongest at the screen's edge, fading
     inward, with no visible boundary.
   - The dimensions: the band (--bottom-nav-h, 64px) plus --frost-reach (44px). The bottom frost is that tall plus the home-indicator inset (it fills its bar and reaches 44px above it); the
     desktop top pane is exactly that tall, with no inset (a desktop has no status bar to clear).
   - Direction is one variable, --frost-dir: "to top" (the bottom edge) or "to bottom" (the top edge).
   - A PHONE draws no top pane (.top-blur is display:none under 700px): iOS applies its own native frost under the status bar, and drawing another would double it. The bottom bar draws its frost
     everywhere, a phone included.
   Change a number here, run `node design/syncDesign.mjs --write`, deploy each app. Muscle, Snap and Dev get this block appended to their generated bottomNav.css; Wad and DadWad repeat it
   verbatim between the markers below, and the design check fails if a copy differs. Spec: design/bottomNavBar.md rule 9 and design/liquidGlass.md. */
/* FROST:BEGIN */
:root { --frost-reach: 44px; --frost-bleed: 16px; }
.bar-frost, .top-blur { pointer-events: none; }
.bar-frost { --frost-dir: to top; --frost-grad-pos: 0 0; --frost-solid-pos: 0 100%; --frost-tint-inset: 0 0 var(--frost-bleed) 0; position: absolute; left: 0; right: 0; bottom: calc(-1 * var(--frost-bleed)); height: calc(100% + var(--frost-reach) + var(--frost-bleed)); z-index: -1; }
.top-blur { --frost-dir: to bottom; --frost-grad-pos: 0 var(--frost-bleed); --frost-solid-pos: 0 0; --frost-tint-inset: var(--frost-bleed) 0 0 0; display: none; }
@media (min-width: 700px) {
  .top-blur { display: block; position: fixed; z-index: 5; top: calc(-1 * var(--frost-bleed)); left: 0; right: 0; width: 100%; height: calc((var(--bottom-nav-h, 64px) + var(--frost-reach)) * var(--frost-top-scale) + var(--frost-bleed)); }
}
.bar-frost::after, .top-blur::after { content: ""; position: absolute; inset: var(--frost-tint-inset); background: linear-gradient(var(--frost-dir),
  rgba(var(--bg-rgb), .48) 0%, rgba(var(--bg-rgb), .40) 10%, rgba(var(--bg-rgb), .28) 25%,
  rgba(var(--bg-rgb), .16) 45%, rgba(var(--bg-rgb), .06) 70%, rgba(var(--bg-rgb), 0) 100%); }
.bar-frost > i, .top-blur > i { position: absolute; inset: 0; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% calc(100% - var(--frost-bleed)), 100% var(--frost-bleed); mask-size: 100% calc(100% - var(--frost-bleed)), 100% var(--frost-bleed);
  -webkit-mask-position: var(--frost-grad-pos), var(--frost-solid-pos); mask-position: var(--frost-grad-pos), var(--frost-solid-pos); }
.bar-frost > i:nth-child(1), .top-blur > i:nth-child(1) { -webkit-backdrop-filter: blur(1px); backdrop-filter: blur(1px); --frost-fade: linear-gradient(var(--frost-dir), #000 0%, rgba(0,0,0,.85) 10%, rgba(0,0,0,.6) 25%, rgba(0,0,0,.35) 45%, rgba(0,0,0,.12) 70%, transparent 100%);
  -webkit-mask-image: var(--frost-fade), linear-gradient(#000, #000);
  mask-image: var(--frost-fade), linear-gradient(#000, #000); }
.bar-frost > i:nth-child(2), .top-blur > i:nth-child(2) { -webkit-backdrop-filter: blur(2.5px); backdrop-filter: blur(2.5px); --frost-fade: linear-gradient(var(--frost-dir), #000 0%, rgba(0,0,0,.85) 9%, rgba(0,0,0,.6) 22%, rgba(0,0,0,.35) 40%, rgba(0,0,0,.12) 63%, transparent 90%);
  -webkit-mask-image: var(--frost-fade), linear-gradient(#000, #000);
  mask-image: var(--frost-fade), linear-gradient(#000, #000); }
.bar-frost > i:nth-child(3), .top-blur > i:nth-child(3) { -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); --frost-fade: linear-gradient(var(--frost-dir), #000 0%, rgba(0,0,0,.85) 8%, rgba(0,0,0,.6) 20%, rgba(0,0,0,.35) 35%, rgba(0,0,0,.12) 55%, transparent 78%);
  -webkit-mask-image: var(--frost-fade), linear-gradient(#000, #000);
  mask-image: var(--frost-fade), linear-gradient(#000, #000); }
.bar-frost > i:nth-child(4), .top-blur > i:nth-child(4) { -webkit-backdrop-filter: blur(8px) saturate(120%); backdrop-filter: blur(8px) saturate(120%); --frost-fade: linear-gradient(var(--frost-dir), #000 0%, rgba(0,0,0,.85) 6%, rgba(0,0,0,.6) 16%, rgba(0,0,0,.35) 28%, rgba(0,0,0,.12) 43%, transparent 62%);
  -webkit-mask-image: var(--frost-fade), linear-gradient(#000, #000);
  mask-image: var(--frost-fade), linear-gradient(#000, #000); }
/* WHERE THE PAGE STARTS UNDER THE TOP PANE (owner: the avatar, the notification button and the first cards sat inside the blur). On a desktop the content begins at --frost-clear = the
   band's height (64px): by there the pane has faded to its tail (the 8px layer ended at 62% of the pane, the 5px at 78%), so the top row and the first card are drawn crisp and untinted, and
   content that scrolls up still passes under the glass. One value for every app: the app's own top padding and its #content / #main-content-area padding are replaced by it. A phone is untouched
   (iOS draws its own frost there). `body` in each selector outranks the app's own id and class rules whichever file loads last. */
:root { --frost-top-scale: .75; --frost-clear: calc(var(--bottom-nav-h, 64px) * var(--frost-top-scale)); }          /* THE TOP IS 75% OF THE BOTTOM (owner: the desktop top wasted room; the bottom frost height, less 25%, is the rule): the pane is (band + reach) x .75 and the page starts the band x .75 = 48px down */
@media (min-width: 700px) {
  body .app, body .col { padding-top: var(--frost-clear); }
  body #content, body #main-content-area { padding-top: 0; }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .top-blur { display: none; }
}
/* FROST:END */
