/* ==========================================================================
   Brite Lotus — Design tokens
   Values extracted from the Framer source design, not approximated.
   Everything downstream reads from this file. Change it here, change it
   everywhere.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Typeface: Satoshi (Fontshare, free for commercial use).
   Drop the .woff2 files into /assets/fonts/ and these rules pick them up.
   The variable font is preferred; the static weights are the fallback.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Satoshi";
  src: url("../fonts/Satoshi-Variable.woff2") format("woff2-variations"),
       url("../fonts/Satoshi-Variable.woff2") format("woff2");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Satoshi";
  src: url("../fonts/Satoshi-VariableItalic.woff2") format("woff2-variations"),
       url("../fonts/Satoshi-VariableItalic.woff2") format("woff2");
  font-weight: 300 900;
  font-style: italic;
  font-display: swap;
}

:root {
  /* ---- Color: core neutrals -------------------------------------------- */
  --bl-black:        #000000;   /* hero and footer ground */
  --bl-ink:          #050505;   /* near-black surfaces */
  --bl-slate:        #1d2327;   /* dark UI surface */
  --bl-charcoal:     #222222;   /* dark pill / button */
  --bl-white:        #ffffff;
  --bl-off-white:    #fafafa;   /* headline white on dark */
  --bl-gray-050:     #fafafa;
  --bl-gray-100:     #f2f2f2;   /* FAQ card */
  --bl-gray-200:     #f0f0f0;
  --bl-gray-300:     #d4d7dd;
  --bl-gray-400:     #878787;
  --bl-gray-600:     #5f6368;

  /* ---- Color: brand ----------------------------------------------------- */
  --bl-yellow:       #e6ff00;   /* primary CTA + inline emphasis */
  --bl-yellow-dim:   #c9df00;   /* pressed state */
  --bl-blue:         #009cdc;   /* lotus mark blue */
  --bl-blue-deep:    #0079ac;   /* hover/pressed — same hue, ~20% darker */
  --bl-blue-soft:    rgba(0, 153, 255, 0.2);

  /* ---- The full brand palette -------------------------------------------
     Recorded here as the source of truth. Note what it is: a cool spectrum
     running cyan → teal → blue → navy → indigo → purple → magenta, plus the
     yellow and the blacks. It is a family, not a set of categorical colors,
     which is why the category accents are assigned along it in order rather
     than picked for contrast with each other.

     Only four clear 4.5:1 on white unaided (#04586e, #133a5d, #29295a,
     #723c8e). The rest are used for fills, rules and artwork, and darkened
     to an "ink" variant wherever they carry type — see bl_category_palette()
     in includes/helpers.php.
     ---------------------------------------------------------------------- */
  --bl-magenta:      #cb59d4;
  --bl-purple:       #723c8e;
  --bl-indigo:       #29295a;
  --bl-navy:         #133a5d;
  --bl-teal-deep:    #04586e;
  --bl-teal:         #028c9b;
  --bl-teal-light:   #02a6b0;
  --bl-cyan:         #03d9dd;

  /* ---- Color: semantic -------------------------------------------------- */
  --bl-text-on-dark:        var(--bl-off-white);
  --bl-text-on-dark-muted:  rgba(250, 250, 250, 0.72);
  --bl-text-on-light:       var(--bl-black);
  --bl-text-on-light-muted: rgba(0, 0, 0, 0.62);
  --bl-hairline-dark:       rgba(255, 255, 255, 0.14);
  --bl-hairline-light:      rgba(0, 0, 0, 0.08);
  --bl-focus:               var(--bl-blue);
  --bl-danger:              #d93b3b;
  --bl-success:             #2f9e5f;

  /* ---- Color: themeable surfaces ----------------------------------------
     The tokens above name colors — --bl-white is white, and has to keep
     meaning white, because plenty of places use it for type sitting on a
     dark ground. These name JOBS instead, and a job can change color when
     the theme does.

     Everything that paints a reading surface, the type on it, or a line
     between two of them should read from here rather than from a color
     name. That is what makes the dark block at the bottom of this file
     four lines of values instead of a second stylesheet.

     Light values are identical to what the color names resolved to before
     this block existed, so introducing it changed nothing on screen.
     ---------------------------------------------------------------------- */
  --bl-surface:         var(--bl-white);        /* the page panel */
  --bl-surface-raised:  var(--bl-white);        /* cards sitting on it */
  --bl-surface-sunken:  var(--bl-gray-100);     /* wells, inset areas */
  --bl-text:            var(--bl-text-on-light);
  --bl-text-muted:      var(--bl-text-on-light-muted);
  --bl-border:          var(--bl-hairline-light);
  --bl-border-strong:   var(--bl-gray-300);

  /* The outline of a control the reader has to find and hit — a radio card,
     a text input, a select. It is deliberately darker than --bl-border-strong
     because WCAG 1.4.11 asks for 3:1 whenever the boundary is the only thing
     saying "this is a thing you can use", and --bl-gray-300 manages 1.4:1 on
     white. That is a hairline on a diagram, not the edge of a button, and on
     this site in particular the reader may well be squinting at it. */
  --bl-border-control:  var(--bl-gray-400);

  /* The menubar's own link ink. Not --bl-text: the bar is a distinct object
     floating over the page and its links sit a shade off true black. */
  --bl-navlink-ink:     #111111;

  /* The brand purple when it is carrying TYPE rather than filling a shape.
     #723c8e is the deepest accent in the palette and the one that clears
     4.5:1 on white — which is exactly why it fails on a dark panel, where it
     comes in at 2.3:1. The dark theme swaps in the lightened step of the
     same hue, the way bl_category_palette() does for the category accents. */
  --bl-accent-text:     var(--bl-purple);

  --bl-tint:            rgba(0, 0, 0, 0.06);    /* a wash over the surface */
  --bl-tint-hover:      rgba(0, 0, 0, 0.03);

  /* Three further steps of grey that the design already distinguishes and
     that a single "muted" would flatten: --bl-charcoal for type that is
     firm but not black, --bl-gray-600 for a section label, --bl-gray-400
     for a field icon or a placeholder. They are named by weight rather
     than by value so the dark theme can restate them without the light
     theme shifting by a single shade. */
  --bl-text-firm:       var(--bl-charcoal);
  --bl-text-soft:       var(--bl-gray-600);
  --bl-text-faint:      var(--bl-gray-400);

  /* The menubar pill is off-white, not white — it has to read as a distinct
     object floating over a white page. */
  --bl-surface-bar:     var(--bl-off-white);

  /* The wash under a hovered menu row. A solid grey on a white page; on a
     dark one it has to be a light veil instead, because a solid fill light
     enough to see would be brighter than the text sitting on it. */
  --bl-hover-fill:      var(--bl-gray-100);

  /* Shadows are the thing a dark theme usually gets wrong. Black at 5% over
     white reads as depth; the same black at 5% over a near-black surface is
     nothing at all, and every card silently flattens.

     Rather than rewrite two dozen box-shadows, each keeps its own geometry
     and alpha and gets multiplied. At 1 the math is a no-op, so light is
     untouched; the dark block raises it, and every shadow on the site
     deepens together and stays in proportion to its neighbors. */
  --bl-shadow-boost: 1;

  /* ---- Typography ------------------------------------------------------- */
  --bl-font-sans: "Satoshi", "Inter", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Display: 80px at desktop, scaled down fluidly. -2px tracking at 80px is
     -0.025em, so tracking is expressed in em to stay proportional. */
  --bl-size-display:  clamp(2.75rem, 1.55rem + 4.4vw, 5rem);   /* 44 → 80px */
  --bl-size-h1:       clamp(2.25rem, 1.35rem + 3.2vw, 3.75rem); /* 36 → 60px */
  --bl-size-h2:       clamp(1.75rem, 1.2rem + 2vw, 2.75rem);    /* 28 → 44px */
  --bl-size-h3:       clamp(1.375rem, 1.1rem + 1vw, 1.75rem);   /* 22 → 28px */
  --bl-size-lead:     clamp(1rem, 0.94rem + 0.25vw, 1.125rem);  /* 16 → 18px */
  --bl-size-body:     1rem;
  --bl-size-sm:       0.875rem;
  --bl-size-xs:       0.75rem;
  --bl-size-micro:    0.6875rem;

  --bl-lh-display: 1.2;
  --bl-lh-heading: 1.15;
  --bl-lh-body:    1.5;
  --bl-lh-tight:   1.2;

  --bl-track-display: -0.025em;
  --bl-track-heading: -0.02em;
  --bl-track-body:    -0.0125em;

  --bl-weight-regular: 400;
  --bl-weight-medium:  500;
  --bl-weight-bold:    700;
  --bl-weight-black:   900;

  /* ---- Space (4px base) -------------------------------------------------- */
  --bl-space-1:  0.25rem;
  --bl-space-2:  0.5rem;
  --bl-space-3:  0.75rem;
  --bl-space-4:  1rem;
  --bl-space-5:  1.5rem;
  --bl-space-6:  2rem;
  --bl-space-7:  2.5rem;
  --bl-space-8:  3rem;
  --bl-space-9:  4rem;
  --bl-space-10: 5rem;
  --bl-space-11: 6.5rem;
  --bl-space-12: 8rem;

  /* Section rhythm scales with the viewport so the design breathes the same
     way at 390px as it does at 2560px. */
  --bl-section-y: clamp(3.5rem, 2rem + 6vw, 8rem);
  --bl-gutter:    clamp(1.25rem, 0.6rem + 2.6vw, 3.5rem);

  /* ---- Layout ------------------------------------------------------------ */
  --bl-max-width:      1240px;
  --bl-max-width-wide: 1440px;
  --bl-max-prose:      68ch;

  /* ---- Radii ------------------------------------------------------------- */
  --bl-radius-xs:   4px;
  --bl-radius-sm:   6px;
  --bl-radius-md:   10px;
  --bl-radius-lg:   15px;
  --bl-radius-xl:   20px;
  --bl-radius-2xl:  40px;   /* portrait card, hero media */
  --bl-radius-pill: 100px;

  /* The light content panel lifts off the footer with this bottom radius. */
  --bl-radius-panel: 30px;

  /* ---- Elevation --------------------------------------------------------- */
  --bl-shadow-sm: 0 1px 5px rgba(0, 0, 0, calc(0.3 * var(--bl-shadow-boost)));
  --bl-shadow-md: 0 1px 10px rgba(0, 0, 0, calc(0.25 * var(--bl-shadow-boost)));
  --bl-shadow-lg: 0 2px 4px rgba(0, 0, 0, calc(0.25 * var(--bl-shadow-boost))),
                  0 12px 32px rgba(0, 0, 0, calc(0.28 * var(--bl-shadow-boost)));
  /* Deliberately light. The menubar sits over a dark ground where a heavy
     shadow turns into a grey smear rather than reading as elevation. */
  --bl-shadow-menubar: 0 1px 2px rgba(0, 0, 0, calc(0.14 * var(--bl-shadow-boost))),
                       0 8px 24px rgba(0, 0, 0, calc(0.16 * var(--bl-shadow-boost)));

  /* Portrait glow — the neon spill from the photo onto the page. */
  --bl-glow-portrait: 0 0 90px rgba(196, 60, 200, 0.35),
                      0 0 160px rgba(60, 90, 220, 0.25);
  --bl-glow-yellow:   0 0 24px rgba(230, 255, 0, 0.35);

  /* ---- Motion ------------------------------------------------------------ */
  --bl-ease-out:  cubic-bezier(0.22, 1, 0.36, 1);
  --bl-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --bl-ease-spring: cubic-bezier(0.34, 1.42, 0.64, 1);

  /* Entrance easing, measured off the reference animation frame by frame.
     At 30% of its duration an element is 24% faded, at 50% it's 56%, at 70%
     it's 79% — a gentle S-curve. The expo-out above reaches 60% in its first
     fifth, which is what made the per-item fades read as abrupt. */
  --bl-ease-enter: cubic-bezier(0.42, 0, 0.58, 1);

  --bl-dur-fast:  160ms;
  --bl-dur-base:  280ms;
  --bl-dur-slow:  520ms;

  /* The mobile menu. Deliberately slower than --bl-dur-base: a panel that
     covers most of a phone screen needs long enough to be seen arriving,
     or it reads as a flash rather than a movement. */
  --bl-dur-menu:  440ms;
  /* Measured off the reference: the body copy fades over ~730ms, the
     portrait over ~500ms, each signup row over ~650ms. */
  --bl-dur-enter: 760ms;
  --bl-dur-row:   650ms;

  /* ---- Z-index scale ----------------------------------------------------- */
  --bl-z-footer:    0;
  --bl-z-panel:     1;
  --bl-z-menubar:   80;
  --bl-z-megamenu:  70;
  --bl-z-overlay:   90;
  --bl-z-toast:     100;
}

