/* =========================================== SECTIONS =========================================== */ .section-header { font-size: var(--text-head); font-weight: normal; margin-bottom: var(--gap-section); padding-bottom: var(--gap-peer); border-bottom: 1px solid var(--border); font-family: var(--font-mono); } /* Canonical "page section box", light-background card with padding + bottom space. One of these in the codebase. Aliased to the per-page class names that were just relabels of this same shape. Templates can use the alias name OR add `.content-section` as a co-class. */ /* The canonical panel. Every one of these carries `.raised` in the markup now, so the fill and the bevel come from layout.css and this rule is the spacing only. The background it used to declare was --surface-overlay, which .raised spells --surface-raised; equal on the platform default and a theme may set them apart, the same move .card and .buy-card made. */ .content-section, .import-page .import-form, .import-page .import-progress, .library-page .library-section, .library-page .library-downloads, .library-page .downloads-hero, .receipt-page .receipt-box, .stripe-disclaimer-page .disclaimer-box { padding: var(--gap-page); margin-bottom: var(--gap-page); } /* Variants of the canonical shape that want top-spacing instead of bottom, or a tighter --gap-pane padding. */ .library-page .library-downloads, .receipt-page .receipt-box { margin-bottom: 0; margin-top: var(--gap-pane); } .import-page .import-progress { padding: var(--gap-pane); margin-bottom: var(--gap-section); } .stripe-disclaimer-page .disclaimer-box { margin-bottom: var(--gap-pane); } .form-section { margin-bottom: var(--gap-page); } .section-group-label { font-family: var(--font-mono); font-size: var(--text-fine); font-weight: bold; text-transform: uppercase; letter-spacing: 0.05em; color: var(--content-muted); margin: var(--gap-page) 0 var(--gap-section) 0; padding-top: var(--gap-pane); border-top: 2px solid var(--border); } .form-section h2 { font-size: var(--text-subhead); font-weight: normal; margin-bottom: var(--gap-section); padding-bottom: var(--gap-peer); border-bottom: 1px solid var(--border); } details.form-section > summary { cursor: pointer; list-style: disclosure-closed; } details.form-section[open] > summary { list-style: disclosure-open; margin-bottom: var(--gap-section); } details.form-section > summary > h2 { display: inline; } details.form-section > summary:hover > h2 { color: var(--content); } /* =========================================== NAVIGATION =========================================== */ nav { margin-bottom: var(--gap-page); } .nav-links { display: flex; gap: var(--gap-page); flex-wrap: wrap; } .nav-links a { color: var(--content); text-decoration: none; font-family: var(--font-mono); transition: opacity 0.2s ease; } .nav-links a:hover { opacity: 0.6; } .shortcuts-help-btn { font-family: var(--font-mono); color: var(--content-muted); font-size: var(--text-note); width: 1.5rem; height: 1.5rem; border: 1px solid var(--border); border-radius: var(--radius-control); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: opacity 0.2s ease; padding: 0; background: none; } .shortcuts-help-btn:hover { opacity: 0.6; } .breadcrumb { font-size: var(--text-note); color: var(--content-muted); margin-bottom: var(--gap-peer); font-family: var(--font-mono); } .breadcrumb a { color: var(--content); text-decoration: none; } .breadcrumb a:hover { text-decoration: underline; } /* =========================================== HEADER & FOOTER =========================================== */ header { background: transparent; border-bottom: none; padding: 0; margin-bottom: var(--gap-page); } footer { text-align: center; font-family: var(--font-mono); color: var(--content-muted); } /* Site-wide header. The class names are quasi-webview's, not this stylesheet's: the header is a `quasi_router::Chrome::band` and `crate::shell::site_header` builds the description rather than the markup. A rule here has to match what that renderer emits, and `quasi_webview::vocabulary` is the list of what it may. */ .chrome-band { display: flex; justify-content: space-between; align-items: center; padding: var(--gap-section) var(--gap-pane); margin-bottom: var(--gap-pane); } .chrome-band .chrome-nav { margin: 0; } /* The places are a `ul` of `li`, which is what a nav of addresses is. The markers and the indent go; the row is the layout. */ .chrome-nav ul { display: flex; gap: var(--gap-pane); flex-wrap: wrap; list-style: none; margin: 0; padding: 0; } .chrome-place { color: var(--content); text-decoration: none; font-family: var(--font-mono); cursor: pointer; transition: opacity 0.2s ease; } .chrome-place:hover { opacity: 0.6; } /* The cart place is offered on every signed-in page and drawn only when the cart holds something. How many items that is is not known when the document is rendered, so `core/cart-badge.js` asks `/api/cart/count` and writes the answer onto the place as `data-count`; the presence is that answer, rather than a class the markup ships hidden and a script takes off. The `li` is what hides, not the anchor: an empty item in a flex row still pays its gap. */ .chrome-nav li:has(> [data-place="cart"]) { display: none; } .chrome-nav li:has(> [data-place="cart"][data-count]) { display: block; } .chrome-brand { font-family: var(--font-display); font-size: var(--text-subhead); text-decoration: none; color: var(--content); } .chrome-brand:hover { opacity: 0.8; } /* Header search */ .chrome-search { flex: 0 1 220px; margin: 0 var(--gap-section); } /* The box carries a real `