/* Cue2Live site styles
 *
 * Loaded after Bootstrap so these win. Everything here is either a design
 * token or a Bootstrap override — page-specific rules belong in the page, but
 * anything reused belongs here rather than in a <style> block in a template.
 *
 * Bootstrap 5.3 components read their own CSS variables (--bs-btn-bg and
 * friends), so overriding --bs-primary alone does NOT restyle .btn-primary.
 * The component-level variables are set explicitly below.
 */

:root {
    /* Brand. Amber reads as a stage/cue light, holds up on black, and is
       unmistakably not Bootstrap's stock #0d6efd. */
    --c2l-accent: #f5a524;
    --c2l-accent-hover: #ffb944;
    --c2l-accent-active: #d98c12;
    /* Text laid over the accent — dark, because amber is a light colour. */
    --c2l-on-accent: #1a1205;

    /* Surfaces, lightest-on-black progression. */
    --c2l-bg: #000000;
    --c2l-surface: #111214;
    --c2l-surface-raised: #1a1c1f;
    --c2l-border: #2a2d31;

    --c2l-text: #f2f3f5;
    --c2l-text-muted: #9aa0a6;

    --c2l-radius: 10px;

    /* Type. Two families and the system mono — swap the two names below and
       the whole site follows; nothing else references a typeface by name.
       Remember to update the Google Fonts link in base.html to match.

       Archivo is variable (500-700 requested), so headings get a real 600
       rather than a browser-synthesised one. Headings read the weight from
       --c2l-display-weight; if you swap in a single-weight display family,
       drop that token to 400 or every heading will be faux-bolded.

       The face is still reserved for large headings. That is a design choice
       rather than a technical limit: two faces meeting at the same size read
       as an accident rather than a system.

       Alternatives that suit a dark, technical site:
         display: "Chivo", "Archivo", "Sora", "Bricolage Grotesque"
         body:    "IBM Plex Sans", "Manrope", "Public Sans"

       Mono is deliberately not downloaded: this is a macOS product, so the
       system stack lands on SF Mono for essentially every visitor. */
    --c2l-font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
    --c2l-display-weight: 600;
    --c2l-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --c2l-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

/* ---------------------------------------------------------------- base --- */

/* Bootstrap components read these rather than inheriting from body, so both
   have to be set for buttons, form controls, dropdowns and tables to follow. */
:root {
    --bs-body-font-family: var(--c2l-font-body);
    --bs-font-sans-serif: var(--c2l-font-body);
    --bs-font-monospace: var(--c2l-font-mono);
}

body {
    background-color: var(--c2l-bg);
    color: var(--c2l-text);
    font-family: var(--c2l-font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Display face: large headings and the few big numbers that behave like
   headings. h4-h6 are deliberately excluded — they land at body size, where the
   display face has no weight range to distinguish itself from body copy. */
h1, h2, h3,
.hero-title,
.section-title,
.product-title,
.doc-title,
.price-tag,
.product-price,
.cart-summary-total .amount,
.spec-value {
    font-family: var(--c2l-font-display);
    font-weight: var(--c2l-display-weight);
    /* Normal-width grotesque: takes the usual slight negative tracking at
       display size. */
    letter-spacing: -0.02em;
    /* Bootstrap's 1.2 heading leading is loose at display sizes. .hero-title
       tightens further on its own. */
    line-height: 1.15;
    /* Only 500-700 is loaded, so a rule asking for 800 would be synthesised.
       Render the nearest real weight instead. */
    font-synthesis: none;
}

/* A heading sized down with Bootstrap's .h4/.h5/.h6 utilities is functioning as
   a label rather than a display line, and card titles sit at body size — both
   stay on Inter, which has the weight range to carry text that small. */
.h4, .h5, .h6,
.feature-card h3 {
    font-family: var(--c2l-font-body);
    font-weight: 600;
    letter-spacing: normal;
}

/* Small uppercase labels stay on the body face. At ~0.78rem in caps they lean
   on weight to read as labels, and the display family has only 400. */
.section-eyebrow,
.spec-list dt,
.compat-table th,
.cart-table thead th,
.cart-summary-title,
.doc-heading,
.doc-section-heading,
.doc-nav .list-group-item {
    font-family: var(--c2l-font-body);
}

/* Mono, wherever code or a cue name appears. */
code, kbd, pre, samp,
.cue-example {
    font-family: var(--c2l-font-mono);
}

/* Inline code sits inside body copy all over the documentation and product
   pages; unstyled it is Bootstrap pink on black. */
code {
    color: var(--c2l-accent);
    background-color: rgba(245, 165, 36, 0.08);
    padding: 0.1em 0.35em;
    border-radius: 4px;
    font-size: 0.875em;
}


/* Bootstrap's .text-muted resolves against a light background by default and
   nearly disappears on black. */
.text-muted,
.text-body-secondary {
    color: var(--c2l-text-muted) !important;
}

a {
    color: var(--c2l-accent);
    text-decoration: none;
}

a:hover {
    color: var(--c2l-accent-hover);
    text-decoration: underline;
}

/* ------------------------------------------------------------- buttons --- */

.btn {
    --bs-btn-border-radius: var(--c2l-radius);
    font-weight: 500;
}

.btn-primary {
    --bs-btn-bg: var(--c2l-accent);
    --bs-btn-border-color: var(--c2l-accent);
    --bs-btn-color: var(--c2l-on-accent);
    --bs-btn-hover-bg: var(--c2l-accent-hover);
    --bs-btn-hover-border-color: var(--c2l-accent-hover);
    --bs-btn-hover-color: var(--c2l-on-accent);
    --bs-btn-active-bg: var(--c2l-accent-active);
    --bs-btn-active-border-color: var(--c2l-accent-active);
    --bs-btn-active-color: var(--c2l-on-accent);
    --bs-btn-disabled-bg: var(--c2l-accent);
    --bs-btn-disabled-border-color: var(--c2l-accent);
    --bs-btn-disabled-color: var(--c2l-on-accent);
}

/* Secondary action that should not compete with Add to Cart. */
.btn-outline-accent {
    --bs-btn-color: var(--c2l-accent);
    --bs-btn-border-color: var(--c2l-accent);
    --bs-btn-hover-bg: var(--c2l-accent);
    --bs-btn-hover-border-color: var(--c2l-accent);
    --bs-btn-hover-color: var(--c2l-on-accent);
    --bs-btn-active-bg: var(--c2l-accent-active);
    --bs-btn-active-border-color: var(--c2l-accent-active);
    --bs-btn-active-color: var(--c2l-on-accent);
    --bs-btn-border-radius: var(--c2l-radius);
    border: 1px solid var(--c2l-accent);
    font-weight: 500;
}

/* Keyboard focus has to stay visible against black. */
.btn:focus-visible,
a:focus-visible,
.nav-link:focus-visible {
    outline: 2px solid var(--c2l-accent);
    outline-offset: 2px;
    box-shadow: none;
}

/* ----------------------------------------------------------------- nav --- */

/* The home page is now several screens tall, so the nav sticks. The wrapper
   (not the navbar) paints the backdrop, because the navbar is inset inside a
   container and content would otherwise scroll through the gap around it. */
.site-nav-wrap {
    position: sticky;
    top: 0;
    z-index: 1030;
    padding-top: 0.75rem;
    padding-bottom: 0.25rem;
    background-color: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

.navbar.bg-dark {
    background-color: var(--c2l-surface) !important;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
}

.navbar-dark .nav-link {
    color: var(--c2l-text);
}

.navbar-dark .nav-link:hover,
.navbar-dark .nav-link:focus {
    color: var(--c2l-accent);
    text-decoration: none;
}

/* Signed-in state. The navbar used to print the full email address and carry
   separate Account and Logout links, so it reflowed on login and put a
   customer's address on every page. One avatar + dropdown replaces all three;
   the address itself lives on the Account page. */
.account-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: var(--c2l-surface-raised);
    border: 1px solid var(--c2l-border);
    color: var(--c2l-text);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1;
}

.nav-link:hover .account-avatar,
.nav-link[aria-expanded="true"] .account-avatar {
    border-color: var(--c2l-accent);
    color: var(--c2l-accent);
}

/* Bootstrap's dropdown panel is white by default — a bright slab over a black
   page. Set the component variables rather than fighting it with !important. */
.dropdown-menu {
    --bs-dropdown-bg: var(--c2l-surface-raised);
    --bs-dropdown-border-color: var(--c2l-border);
    --bs-dropdown-border-radius: var(--c2l-radius);
    --bs-dropdown-color: var(--c2l-text);
    --bs-dropdown-link-color: var(--c2l-text);
    --bs-dropdown-link-hover-bg: var(--c2l-surface);
    --bs-dropdown-link-hover-color: var(--c2l-accent);
    --bs-dropdown-link-active-bg: var(--c2l-surface);
    --bs-dropdown-link-active-color: var(--c2l-accent);
    --bs-dropdown-divider-bg: var(--c2l-border);
}

/* --------------------------------------------------------------- cards --- */

.card {
    background-color: var(--c2l-surface);
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    color: var(--c2l-text);
}

.card.bg-dark {
    background-color: var(--c2l-surface) !important;
}

.card-subtitle {
    color: var(--c2l-accent) !important;
}

.list-group-item,
.list-group-item-dark {
    background-color: var(--c2l-surface-raised);
    border-color: var(--c2l-border);
    color: var(--c2l-text);
}

/* Stand-in for a product card with no screenshot yet. Matches the aspect the
   real card-img-top images occupy so the card doesn't look truncated next to
   its neighbours. */
.product-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 10;
    background: linear-gradient(160deg, var(--c2l-surface-raised), var(--c2l-surface));
    border-bottom: 1px solid var(--c2l-border);
    border-top-left-radius: var(--c2l-radius);
    border-top-right-radius: var(--c2l-radius);
    color: var(--c2l-accent);
    font-size: 3rem;
}

/* ------------------------------------------------------------ carousel --- */

.carousel-img {
    width: 100%;
    height: auto;
    max-height: 353px;
    object-fit: contain;
    border-radius: var(--c2l-radius);
}

/* The stock control icons are white on white screenshots and vanish. */
.carousel-control-prev-icon,
.carousel-control-next-icon {
    background-color: rgba(0, 0, 0, 0.55);
    border-radius: 50%;
    padding: 1rem;
    background-size: 50% 50%;
}

/* -------------------------------------------------------------- footer --- */

/* Was .bg-light: a white bar under a fully black page. */
.site-footer {
    background-color: var(--c2l-surface);
    border-top: 1px solid var(--c2l-border);
    color: var(--c2l-text-muted);
}

.site-footer a {
    color: var(--c2l-text-muted);
}

.site-footer a:hover {
    color: var(--c2l-accent);
}

/* --------------------------------------------------------------- forms --- */

.form-control,
.form-select {
    background-color: var(--c2l-surface-raised);
    border-color: var(--c2l-border);
    color: var(--c2l-text);
}

.form-control:focus,
.form-select:focus {
    background-color: var(--c2l-surface-raised);
    border-color: var(--c2l-accent);
    color: var(--c2l-text);
    box-shadow: 0 0 0 0.2rem rgba(245, 165, 36, 0.25);
}

.form-control::placeholder {
    color: var(--c2l-text-muted);
}

/* Auth panels (login, signup, create password). These used Bootstrap's .w-50,
   a hard 50% of the viewport at every breakpoint: a two-field login stretched
   across a desktop monitor, and cramped on a phone. Capping the width instead
   lets the panel fill its column on small screens and stop growing on large
   ones. */
.auth-panel {
    max-width: 26rem;
}

/* -------------------------------------------------------- account page --- */

/* Larger form of the navbar avatar, used as the identity header. */
.account-avatar-lg {
    width: 56px;
    height: 56px;
    font-size: 1.4rem;
    flex-shrink: 0;
}

/* Separates the irreversible action from the routine controls above it. */
.account-danger {
    border-top: 1px solid var(--c2l-border);
}

/* Bootstrap's .list-group-flush strips the outer border but keeps its own
   background, which is white here. */
.list-group-flush > .list-group-item {
    background-color: transparent;
    border-color: var(--c2l-border);
}

/* Transient Add to Cart feedback set by flashButton() in cart.js. Both states
   keep the button's footprint so the card doesn't jump while the label swaps. */
.btn-added,
.btn-added:disabled {
    --bs-btn-disabled-bg: #2e7d32;
    --bs-btn-disabled-border-color: #2e7d32;
    --bs-btn-disabled-color: #ffffff;
    --bs-btn-disabled-opacity: 1;
}

.btn-failed,
.btn-failed:disabled {
    --bs-btn-disabled-bg: #b3261e;
    --bs-btn-disabled-border-color: #b3261e;
    --bs-btn-disabled-color: #ffffff;
    --bs-btn-disabled-opacity: 1;
}


/* ----------------------------------------------------------- home page --- */

/* The home page is a long scrolling landing page: full-bleed bands, each one
   answering a single question, rather than one screen of carousel. The rules
   here are shared by those bands; nothing else on the site uses them. */

html {
    scroll-behavior: smooth;
    /* Anchored jumps must clear the sticky navbar. */
    scroll-padding-top: 5.5rem;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* .page-section is the general name; .home-section is the original one, kept
   because home.html still uses it. Same rule either way — drop the alias once
   home.html is switched over. */
.home-section,
.page-section {
    padding: 4.5rem 0;
}

/* Alternating band, so sections read as separate without a hard rule between
   every one of them. */
.home-section-alt,
.page-section-alt {
    background-color: var(--c2l-surface);
    border-top: 1px solid var(--c2l-border);
    border-bottom: 1px solid var(--c2l-border);
}

.section-eyebrow {
    color: var(--c2l-accent);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    margin-bottom: 0.75rem;
}

.section-title {
    font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.5rem);
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    color: var(--c2l-text);
}

.section-lede {
    color: var(--c2l-text-muted);
    font-size: 1.05rem;
    max-width: 44rem;
}

/* ------ hero ------ */

.home-hero {
    position: relative;
    padding: 4rem 0 3.5rem;
    overflow: hidden;
}

/* Stage-light wash behind the headline. Decorative only.
 *
 * The image is generated, not stock — tools/gen_spectrum.py builds it and can
 * be re-run to change the arc, the palette or the grain. A grainy spectral
 * sweep, black across the top and bright at the bottom edge: anchored to the
 * bottom it reads as lights washing up from a stage, and the warm orange/red
 * band through the middle sits with the amber accent rather than fighting it.
 *
 * The scrim is doing real work and is not decoration: nearly opaque over the
 * headline, thinnest where the warm band is, then solid black again at the
 * bottom so the section meets the next one on flat black instead of the
 * image's bright cyan edge. Thin these stops out and the hero copy stops being
 * readable — check the contrast before loosening them.
 *
 * To drop the photo and go back to the plain amber glow, replace the
 * background-image below with the radial-gradient kept in git history.
 */
.home-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(to bottom,
            rgba(0, 0, 0, 0.94) 0%,
            rgba(0, 0, 0, 0.86) 32%,
            rgba(0, 0, 0, 0.72) 62%,
            rgba(0, 0, 0, 0.88) 86%,
            var(--c2l-bg) 100%),
        url("../images/bg_spectrum.jpg");
    background-size: cover, cover;
    background-position: center top, center bottom;
    background-repeat: no-repeat, no-repeat;
    /* Slightly desaturated so the rainbow does not out-shout the brand amber. */
    filter: saturate(0.85);
    pointer-events: none;
    z-index: 0;
}

/* The amber radial is kept on top of the photo — it is what ties the hero back
   to the accent colour, and it sits behind the headline where the photo is
   darkest. */
.home-hero::after {
    content: "";
    position: absolute;
    inset: -40% 0 auto 50%;
    width: min(1100px, 130%);
    height: 700px;
    transform: translateX(-50%);
    background: radial-gradient(ellipse at center,
                rgba(245, 165, 36, 0.13) 0%,
                rgba(245, 165, 36, 0.04) 38%,
                transparent 70%);
    pointer-events: none;
    z-index: 0;
}

.home-hero > * {
    position: relative;
    z-index: 1;
}

.hero-title {
    font-size: clamp(2.25rem, 1.4rem + 3.4vw, 3.75rem);
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.03em;
    line-height: 1.08;
}

.hero-lede {
    color: var(--c2l-text-muted);
    font-size: clamp(1.02rem, 0.95rem + 0.3vw, 1.2rem);
    max-width: 34rem;
}

/* Version / platform pill above the headline. */
.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.85rem;
    border: 1px solid var(--c2l-border);
    border-radius: 999px;
    background-color: var(--c2l-surface);
    color: var(--c2l-text-muted);
    font-size: 0.82rem;
}