/* ==========================================================================
   Dark theme — reading surfaces only

   Scoped deliberately. The marketing pages are a composition of light and
   dark already: the hero and footer are black BY DESIGN, and the contrast
   between them and the white panel is the design. Inverting that does not
   produce a dark homepage, it produces a broken one, because the parts that
   were the loud dark accent become the quiet light ground and the hierarchy
   turns inside out.

   The reading surfaces have no such composition. They are a page of text on
   a panel, which is exactly the thing that is painful to read at night, and
   exactly the thing a dark theme is for.

   Note what is NOT redefined here: --bl-black, --bl-white, and the grounds
   built from them. The footer and any dark band inside an article stay at
   true black, so the panel — now #15181c — still reads as a distinct plane
   floating above them and the footer reveal still works. If the panel went
   to #000 too, the whole page would flatten into one sheet and the site's
   signature move would silently stop existing.
   ========================================================================== */

@media (prefers-color-scheme: dark) {

  /* EVERY page, unless it opts out.

     This was an allowlist of page classes, and an allowlist is a list someone
     forgets to add to: /connect and /404 shipped with no dark theme because
     they were simply never named here, and nobody notices until a reader with
     a dark system opens one at night and gets a white flash.

     So it is now a denylist of two. A new page gets the dark theme by writing
     no CSS at all, which is the only version of this that survives contact
     with a growing site.

     .bl-theme-fixed  — pages composed to be dark whatever the system says. The
                        homepage is the one: its hero IS the dark ground, and
                        re-theming the sections under it would flatten the
                        contrast the page is built on.
     The admin used to be excluded here because it paints with the absolute
     tokens rather than the semantic ones. It now carries its own remapping
     block at the foot of admin.css, so it is in. */
  body:not(.bl-theme-fixed) {
    /* Tells the browser to render native form controls, scrollbars and
       spellcheck underlines dark too. Without it you get a dark page with a
       white scrollbar and a white select menu. */
    color-scheme: dark;

    --bl-surface:        #15181c;   /* the panel: clearly above true black */
    --bl-surface-raised: #1e232a;   /* cards lift off it */
    --bl-surface-sunken: #0e1013;

    /* Not #ffffff. Pure white on a near-black ground is the glare problem
       again in reverse — it haloes and it is tiring over a long article. */
    --bl-text:           #e9eaec;
    --bl-text-muted:     rgba(233, 234, 236, 0.66);
    --bl-text-firm:      #e9eaec;
    --bl-text-soft:      rgba(233, 234, 236, 0.72);
    --bl-text-faint:     rgba(233, 234, 236, 0.52);

    /* The bar keeps its relationship to the page: a shade off the panel, so
       it still reads as a separate object rather than a hole in it. */
    --bl-surface-bar:    #232830;

    /* A veil rather than a fill. A solid light grey here would be brighter
       than the label sitting on it. */
    --bl-hover-fill:     rgba(255, 255, 255, 0.09);

    --bl-border:         rgba(255, 255, 255, 0.13);
    --bl-border-strong:  rgba(255, 255, 255, 0.26);
    --bl-border-control: rgba(255, 255, 255, 0.42);
    --bl-navlink-ink:    var(--bl-text);
    --bl-accent-text:    #b17bcd;
    --bl-tint:           rgba(255, 255, 255, 0.08);
    --bl-tint-hover:     rgba(255, 255, 255, 0.05);

    /* Every shadow on the page, deepened together. See the note on the
       token itself. */
    --bl-shadow-boost:   2.6;

    /* The mid-tone brand blue is a link color on white. On a near-black
       ground it is too dark to read, so links take the brighter step of the
       same hue. */
    --bl-blue-deep:      #3fb9ee;
  }

  /* The circuit ground is dark line art at 30% — drawn to sit on white. On
     a dark panel it disappears entirely. Inverted it becomes light line art
     on dark, which is the same idea; the opacity comes down because light
     lines on dark read considerably louder than dark lines on white at the
     same value. */
  body:not(.bl-theme-fixed) .bl-ground-circuit::before {
    filter: invert(1);
    opacity: 0.11;
  }

  /* The menubar pill is now dark, so the dark wordmark inside it has to
     become the light one. The light variant already ships for the footer. */
  body:not(.bl-theme-fixed) .bl-menubar__logo img {
    content: url("../img/logo-horizontal-light.png");
  }

  /* The mega menu's device icons. Every one of the fourteen is a single-color
     SVG with fill="#000000" baked in, loaded through an <img> — so there is
     no currentColor to inherit and no inner node for CSS to reach. A plain
     invert is exactly right here and only because they are monochrome: on a
     colored icon it would rotate the hue as well as the lightness. If a
     colored icon ever joins this menu, it needs excluding from this rule
     rather than the rule being softened. */
  body:not(.bl-theme-fixed) .bl-mega__icon img {
    filter: invert(1);
  }

  /* The sign-up pill.

     At rest what you see is __shape, an opaque layer sitting behind the
     label; the blue underneath it is only revealed on hover, when the shape
     shrinks into a disc at the right end. So "white pill, black text" means
     coloring the shape, not the button's background.

     The hover state then needs both of its own colors: the label ends up on
     the blue that has been revealed, so it turns white, and the arrow ends
     up inside the now-white disc, so it turns dark. Without the second of
     those the arrow is white-on-white and the animation appears to break. */
  body:not(.bl-theme-fixed) .bl-navcta { color: var(--bl-surface); }

  body:not(.bl-theme-fixed) .bl-navcta__shape { background: var(--bl-text); }

  body:not(.bl-theme-fixed) .bl-navcta:hover,
  body:not(.bl-theme-fixed) .bl-navcta:focus-visible { color: var(--bl-white); }

  body:not(.bl-theme-fixed) .bl-navcta:hover .bl-navcta__arrow,
  body:not(.bl-theme-fixed) .bl-navcta:focus-visible .bl-navcta__arrow { color: var(--bl-surface); }

  /* The category accent.

     bl_category_vars() writes --cat, --cat-ink and --cat-lit onto each card,
     chip and article inline. An inline declaration cannot be overridden from
     a stylesheet, so the theme cannot simply redefine --cat-ink — instead the
     accent's text usages read --cat-fg first, and --cat-fg is set here, on
     that same element, because a custom property only resolves against the
     element that carries it.

     The attribute selector is matching the inline block this site writes
     itself, so it is stable; it is not sniffing arbitrary markup. Anything
     it misses falls through to --cat-ink and is merely too dark, never
     broken. */
  body:not(.bl-theme-fixed) [style*="--cat"] {
    --cat-fg: var(--cat-lit, var(--cat-ink));
  }

  /* One exception, and it is a real one. The badge that floats on a card's
     artwork keeps its white pill in both themes, because it sits on a photo
     rather than on the page — and on white, the lightened accent is the
     wrong one. So it steps back to the ink value, which is what white was
     always paired with. The inline badge is a tinted chip on the card
     surface itself and is not affected. */
  .bl-oasis .bl-card__badge:not(.bl-card__badge--inline) {
    --cat-fg: var(--cat-ink);
  }

  /* The active filter chip is the one place the accent is a FILL rather than
     text, so it keeps the deep ink behind it — but white on a deep fill was
     tuned against a white page. On the dark panel the fill needs to read as
     the lit accent with the panel's own color punched out of it, which is
     the same contrast ratio the other direction.

     The fill and the text are derived from ONE value so they cannot drift
     apart. The "All" chip carries no accent at all, and reading the fill and
     the text from separate fallbacks put dark text on a charcoal fill — a
     chip you could not read. Here an accent-less chip simply inverts: light
     fill, panel-colored text, which is what "selected" looks like on a dark
     surface anyway. */
  .bl-oasis .bl-chip.is-active,
  .bl-oasis .bl-pagination__page.is-current {
    --chip-fill: var(--cat-lit, var(--cat-ink, var(--bl-text)));
    background: var(--chip-fill);
    border-color: var(--chip-fill);
    color: var(--bl-surface);
  }

  /* Two more places a charcoal fill was doing the work of "this one is
     selected" against a white page, and would now be a dark shape on a dark
     page. The carousel's progress fill takes the lit accent; its inactive
     dots take the text color at low alpha, which is the same relationship
     they had to the light page. */
  .bl-oasis .bl-carousel__fill {
    background: var(--cat-lit, var(--cat-ink, var(--bl-text)));
  }

  .bl-oasis .bl-carousel__dot[aria-selected="true"]::before {
    background: color-mix(in srgb, var(--bl-text) 40%, transparent);
  }

  /* The last few colors that were written as literals rather than tokens,
     each measured against the dark panel rather than guessed at.

     The menubar links were #111111 — 1.06:1 on the dark bar, which is to
     say invisible. The red the subscribe block uses for its mark came to
     3.28:1 and the legal draft badge to 2.47:1; both take the same hue a
     few steps lighter. The light values are left exactly where they are,
     which is why these live here and not in the rules themselves. */

  .bl-oasis .bl-subscribe__mark { color: #ff6b6b; }

  .bl-legal .bl-legalpage__draft { color: #e0a264; }

  /* The CTA pill was a dark shape reading against a white bar. On a dark bar
     it is a dark shape on a dark bar, so it inverts — the same move the
     active chip makes, for the same reason. */
  body:not(.bl-theme-fixed) .bl-btn--dark {
    background: var(--bl-text);
    border-color: var(--bl-text);
    color: var(--bl-surface);
  }
}