.hero-badge .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background-color: var(--c2l-accent);
}

/* ------ screenshots ------ */

.device-shot {
    width: 100%;
    height: auto;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.65);
}

/* ------ spec strip ------ */

.spec-strip {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
}

.spec-item {
    padding: 1.1rem 1rem;
    text-align: center;
}

.spec-item + .spec-item {
    border-left: 1px solid var(--c2l-border);
}

@media (max-width: 767.98px) {
    /* Four across is unreadable on a phone, so the strip becomes a 2x2 grid.
       The dividers have to follow: a vertical rule between the columns, a
       horizontal one between the rows. */
    .spec-item + .spec-item { border-left: none; }
    .spec-item:nth-child(even) { border-left: 1px solid var(--c2l-border); }
    .spec-item:nth-child(n + 3) { border-top: 1px solid var(--c2l-border); }
}

.spec-value {
    display: block;
    color: var(--c2l-text);
    font-size: 1.05rem;
    font-weight: var(--c2l-display-weight);
}

.spec-label {
    display: block;
    color: var(--c2l-text-muted);
    font-size: 0.8rem;
    letter-spacing: 0.04em;
}

/* ------ feature cards ------ */

.feature-card {
    height: 100%;
    padding: 1.5rem;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface-raised);
    transition: border-color 150ms ease, transform 150ms ease;
}

.home-section-alt .feature-card,
.page-section-alt .feature-card {
    background-color: var(--c2l-bg);
}

.feature-card:hover {
    border-color: var(--c2l-accent);
    transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
    .feature-card { transition: none; }
    .feature-card:hover { transform: none; }
}

.feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    margin-bottom: 0.9rem;
    border-radius: var(--c2l-radius);
    background-color: rgba(245, 165, 36, 0.12);
    color: var(--c2l-accent);
    font-size: 1.25rem;
}

.feature-card h3 {
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: 0.4rem;
}

.feature-card p {
    color: var(--c2l-text-muted);
    font-size: 0.92rem;
    margin-bottom: 0;
}

/* ------ numbered steps ------ */

.step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--c2l-accent);
    color: var(--c2l-accent);
    font-weight: 600;
    font-size: 0.95rem;
}

/* Cue-naming example. A plain <code> on a dark card is hard to pick out. */
.cue-example {
    display: block;
    padding: 0.85rem 1rem;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-bg);
    color: var(--c2l-accent);
    font-family: var(--bs-font-monospace);
    font-size: 0.9rem;
    overflow-x: auto;
    white-space: nowrap;
}

/* ------ checked list ------ */

.check-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.check-list li {
    position: relative;
    padding-left: 1.75rem;
    margin-bottom: 0.6rem;
    color: var(--c2l-text-muted);
}

.check-list li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    top: 0;
    color: var(--c2l-accent);
    font-weight: 700;
}

/* ------ closing call to action ------ */

.cta-panel {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background: linear-gradient(160deg, var(--c2l-surface-raised), var(--c2l-surface));
    padding: 2.5rem;
}

.price-tag {
    font-size: 2.75rem;
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    line-height: 1;
}

/* ------ founder note ------ */

.founder-note {
    border-left: 2px solid var(--c2l-accent);
    padding-left: 1.25rem;
    color: var(--c2l-text-muted);
    font-size: 1.05rem;
}

/* ------ faq ------ */

/* Bootstrap's accordion is white by default; same treatment as .dropdown-menu. */
.faq-accordion {
    --bs-accordion-bg: var(--c2l-surface);
    --bs-accordion-color: var(--c2l-text);
    --bs-accordion-border-color: var(--c2l-border);
    --bs-accordion-border-radius: var(--c2l-radius);
    --bs-accordion-btn-color: var(--c2l-text);
    --bs-accordion-btn-bg: var(--c2l-surface);
    --bs-accordion-active-bg: var(--c2l-surface-raised);
    --bs-accordion-active-color: var(--c2l-accent);
    --bs-accordion-btn-focus-box-shadow: 0 0 0 0.2rem rgba(245, 165, 36, 0.25);
    /* Stock chevron is near-black and invisible here. */
    --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%239aa0a6'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
    --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23f5a524'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.faq-accordion .accordion-body {
    color: var(--c2l-text-muted);
}

/* Brand-coloured text. Bootstrap's .text-warning is a near-miss for the accent
   and drifts from it whenever the token changes. */
.text-accent {
    color: var(--c2l-accent) !important;
}

/* Quiet label on a card ("Free", "Coming soon"). Bootstrap's .text-bg-dark is
   near-invisible on these surfaces. */
.badge-soft {
    display: inline-block;
    border: 1px solid var(--c2l-border);
    background-color: var(--c2l-bg);
    color: var(--c2l-text-muted);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 0.3em 0.7em;
    border-radius: 999px;
    vertical-align: middle;
}

/* The slides are not all the same shape: the app-window shot is ~1.37:1, the
   two full-desktop shots ~1.70:1. Left at their natural heights they resized
   the page on every rotation. The ratio lives on this wrapper rather than on
   the <img> itself: aspect-ratio on a replaced element still has to fight the
   image's own intrinsic ratio, while on a plain box it just holds. */
.carousel-frame {
    aspect-ratio: 1.7;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Inside the frame the shot keeps its own shape and its own border, scaled
   down to fit rather than letterboxed inside a frame-wide border. */
.carousel-frame > .carousel-img.device-shot {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;   /* beats the 353px cap on the shared .carousel-img */
    min-width: 0;       /* flex items refuse to shrink below content without it */
}

/* Same reason: the captions are different lengths and wrap to a second line at
   different breakpoints, which moved the page under the carousel. */
#carouselIndicators .carousel-item > p {
    min-height: 3em;   /* two lines at Bootstrap's 1.5 line-height */
}


/* ------------------------------------------------------- products page --- */

/* One panel per paid product: a screenshot beside the spec sheet, rather than
   four fixed-width .cards crammed into a .card-group. The old layout mixed
   .card-group with .col-lg-3 children and pinned every card to 18rem, so the
   cards neither lined up nor filled the row. */
.product-panel {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface-raised);
    padding: 2rem;
}

.page-section-alt .product-panel {
    background-color: var(--c2l-bg);
}

.product-title {
    font-size: 1.6rem;
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    margin-bottom: 0.25rem;
}

.product-kicker {
    color: var(--c2l-text-muted);
    font-size: 0.95rem;
}

/* Price beside the product name. Smaller than the home page's .price-tag,
   which anchors a whole call-to-action panel. */
.product-price {
    font-size: 1.75rem;
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    line-height: 1;
    white-space: nowrap;
}

/* Requirements, as label/value pairs rather than a list of sentences. */
.spec-list {
    margin-bottom: 0;
}

.spec-list dt {
    color: var(--c2l-text-muted);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding-top: 0.55rem;
}

.spec-list dd {
    color: var(--c2l-text);
    font-size: 0.92rem;
    padding-top: 0.5rem;
    margin-bottom: 0;
    border-top: 1px solid var(--c2l-border);
}

.spec-list dt + dd {
    border-top: 1px solid var(--c2l-border);
}

@media (max-width: 575.98px) {
    /* Stacked, the rule under the label would separate it from its own value. */
    .spec-list dt { border-top: 1px solid var(--c2l-border); }
    .spec-list dd { border-top: none; padding-top: 0.1rem; }
}

/* Standalone in a .feature-card the placeholder is a whole tile, not the top
   of a card, so it needs a border and radius on all four sides. */
.feature-card .product-placeholder {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
}

/* At-a-glance matrix under the product panels. */
.compat-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--c2l-text);
    --bs-table-border-color: var(--c2l-border);
    --bs-table-striped-color: var(--c2l-text);
    --bs-table-hover-bg: var(--c2l-surface-raised);
    --bs-table-hover-color: var(--c2l-text);
    margin-bottom: 0;
}

.compat-table th {
    color: var(--c2l-text-muted);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}

.compat-table td {
    font-size: 0.92rem;
    vertical-align: middle;
}

/* Wide table on a narrow screen scrolls itself rather than the page. */
.compat-scroll {
    overflow-x: auto;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
}


/* ----------------------------------------------------------- cart page --- */

/* The cart markup is written by loadCart() in the page's own script, which is
   left alone: everything here styles either the static shell or the rows that
   script injects. Nothing below selects on an id or handler the script needs.
   The one contract that matters is that #cart-items holds the <tr> rows. */

.cart-panel {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
    overflow: hidden;
}

.cart-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--c2l-text);
    --bs-table-border-color: var(--c2l-border);
    margin-bottom: 0;
}

.cart-table thead th {
    background-color: var(--c2l-surface-raised);
    border-bottom: 1px solid var(--c2l-border);
    color: var(--c2l-text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 1rem 1.5rem;
    white-space: nowrap;
}

.cart-table td {
    padding: 1.35rem 1.5rem;
    border-color: var(--c2l-border);
    vertical-align: middle;
}

/* Injected rows are plain <td>s with no classes of their own, so the column
   treatment has to come from position. Order: name, price, qty, line total,
   remove. */
.cart-table tbody td:first-child {
    font-weight: 500;
}

.cart-table tbody td:nth-child(2),
.cart-table tbody td:nth-child(3) {
    color: var(--c2l-text-muted);
    font-variant-numeric: tabular-nums;
}

.cart-table tbody td:nth-child(3) {
    text-align: center;
}

.cart-table tbody td:nth-child(4) {
    text-align: right;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.cart-table tbody td:last-child {
    text-align: right;
    width: 1%;
}

/* The remove control keeps its markup (a .btn.btn-sm.btn-danger containing an
   X) — restyled here into something quieter than a solid red block, since it
   sits next to the price on every line. */
#cart-items .btn-danger {
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--c2l-border);
    --bs-btn-color: var(--c2l-text-muted);
    --bs-btn-hover-bg: #b3261e;
    --bs-btn-hover-border-color: #b3261e;
    --bs-btn-hover-color: #ffffff;
    --bs-btn-active-bg: #8c1d17;
    --bs-btn-active-border-color: #8c1d17;
    --bs-btn-active-color: #ffffff;
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 50%;
    line-height: 1;
}

/* ------ order summary ------ */

.cart-summary {
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background: linear-gradient(160deg, var(--c2l-surface-raised), var(--c2l-surface));
    padding: 2rem;
}

@media (min-width: 992px) {
    /* Keeps the total and the checkout button in view while a long cart
       scrolls. 5.5rem clears the sticky navbar. */
    .cart-summary {
        position: sticky;
        top: 5.5rem;
    }
}

.cart-summary-title {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--c2l-text-muted);
    margin-bottom: 1.75rem;
}

.cart-summary-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.7rem 0;
    color: var(--c2l-text-muted);
    font-size: 0.92rem;
}

.cart-summary-total {
    border-top: 1px solid var(--c2l-border);
    margin-top: 0.9rem;
    padding-top: 1.5rem;
    padding-bottom: 0;
    color: var(--c2l-text);
    font-size: 1rem;
}

.cart-summary-total .amount {
    font-size: 1.75rem;
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Reassurances under the checkout button. */
.cart-assurances {
    list-style: none;
    padding-left: 0;
    margin: 2.75rem 0 0;
    padding-top: 2rem;
    border-top: 1px solid var(--c2l-border);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--c2l-text-muted);
}

.cart-assurances li {
    position: relative;
    padding-left: 1.75rem;
    margin-bottom: 0.9rem;
}

.cart-assurances li:last-child {
    margin-bottom: 0;
}

.cart-assurances i {
    position: absolute;
    left: 0;
    top: 0.15rem;
    color: var(--c2l-accent);
}

/* Quiet destructive action: it should not compete with Checkout. */
.cart-clear {
    --bs-btn-color: var(--c2l-text-muted);
    --bs-btn-hover-color: #e06c65;
    text-decoration: none;
    padding-left: 0;
}

/* ------ empty state ------ */

/* Driven entirely by CSS so the page script stays untouched: #cart-items is
   empty exactly when loadCart() found nothing to render. Browsers without
   :has() simply fall back to today's behaviour — an empty table. */
.cart-empty {
    display: none;
    margin-bottom: 3rem;
    border: 1px dashed var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
    padding: 5rem 2rem;
    text-align: center;
}

.cart-page:has(#cart-items:empty) .cart-empty {
    display: block;
}

.cart-page:has(#cart-items:empty) .cart-filled {
    display: none;
}

.cart-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: 1.25rem;
    border-radius: 50%;
    background-color: var(--c2l-surface-raised);
    border: 1px solid var(--c2l-border);
    color: var(--c2l-text-muted);
    font-size: 1.6rem;
}


/* -------------------------------------------------- documentation page --- */

/* This page used Bootstrap's .border-info / .text-info throughout — Bootstrap
   blue and a blue glow, on a black-and-amber site — plus a page-level <style>
   block that redefined .small globally. Both are replaced here with the design
   tokens; the tab structure, ids and data-bs attributes are untouched. */

/* Scoped replacement for the old global `.small { font-size: 0.85rem }`. */
.doc-body .small {
    font-size: 0.85rem;
}

/* ------ sidebar ------ */

@media (min-width: 992px) {
    /* The tab list is the page's table of contents, so it should stay put while
       a long panel scrolls. 5.5rem clears the sticky navbar. */
    .doc-nav {
        position: sticky;
        top: 5.5rem;
    }
}

.doc-nav .list-group-item {
    background-color: var(--c2l-surface);
    border-color: var(--c2l-border);
    color: var(--c2l-text-muted);
    font-family: var(--c2l-font-display);
    font-weight: 500;
    padding: 0.85rem 1rem;
    text-align: left;
    transition: color 120ms ease, background-color 120ms ease;
}

.doc-nav .list-group-item:hover {
    background-color: var(--c2l-surface-raised);
    color: var(--c2l-text);
}

/* Bootstrap paints .active with --bs-primary, which is still its blue. */
.doc-nav .list-group-item.active {
    background-color: var(--c2l-surface-raised);
    border-color: var(--c2l-border);
    color: var(--c2l-accent);
    box-shadow: inset 3px 0 0 var(--c2l-accent);
}

.doc-nav .list-group-item:focus-visible {
    outline: 2px solid var(--c2l-accent);
    outline-offset: -2px;
    z-index: 1;
}

/* ------ panels ------ */

/* Replaces `border border-info rounded p-3`, which carried a blue glow. */
.doc-card {
    height: 100%;
    padding: 1.25rem;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
}

.doc-card > :last-child {
    margin-bottom: 0;
}

/* Replaces the .text-info sub-headings. */
.doc-heading {
    color: var(--c2l-accent);
    font-family: var(--c2l-font-display);
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 0.65rem;
}

/* Tab-level heading, one per panel. */
.doc-title {
    font-size: 1.6rem;
    font-weight: var(--c2l-display-weight);
    letter-spacing: -0.02em;
    margin-bottom: 1.75rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--c2l-border);
}

/* Section heading inside a panel (Installation, Connectivity, ...). */
.doc-section-heading {
    color: var(--c2l-text);
    font-family: var(--c2l-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 0.9rem;
}

.doc-section {
    margin-bottom: 3rem;
}

.doc-section:last-child {
    margin-bottom: 0;
}

/* ------ definition lists ------ */

/* The dl.row pairs used inside panels: label in the accent, value in body text,
   with a rule between rows so long values stay legible. */
.doc-dl {
    margin-bottom: 0;
}

.doc-dl dt {
    color: var(--c2l-text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    padding-top: 0.6rem;
}

.doc-dl dd {
    font-size: 0.85rem;
    padding-top: 0.6rem;
    margin-bottom: 0;
}

.doc-dl > dt:not(:first-of-type),
.doc-dl > dt:not(:first-of-type) + dd {
    border-top: 1px solid var(--c2l-border);
}

.doc-card ul {
    padding-left: 1.1rem;
}

.doc-card li {
    margin-bottom: 0.4rem;
}

/* ------ figures ------ */

/* Screenshots had `border border-white p-1` — a hard white frame on black. */
.doc-figure {
    margin-bottom: 0;
}

.doc-figure img {
    width: 100%;
    height: auto;
    border: 1px solid var(--c2l-border);
    border-radius: var(--c2l-radius);
    background-color: var(--c2l-surface);
}

.doc-figure figcaption {
    color: var(--c2l-text-muted);
    font-size: 0.78rem;
    text-align: center;
    margin-top: 0.5rem;
}

/* The BarBuilder panel is the last place carrying Bootstrap's .text-info — it
   marks two notes as informational and a third as a caution. The distinction is
   worth keeping, so the caution stays highlighted and the informational lines
   drop to body text rather than staying Bootstrap blue. */
.doc-body .text-info {
    color: var(--c2l-text) !important;
}

/* The three port-state indicator shots sit in a row and are small by nature. */
.doc-state-figure {
    width: 120px;
}
