/* THE DARK STAGE — the whole product's surface.
   Marketing, 2026-08-25. Extended to every signed-in page, 2026-08-26.

   Why this file exists
   ====================
   The greyscale stage (fe-landing.css, 2026-08-02) was built on a correct
   instinct — "on a page whose job is to be understood the only thing that
   should catch the eye is the one action" — and then took it one step too far.
   What it produced was a page with no horizon: white on white, one blue pill,
   and every proof rendered as another block of grey prose. Read next to a
   competitor's lander it does not look restrained, it looks unfinished, and
   the product it is selling — an employee that BUILDS things — never appears
   on screen at all.

   The correction is not "add colour". It is: put the product on the stage.
   Everything below serves one of three jobs.

     1. A LIT ROOM, not a white page. A near-black canvas (--bg) with two
        raised planes above it and three radial washes behind the fold. Depth
        is what makes a screenshot sit ON something instead of floating in
        nothing, and it is the cheapest way to make one element — the action —
        the brightest thing in view. The greyscale rule survives inverted:
        there is still exactly one bright thing per screen.

     2. MOTION THAT IS AN ARGUMENT. Two animations only, and both of them
        state the pitch rather than decorate it: the headline word cycles
        through the kinds of business it builds (the range IS the product),
        and the build layers assemble a real site one band at a time (the
        build IS the product). Nothing else moves. Both stop dead under
        prefers-reduced-motion — see the block at the end of this file.

     3. CHROME AROUND EVERY PROOF. A screenshot with no frame reads as an
        illustration. The same screenshot inside browser chrome with a lock
        and a hostname reads as a place that exists. We ship real captures
        (`manage.py landing_shots`), so the frame is not a costume — it is the
        missing half of a true claim.

   What this file may NOT do
   =========================
   - No dollar figures, ever. The product rules in CLAUDE.md are enforced by
     core/tests.py::ClaimTests and they are not softened by a redesign.
   - No fabricated metrics. Every number rendered in a mock below is either
     structural (v1, v2) or lorem-shaped bars with no digits attached. If you
     are tempted to put "1,284 visitors" in a mock, don't — GROWTH_PLAN §0.
   - No hue on the app. Everything here is scoped under `body.fe-dark`,
     which base.html sets only when `noindex` is false. The signed-in product
     keeps the light one-column register from firstemployee.css untouched.

   Load order: firstemployee.css → fe-landing.css → THIS. It is last on
   purpose; it re-points the design tokens the other two consume, so most of
   the re-skin happens without touching their rules at all. */

/* ==========================================================================
   1. TOKENS
   The whole light system is var-driven, so flipping the surface is mostly a
   matter of re-pointing the vars rather than rewriting components. Anything
   that still needs a hand-written override lives in §3 and is commented with
   the reason it could not be done here.
   ========================================================================== */
body.fe-dark {
    --bg:         #0B0D12;  /* ink-deep: the canvas */
    --bg-2:       #12151C;  /* ink-raised: cards, mocks, the report */
    --bg-3:       #191D27;  /* wells, meters, table zebra */
    --text:       #F3F5F9;
    --text-dim:   #A5AEC2;
    --text-faint: #79839B;
    --line:       rgba(255, 255, 255, .10);
    --line-2:     rgba(255, 255, 255, .17);

    /* The accent trio. --accent is the anchor and is the only one that ever
       carries text; violet and cyan are structural (step numerals, bullet
       squares, the third mock pane) and never sit under small copy.
       #6C8CFF on #0B0D12 is 7.4:1 — comfortably over AA, which matters
       because on a dark canvas the accent is also the link colour. */
    --accent:      #6C8CFF;
    --accent-hi:   #8FA8FF;
    --accent-deep: #2F5FE0;  /* the dark end of the CTA gradient */
    --accent-iris: #7452F2;  /* the light end */
    --accent-wash: rgba(108, 140, 255, .14);
    --violet:      #A78BFA;
    --cyan:        #22D3EE;

    /* The stage vars pointed at near-black to draw dark bands on a white
       page. There is no white page any more, so they invert: a "dark band"
       is now the RAISED plane. */
    --stage:   #12151C;
    --stage-2: #191D27;

    /* Status colours have to move: #157F4B and #B91C1C were chosen against
       white and both fall under 4.5:1 on ink. These are the same hues lifted
       until they clear it on --bg. */
    --good: #4ADE80;
    --warn: #FBBF24;
    --bad:  #F87171;

    /* A display stack for the poster type. No webfont: a 40KB download to
       render one headline is a bad trade on the page whose job is to be fast,
       and every name below is already on the box that has it. The tail is the
       body sans, so a machine with none of them still gets the design — just
       a little wider. */
    --display: "Bricolage Grotesque", "Avenir Next", Avenir, "Segoe UI Variable Display",
               "Helvetica Neue", system-ui, sans-serif;

    background: var(--bg);
    color: var(--text-dim);
}

/* The three washes behind the fold. Painted on <body> rather than on the hero
   so they survive the hero's own stacking context and bleed a few hundred
   pixels past it — a glow that stops exactly at a section edge reads as a
   rectangle, which is the opposite of the point. `background-attachment` is
   deliberately NOT fixed: on iOS a fixed layer repaints every scroll frame. */
body.fe-dark::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 1100px;
    pointer-events: none;
    z-index: 0;
    background:
        radial-gradient(760px 400px at 50% -6%,  rgba(108, 140, 255, .26), transparent 70%),
        radial-gradient(520px 320px at 12% 22%,  rgba(34, 211, 238, .10),  transparent 70%),
        radial-gradient(560px 340px at 88% 18%,  rgba(167, 139, 250, .16), transparent 70%);
    /* Fade the wash out at both rails so it never draws a visible edge
       against the viewport on a wide monitor. */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 200px, #000 calc(100% - 200px), transparent);
            mask-image: linear-gradient(to right, transparent, #000 200px, #000 calc(100% - 200px), transparent);
}
body.fe-dark > * { position: relative; z-index: 1; }

/* ==========================================================================
   2. THE STAGE + NAV
   ========================================================================== */

/* fe-landing.css hard-codes the light stage gradient and a white nav (it was
   written when greyscale was the decision). Both are re-stated here rather
   than deleted there, so reverting this file alone restores the old surface
   exactly. */
body.fe-dark .fe-stage {
    background: none;
    color: var(--text-dim);
}
body.fe-dark .fe-stage h1,
body.fe-dark .fe-stage h2,
body.fe-dark .fe-stage strong { color: var(--text); }
body.fe-dark .fe-stage-sub { color: var(--text-dim); }

/* The nav rides the canvas with no fill until you scroll, then earns a
   surface. `.is-stuck` is set by fe-stage.js; the no-JS state is the
   transparent one, which is correct on a page that opens at scrollTop 0. */
body.fe-dark .fe-nav {
    position: sticky;
    top: 0;
    z-index: 40;
    background: transparent;
    border-bottom: 1px solid transparent;
    transition: background-color .2s ease, border-color .2s ease, backdrop-filter .2s ease;
}
body.fe-dark .fe-nav.is-stuck {
    background: rgba(11, 13, 18, .78);
    border-bottom-color: var(--line);
    -webkit-backdrop-filter: saturate(140%) blur(12px);
            backdrop-filter: saturate(140%) blur(12px);
}
body.fe-dark .fe-nav .fe-brand { color: var(--text); }
body.fe-dark .fe-nav .fe-navlink { color: rgba(255, 255, 255, .66); }
body.fe-dark .fe-nav .fe-navlink:hover,
body.fe-dark .fe-nav .fe-navlink.is-active { color: #fff; }

/* One gradient in the whole navigation, on the one control that is the point
   of the page. Everything else is a hairline. */
body.fe-dark .fe-nav .fe-btn.fe-btn-primary,
body.fe-dark .fe-btn-primary {
    background: linear-gradient(90deg, var(--accent-deep), var(--accent-iris));
    border-color: transparent;
    color: #fff;
    border-radius: 999px;
    transition: filter .15s ease;
}
body.fe-dark .fe-nav .fe-btn.fe-btn-primary:hover,
body.fe-dark .fe-btn-primary:hover {
    background: linear-gradient(90deg, var(--accent-deep), var(--accent-iris));
    filter: brightness(1.12);
    border-color: transparent;
    color: #fff;
}
/* ⚠ `background` is NOT optional here. firstemployee.css gives `.fe-btn` a
   white fill for the light app, and the first version of this rule set only
   the border and the text colour — which left every secondary button on the
   dark pages as a solid white pill. It survived review because there is
   exactly one of them below the fold on one page ("Read their terms, then
   read ours"), and it was never in a 900px viewport slice. */
body.fe-dark .fe-btn {
    background: transparent;
    border-color: var(--line-2);
    color: var(--text);
    border-radius: 999px;
}
body.fe-dark .fe-btn:hover {
    border-color: rgba(255, 255, 255, .34);
    color: #fff;
}

/* ==========================================================================
   3. THE HERO
   ========================================================================== */

/* Poster type. The old floor was 2.7rem because at 390px the headline was
   reading as body copy; on a dark canvas it can go further before it shouts,
   and the display stack is tighter per character than the UI sans, so the
   same line count holds at a larger size. */
body.fe-dark .fe-stage h1 {
    font-family: var(--display);
    /* 2.4rem floor, not 2.9: the reserved rotator box is 8.8em wide, and at
       2.9rem on a 390px screen that is 408px inside 366px of usable width —
       the longest word was being clipped by the body's overflow guard, which
       is why the horizontal-overflow check did not catch it. At 2.4rem the
       box is ~338px and every word fits. */
    font-size: clamp(2.4rem, 6.4vw, 4.9rem);
    font-weight: 800;
    letter-spacing: -.028em;
    line-height: 1.045;
}
/* TWO TIERS, NOT THREE LINES.
   The headline is two sentences — the promise ("Start a business.") and the
   mechanism ("Your first employee builds it.") — and setting both at poster
   size made it wrap to three lines and stand 250px tall at 1440. That pushed
   the build loop, the most persuasive thing on the site, to 912px down: below
   the fold on a laptop, invisible to anyone who did not decide to scroll.

   The competitor's headline is four words on one line because their pitch is
   four words. Ours is not, and shortening it would drop the positioning
   (DEVELOPMENT_PLAN: the pitch is starting a business, the employee is how).
   So the second clause becomes a deck — same words, same order, read at about
   half the size. The <h1> still contains the whole sentence, which is what
   the copy test asserts and what a screen reader gets. */
.fe-h1-deck {
    display: block;
    margin-top: .28em;
    font-size: .42em;
    font-weight: 700;
    letter-spacing: -.015em;
    line-height: 1.2;
    color: var(--text);
}

body.fe-dark .fe-col h2 {
    font-family: var(--display);
    letter-spacing: -.02em;
    color: var(--text);
}

/* --- the rotating word ------------------------------------------------
   The mechanic: an inline-block whose WIDTH is animated to the measured
   width of the incoming word, with the word itself cross-fading through a
   small blur inside it. Animating width (not just swapping text) is what
   stops the rest of the line from jumping on every tick — the line re-flows
   over 350ms instead of snapping, so the eye reads it as one continuous
   sentence rather than four different ones.

   A hidden measuring twin sits off-canvas at -9999px carrying the incoming
   word; JS reads its scrollWidth to get the target. It is aria-hidden and so
   is the animation as a whole: the <h1> exposes ONE stable sentence to a
   screen reader (see the sr-only span in index.html), because a headline
   that mutates four times a minute is hostile to anything that reads
   linearly, and to Google.

   No-JS state: the span holds the first word at its natural width, and
   `width` is only ever set as an inline style by JS. So the headline is
   complete and correct with the script blocked. */
/* No width transition: the box is reserved at the widest word by
   fe-stage.js and never changes, which is what took the landing's CLS from
   0.40 to a passing score on mobile. If you reintroduce an animated width
   here, measure CLS before you ship it. */
.fe-rot {
    position: relative;
    display: inline-block;
    white-space: nowrap;
    text-align: center;
    vertical-align: baseline;
    /* Pre-reserved so the box is the right size on the FIRST paint, before
       fe-stage.js runs and writes the exact px. Measured at 8.8em for the
       current word list at both 390px and 1440px — the ratio is stable
       because it is a function of the font, not the viewport. Without it the
       reserve landed after load and cost 0.088 of CLS on mobile all by
       itself. Re-measure if you change the longest word. */
    min-width: 8.8em;
}
.fe-rot-measure {
    position: absolute;
    left: -9999px;
    top: 0;
    visibility: hidden;
    white-space: nowrap;
}
.fe-rot-word {
    display: inline-block;
    padding-bottom: 1px;
    border-bottom: 3px solid var(--accent);
    background: linear-gradient(90deg, var(--accent), var(--violet) 55%, var(--cyan));
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    transition: opacity .18s ease, filter .18s ease;
}
.fe-rot-word.is-out { opacity: 0; filter: blur(4px); }
/* The full stop rides with the word: same fade, so the two never separate
   mid-swap, and it inherits the headline's own colour rather than the
   gradient (a gradient-clipped period is a smudge at this size). */
.fe-rot-dot { color: var(--text); transition: opacity .18s ease; }
.fe-rot-word.is-out + .fe-rot-dot { opacity: 0; }

/* --- the brief box ----------------------------------------------------
   `.fe-briefbox` is the real class (fe-landing.css §152); it is one bordered
   surface with the submit arrow living inside the field, which is already the
   right shape. All that changes is that the surface stops being white paper
   and becomes a lit panel: 4% white over the canvas, a hairline, and a large
   soft drop shadow so the box sits ON the glow rather than in it. */
body.fe-dark .fe-briefbox {
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 16px;
    padding: 20px;
    box-shadow: 0 24px 64px -16px rgba(0, 0, 0, .6);
    -webkit-backdrop-filter: blur(10px);
            backdrop-filter: blur(10px);
}
body.fe-dark .fe-briefbox textarea,
body.fe-dark textarea.form-control,
body.fe-dark input.form-control {
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 12px;
    color: var(--text);
    resize: none;
}
body.fe-dark textarea::placeholder,
body.fe-dark input::placeholder { color: rgba(255, 255, 255, .5); }
body.fe-dark .fe-briefbox textarea:focus,
body.fe-dark textarea.form-control:focus,
body.fe-dark input.form-control:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(108, 140, 255, .25);
    background: rgba(255, 255, 255, .06);
    color: var(--text);
    outline: none;
}
/* The submit control. Full width at the foot of the box now (see
   index.html), so the absolute corner positioning fe-landing.css gives it has
   to be undone rather than merely recoloured. It is the one gradient in the
   hero and the only thing on the first screen that is meant to be clicked. */
body.fe-dark .fe-briefgo.fe-briefgo-wide {
    position: static;
    width: 100%;
    height: auto;
    border-radius: 999px;
    padding: 13px 18px;
    font-size: .98rem;
    font-weight: 650;
    background: linear-gradient(90deg, var(--accent-deep), var(--accent-iris));
    color: #fff;
    border: 0;
    box-shadow: none;
    transition: filter .15s ease;
}
body.fe-dark .fe-briefgo.fe-briefgo-wide:hover { filter: brightness(1.14); }
/* The right padding on the textarea existed to clear the corner arrow. With
   the arrow gone it is just a ragged right edge on every line of the brief. */
body.fe-dark .fe-briefbox textarea { padding-right: 18px; min-height: 84px; }
body.fe-dark .fe-briefhint,
body.fe-dark .fe-stage-free { color: var(--text-faint); }

/* The chips live INSIDE the box now (see index.html). Inside, they are
   obviously part of the control, so the sentence that used to explain them
   ("Press Enter, or pick one below") is gone with them. */
body.fe-dark .fe-briefbox-eg {
    margin-block: 12px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 7px;
    margin: 0;
}
/* The dot separator in the one remaining line under the box. */
body.fe-dark .fe-stage-free { display: flex; align-items: center; justify-content: center; gap: 10px; }
body.fe-dark .fe-stage-free .fe-dot {
    width: 4px; height: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .22);
    display: inline-block;
}

/* The preset chips (`.fe-eg`). These already existed and already spanned
   sectors on purpose — a firm, a trade, a shop, a directory — and that range
   is the same argument the rotating headline makes. All that changes is that
   they stop reading as grey tags and start reading as controls. */
body.fe-dark .fe-eg {
    /* Reserved so a swapped label cannot reflow the row and shift its
       neighbours — the second CLS source on the page after the headline. */
    min-width: 168px;
    justify-content: center;
    background: var(--accent-wash);
    border: 1px solid rgba(108, 140, 255, .3);
    color: #CDD8FF;
    border-radius: 999px;
    transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
/* One chip at a time fades while its label is swapped (fe-stage.js). */
body.fe-dark .fe-eg { transition: border-color .15s ease, color .15s ease, background-color .15s ease, opacity .2s ease; }
body.fe-dark .fe-eg.is-out { opacity: 0; }
body.fe-dark .fe-eg:hover {
    border-color: rgba(108, 140, 255, .62);
    background: rgba(108, 140, 255, .2);
    color: #fff;
}

/* The quiet second door, and the way down. Both stay quiet — they were
   deliberately subordinate to the box and a redesign is not a reason to
   promote them. */
body.fe-dark .fe-noidea { color: var(--text-faint); }
body.fe-dark .fe-noidea button { color: var(--accent); }
body.fe-dark .fe-noidea button:hover { color: var(--accent-hi); }
body.fe-dark .fe-stage-down a { color: var(--text-dim); }
body.fe-dark .fe-stage-down a:hover { color: var(--text); }
body.fe-dark .fe-stage-down .fe-down-a { border-color: var(--line-2); }
body.fe-dark .fe-stage-down a:hover .fe-down-a { border-color: var(--accent); }

/* ==========================================================================
   4. THE BUILD LAYERS
   The centrepiece. A browser frame containing two panes: the steps our
   founding build actually runs down the left, and a miniature site that
   assembles band by band on the right, in step with them.

   It is DOM, not an image or a video, for three reasons: it is ~3KB instead
   of ~300KB, it stays sharp at any density, and — the real one — it is
   readable by a text-only client, so the page still argues its case with CSS
   off. The mini-site's colours come from real entries in tenants/tokens.py
   (forest / ember / royal), so what is on screen is the palette range a build
   can actually land on, not an art director's invention.
   ========================================================================== */
.fe-bl-wrap {
    border-radius: 24px;
    padding: 8px;
    /* The dot grid. It reads as graph paper under the frame and gives the
       glow something to fall on. 1px dots at 26px pitch is under the density
       where it starts to shimmer against a display's own subpixel grid. */
    background-image: radial-gradient(rgba(232, 234, 238, .05) 1px, transparent 1.4px);
    background-size: 26px 26px;
}
.fe-bl {
    max-width: 880px;
    margin-inline: auto;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--bg-2);
    text-align: left;
    font-size: 12.5px;
    overflow: hidden;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .04),
                0 32px 90px -24px rgba(108, 140, 255, .35);
}

/* --- browser chrome (shared with the gallery cards) --- */
.fe-chrome {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 15px;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.fe-chrome i {
    width: 8px; height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex: none;
}
.fe-chrome i:nth-child(1) { background: rgba(108, 140, 255, .55); }
.fe-chrome i:nth-child(2) { background: rgba(167, 139, 250, .55); }
.fe-chrome i:nth-child(3) { background: rgba(34, 211, 238, .55); }
.fe-chrome b {
    margin-left: 8px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 12px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .06);
    font: inherit;
    font-size: 11.5px;
    font-weight: 400;
    color: rgba(255, 255, 255, .58);
    /* The hostname is the whole point of the frame — it says "this is a
       place", not "this is a picture". Never truncate it away on a phone;
       drop the padding instead. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fe-chrome b svg { flex: none; opacity: .8; }
.fe-chrome .fe-chrome-live {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--good);
    background: rgba(74, 222, 128, .1);
    border: 1px solid rgba(74, 222, 128, .28);
    border-radius: 999px;
    padding: 2px 9px;
}
.fe-chrome .fe-chrome-live::before {
    content: "";
    width: 5px; height: 5px;
    border-radius: 50%;
    background: currentColor;
}

/* --- the slides ---
   All five businesses are in the DOM; one is shown at a time. `display` is
   NOT used to switch them: a display:none slide has no layout, so the frame
   would collapse to zero height between businesses and the page would jump
   every few seconds. They stack in one grid cell instead, and only opacity
   and pointer-events change. The frame therefore holds the height of the
   TALLEST demo at all times, which is why every demo below is written to a
   similar length. */
.fe-bl-body {
    display: grid;
    min-height: 300px;
}
.fe-demo {
    grid-area: 1 / 1;
    display: grid;
    grid-template-columns: 1fr;
    min-width: 0;
}
@media (min-width: 640px) {
    .fe-demo { grid-template-columns: 1.05fr 1fr; }
}

/* With JS off, every slide is visible and they would stack on top of each
   other — so the un-armed state shows the FIRST and hides the rest. This is
   the one place the stylesheet hides something JS does not have to undo,
   because the thing it hides is a duplicate, not content. The first slide
   ships complete, which is what a crawler and a reader with no JS get. */
.fe-demo:not(:first-child) { visibility: hidden; }
html.fe-bl-armed .fe-demo {
    visibility: hidden;
    opacity: 0;
    transition: opacity .45s ease;
    pointer-events: none;
}
html.fe-bl-armed .fe-demo.is-current {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
}

.fe-bl-steps { padding: 16px; min-width: 0; }
.fe-bl-brief {
    display: inline-block;
    margin-bottom: 12px;
    padding: 6px 12px;
    border-radius: 9px;
    background: rgba(47, 95, 224, .25);
    color: rgba(255, 255, 255, .92);
    line-height: 1.45;
}
.fe-bl-steps ol { list-style: none; margin: 0; padding: 0; }
.fe-bl-steps li {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 4px 0;
    color: var(--text);
    line-height: 1.45;
}

/* The tonight line. Under a rule and in the accent, because it is a different
   day's work — the build finished on the line above it. This is the beat a
   site builder cannot show, so it is the one thing here allowed to be a
   colour rather than grey. */
.fe-bl-tonight {
    margin: 10px 0 0;
    padding-top: 10px;
    border-top: 1px solid var(--line);
    color: var(--accent);
    font-size: 12px;
    line-height: 1.5;
}

/* Steps arrive under the JS-set arming class — see the note on
   `html.fe-bl-armed` above. With no JS every step is present and ticked,
   which is the true end state of a finished build. */
html.fe-bl-armed .fe-bl-steps li,
html.fe-bl-armed .fe-bl-tonight {
    color: var(--text-dim);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .3s ease, transform .3s ease, color .3s ease;
}
html.fe-bl-armed .fe-bl-steps li.is-in,
html.fe-bl-armed .fe-bl-tonight.is-in { opacity: 1; transform: none; }
html.fe-bl-armed .fe-bl-steps li.is-done { color: var(--text); }
html.fe-bl-armed .fe-bl-tonight.is-in { color: var(--accent); }

/* The checkbox. TICKED is the default state and the empty one is the
   exception that exists only while JS is driving — so a no-JS reader sees a
   finished build rather than a list of unchecked boxes, which would read as
   "it did not do any of this". */
.fe-bl-steps li::before {
    content: "";
    flex: none;
    width: 13px; height: 13px;
    border-radius: 4px;
    border: 1.5px solid var(--accent);
    background: var(--accent);
    transform: translateY(2px);
    transition: background-color .25s ease, border-color .25s ease;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-6.5' fill='none' stroke='%230B0D12' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-size: 100% 100%;
    background-repeat: no-repeat;
}
html.fe-bl-armed .fe-bl-steps li:not(.is-done)::before {
    border-color: var(--line-2);
    background: none;
}
/* The publish step is the one that takes real time, so while it is running it
   shows a ring rather than a box — the only spinner on the page. */
html.fe-bl-armed .fe-bl-steps li[data-publish].is-in:not(.is-done)::before {
    border-color: var(--accent);
    border-right-color: transparent;
    border-radius: 50%;
    animation: fe-spin .7s linear infinite;
}
@keyframes fe-spin { to { transform: translateY(2px) rotate(360deg); } }

/* The live line is the payoff: a green dot, not a tick. */
.fe-bl-steps li[data-live] { color: var(--good); font-weight: 600; }
.fe-bl-steps li[data-live]::before {
    width: 8px; height: 8px;
    border-radius: 50%;
    border: 0;
    background: var(--good);
    background-image: none;
    transform: translateY(-1px);
    box-shadow: 0 0 0 3px rgba(74, 222, 128, .16);
}
html.fe-bl-armed .fe-bl-steps li[data-live].is-done { color: var(--good); }
html.fe-bl-armed .fe-bl-steps li[data-live]:not(.is-done)::before {
    background: var(--good);
    border: 0;
}

/* The Live badge in the chrome only appears once the build reaches its live
   step, so the frame never claims a site is up before it says so. */
.fe-chrome .fe-chrome-live { opacity: 1; transition: opacity .3s ease; }
html.fe-bl-armed .fe-chrome .fe-chrome-live { opacity: 0; }
html.fe-bl-armed .fe-chrome .fe-chrome-live.is-on { opacity: 1; }

.fe-bl-preview {
    padding: 12px;
    min-width: 0;
    border-top: 1px solid rgba(255, 255, 255, .06);
}
@media (min-width: 640px) {
    .fe-bl-preview {
        border-top: 0;
        border-left: 1px solid rgba(255, 255, 255, .06);
    }
}

/* --- the miniature site ---
   A real layout at ~1/6 scale: header, hero, cards, footer band. Every colour
   is a custom property set on .fe-mini by the template, so one block of CSS
   renders every palette and adding a fourth mini-site is three variables. */
.fe-mini {
    height: 224px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 6px;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .08);
    background: var(--m-bg, #fff);
    transition: background-color .4s ease;
}
/* ⚠ THE HIDDEN STATE IS ARMED BY JS, NOT BY THIS FILE.
   `html.fe-bl-armed` is added by fe-stage.js only once it has confirmed it
   can also REMOVE the hidden state — i.e. that IntersectionObserver exists
   and reduced motion is not requested. Without it these rules never match and
   the frame ships fully assembled.

   This was got wrong the first time and caught by screenshotting the page
   with JavaScript disabled: the steps list rendered empty and the mini-site
   was a blank coloured box. CSS that hides content plus JS that reveals it is
   the single most common way to serve a crawler a blank page, and this
   component sits above the fold on the page that has to rank.

   Also scoped to [data-buildloop] because `_mini.html` is reused as a
   static illustration in the range strip, where nothing would ever reveal it. */
html.fe-bl-armed [data-buildloop] .fe-mini > * {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .34s ease, transform .34s ease;
}
html.fe-bl-armed [data-buildloop] .fe-mini > .is-in { opacity: 1; transform: none; }

.fe-mini-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--m-fg) 10%, transparent);
}
.fe-mini-nav span:first-child {
    font-size: 8px;
    font-weight: 800;
    letter-spacing: .02em;
    color: var(--m-fg);
}
.fe-mini-nav em {
    font-style: normal;
    font-size: 6px;
    font-weight: 600;
    color: color-mix(in srgb, var(--m-fg) 75%, transparent);
    margin-left: 6px;
}
.fe-mini-nav i {
    display: inline-block;
    width: 22px; height: 8px;
    border-radius: 999px;
    background: var(--m-accent);
    margin-left: 6px;
    vertical-align: middle;
}

.fe-mini-hero {
    display: flex;
    gap: 10px;
    align-items: stretch;
    padding: 8px 10px;
    background: linear-gradient(color-mix(in srgb, var(--m-accent) 16%, transparent), transparent);
}
.fe-mini-hero > div { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.fe-mini-h {
    font-size: 11px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.01em;
    color: var(--m-fg);
}
.fe-mini-p {
    font-size: 6.5px;
    line-height: 1.35;
    color: color-mix(in srgb, var(--m-fg) 70%, transparent);
}
.fe-mini-cta {
    display: inline-flex;
    align-items: center;
    height: 13px;
    padding: 0 8px;
    border-radius: 3px;
    font-size: 6.5px;
    font-weight: 700;
    background: var(--m-accent);
    color: var(--m-on-accent, #fff);
}
/* The image block. A gradient wash plus one glyph — the same thing
   tenants/art.py draws at full size, which is why it can stand in for it. */
.fe-mini-art {
    flex: none;
    width: 76px;
    border-radius: 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, .78);
    background:
        radial-gradient(80% 90% at 25% 15%, rgba(255, 255, 255, .28), transparent 55%),
        linear-gradient(150deg, var(--m-accent), color-mix(in srgb, var(--m-fg) 55%, transparent));
}

.fe-mini-rows { flex: 1 1 auto; min-height: 0; padding: 6px 10px; display: flex; flex-direction: column; gap: 5px; }
.fe-mini-row {
    display: flex;
    align-items: baseline;
    gap: 5px;
    font-size: 6.5px;
    color: var(--m-fg);
}
.fe-mini-row span:first-child { font-weight: 600; }
.fe-mini-row i {
    flex: 1 1 auto;
    border-bottom: 1px dotted color-mix(in srgb, var(--m-fg) 26%, transparent);
    transform: translateY(-2px);
}
.fe-mini-row b { font-weight: 700; color: var(--m-accent); font-size: 6.5px; }

.fe-mini-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px 10px;
    background: var(--m-foot, var(--m-fg));
}
/* The footer band is painted in the palette's FOREGROUND, so its text has to
   be the palette's BACKGROUND — not white. On a light palette (paper, sky)
   fg is near-black and white text reads fine, which is why this was missed;
   on a dark one (ember, forest, orchid) fg is a light cream and white-on-cream
   is invisible. Keying both to --m-bg is correct for every palette by
   construction: bg and fg are the pair `tenants/tokens.py` already guarantees
   clears AA against each other. */
.fe-mini-foot span {
    font-size: 5.5px;
    font-weight: 700;
    color: var(--m-bg);
}
.fe-mini-foot i {
    display: inline-block;
    width: 16px; height: 3px;
    border-radius: 999px;
    background: var(--m-bg);
    opacity: .4;
    margin-left: 5px;
}

/* --- the three steps under the frame ---
   ⚠ SPECIFICITY. `firstemployee.css:510` carries

       body.fe-dark .fe-col ol:not(.fe-walk) { display: inline-block; ... }

   which scores (0,3,2) — the `:not()` argument counts as a class. A plain
   `.fe-walk3 { display:flex }` is (0,1,0) and loses, which is exactly the
   regression CLAUDE.md records against `.fe-steps3 ol` (three steps stacked at
   every width for a week). The selectors below are written at (0,4,2) — one
   class more than the rule they have to beat — so this cannot be re-broken by
   someone reordering the stylesheets. Do not "simplify" them back down. */
body.fe-dark .fe-col ol.fe-walk3.fe-walk3 {
    list-style: none;
    margin: 30px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: none;
    text-align: left;
}
@media (min-width: 640px) {
    body.fe-dark .fe-col ol.fe-walk3.fe-walk3 {
        flex-direction: row;
        justify-content: center;
        align-items: center;
        gap: 56px;
    }
}
.fe-walk3 li { display: flex; align-items: center; gap: 10px; }
.fe-walk3 li > span:first-child {
    flex: none;
    width: 24px; height: 24px;
    display: grid;
    place-items: center;
    border-radius: 7px;
    border: 1px solid;
    font-size: 13px;
    font-weight: 700;
    font-family: var(--mono);
}
.fe-walk3 li:nth-child(1) > span:first-child { color: var(--accent); border-color: rgba(108, 140, 255, .45); }
.fe-walk3 li:nth-child(2) > span:first-child { color: var(--violet); border-color: rgba(167, 139, 250, .45); }
.fe-walk3 li:nth-child(3) > span:first-child { color: var(--cyan);   border-color: rgba(34, 211, 238, .45); }
.fe-walk3 li > span:last-child { font-size: .9rem; font-weight: 600; color: var(--text); }

/* ⚠ THE HERO NO LONGER OWNS THE WHOLE FIRST SCREEN.
   fe-landing.css sets `.fe-stage-hero { min-height: 100svh }`, and the
   reasoning behind it (2026-08-02) was sound for the page as it then was: the
   thing below the fold was a replay terminal, and the hero had to stop it
   peeking over the edge and competing for attention.

   That reasoning inverted the day the build loop went in. What is under the
   fold now is the single most persuasive thing on the site — a real founding
   build running, business after business — and a full-viewport hero means
   nobody sees it without deciding to scroll first. A competitor's frame is on
   screen at 1440x900 without touching the mouse; ours was 900px down.

   So the hero is sized by its content plus breathing room, and the frame is
   pulled up to sit just under the fold line: visible on a laptop, and the
   scroll cue points straight at it.

   Specificity: (0,3,2) against fe-landing's (0,1,1), so no !important. */
body.fe-dark .fe-stage.fe-stage-hero {
    min-height: 0;
    padding-block: 2.6rem 1.2rem;
}
/* The scroll cue was `margin: auto 0 0` so it pinned to the bottom of a
   full-height hero. With the hero no longer full height that auto margin does
   nothing useful and just adds a gap. */
body.fe-dark .fe-stage-hero .fe-stage-down {
    margin: 0;
    padding-top: 1.6rem;
}

/* The live-example line sits under the loop and has to read as its caption,
   so it is centred with it. It was a left-aligned `.fe-egline` inside the old
   "How it works" section, where left was right; moved under a centred frame it
   read as a stray link floating at the page's left rail. */
body.fe-dark .fe-egline {
    text-align: center;
    margin: 1.1rem auto 0;
}

/* Section rhythm. The greyscale page ran everything at the same interval and
   the result was a scroll with no joints in it — you could not tell where one
   argument stopped and the next began. These two get real air because they
   are the pair that carries the whole pitch. */
.fe-buildstage { margin-block: 1.6rem 0; }
.fe-range { margin-block: 5.5rem 0; }
.fe-range .fe-lead { margin-inline: auto; max-width: 46rem; }

/* ==========================================================================
   4b. THE RANGE STRIP
   Three mini-sites side by side in three different palettes. The single job
   of this section is to kill "every site it builds looks the same" on sight,
   so the three have to be visible AT ONCE — a carousel or a tabbed switcher
   would show one at a time and prove nothing. On a phone they stack, which
   still reads as three, because they are three different colours in a row.
   ========================================================================== */
.fe-range-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px;
    margin-block: 26px 14px;
}
@media (min-width: 720px) {
    .fe-range-grid { grid-template-columns: repeat(3, 1fr); }
}
.fe-range-card {
    margin: 0;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--bg-2);
    overflow: hidden;
    transition: transform .25s ease, border-color .25s ease;
}
.fe-range-card:hover {
    transform: translateY(-3px);
    border-color: rgba(255, 255, 255, .2);
}
/* The mini fills the card below the chrome; it keeps its own 224px so all
   three cards are the same height regardless of how much copy each carries. */
.fe-range-card .fe-mini { border-radius: 0; box-shadow: none; }
/* Three cards across a 1180px rail leaves ~360px each, and a full tenant
   hostname is ~28 characters. At the frame's default 11.5px it was landing
   one character short and ellipsing — which truncates the ".app" and so
   destroys the only thing the address bar is there to say. Dropping to 10.5px
   and trimming the padding buys the room without shrinking the card. */
.fe-range-card .fe-chrome { padding: 8px 11px; gap: 6px; }
.fe-range-card .fe-chrome b { margin-left: 5px; padding: 3px 9px; font-size: 10.5px; }

/* ==========================================================================
   5. PROOF: screenshots in chrome, and the section rhythm
   ========================================================================== */

/* Every real capture gets a frame — and, since 2026-08-25, gets INSET inside
   it rather than filling it.

   THE BUG THIS FIXES. The signed-in product is light and stays light
   (ZERO_TO_ONE_PLAN §15.4), so `shift-report.png` and `receipts.png` are
   screenshots of a white app. Dropped full-bleed at 940px onto a near-black
   page they stopped reading as screenshots and started reading as three
   blank white slabs punched through the design — which is exactly what they
   looked like when the whole page was viewed at once, and the reason this
   was missed is that it was only ever checked one 900px viewport at a time.

   Three things fix it, and all three are on the frame, never on the image:
     1. Padding, so the dark card is visibly BEHIND the shot on every side.
     2. A chrome bar, so the white rectangle is obviously an application
        window rather than a hole.
     3. A height cap with `object-position: top`, so a 1830px-tall capture is
        a window onto the app instead of a full-page dump. It also takes a
        large amount of dead scroll out of the page.

   The <picture> markup is untouched, so the art-directed pair and the
   width/height attributes core/test_landing.py reads still work exactly as
   before — the cap is presentational only and the reserved box is unchanged. */
body.fe-dark .fe-shot {
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--bg-2);
    overflow: hidden;
    margin-block: 1.8rem;
    padding: 0 10px 10px;
}
/* The chrome bar. Drawn on the figure with ::before so it needs no markup
   change and cannot desynchronise from the shot it belongs to. */
body.fe-dark .fe-shot::before {
    content: "";
    display: block;
    height: 30px;
    margin: 0 -10px 10px;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
    background-image:
        radial-gradient(circle, rgba(108, 140, 255, .55) 4px, transparent 4.5px),
        radial-gradient(circle, rgba(167, 139, 250, .55) 4px, transparent 4.5px),
        radial-gradient(circle, rgba(34, 211, 238, .55) 4px, transparent 4.5px);
    background-repeat: no-repeat;
    background-position: 16px center, 30px center, 44px center;
}
body.fe-dark .fe-shot img {
    display: block;
    width: 100%;
    height: auto;
    /* The window. Tall captures are cropped from the top, which is where the
       thing the shot exists to prove always is. */
    max-height: 460px;
    object-fit: cover;
    object-position: top center;
    border-radius: 8px;
}
body.fe-dark .fe-shot figcaption {
    padding: 11px 6px 2px;
    margin-top: 10px;
    border-top: 1px solid var(--line);
    color: var(--text-faint);
    font-size: .87rem;
}
body.fe-dark .fe-shot figcaption a { color: var(--accent); }

body.fe-dark .fe-card {
    background: var(--bg-2);
    border-color: var(--line);
}
body.fe-dark .fe-quiet {
    background: var(--accent-wash);
    border-color: rgba(108, 140, 255, .28);
    color: var(--text-dim);
}
body.fe-dark .fe-foot {
    background: transparent;
    border-top-color: var(--line);
}
body.fe-dark .fe-foot a { color: rgba(255, 255, 255, .6); }
body.fe-dark .fe-foot a:hover { color: #fff; }

/* A sub-heading inside a section. Used where a distinct promise lives inside
   a larger argument — the "what is switched on, and what is not" list inside
   the capability section. Sized between h2 and body so it reads as a real
   division, not as a bold paragraph. */
.fe-sub-h {
    margin: 3rem 0 .4rem;
    padding-top: 2rem;
    border-top: 1px solid var(--line);
    font-family: var(--display);
    font-size: 1.3rem;
    letter-spacing: -.015em;
    color: var(--text);
}

/* An eyebrow above a section heading. Small, accent, uppercase — it does the
   job the old grey lead paragraph was doing (telling you what this section
   is) in four words instead of thirty. */
.fe-eyebrow {
    margin: 0 0 10px;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--accent);
}

/* --- the hard-coded near-blacks -------------------------------------------
   Most of firstemployee.css runs on `var(--text)` and therefore inverted for
   free when §1 re-pointed the tokens. Eight rules do not: they were written
   with the literal `#0B0B0C` before the vars existed. On a dark canvas that
   is black-on-black — the /pricing/ and /receipts/ headlines were invisible
   the moment the skin went site-wide, which is exactly the class of bug that
   only shows up on the pages you did not open.

   Every one of those eight is listed here. `h1, h2, h3, h4` is the one that
   matters most: it is a bare ELEMENT selector, so it applies on every page
   including ones with no `.fe-col` and no `.fe-stage` wrapper, and it is the
   reason this cannot be fixed by styling the two containers.

   Two things NOT done here, deliberately:
   - Not edited in firstemployee.css. That file is shared with the signed-in
     app, which is still light, and #0B0B0C is correct there.
   - Not `!important`. Each of these adds `body.fe-dark` to a selector
     that had at most two classes, so specificity alone settles it. If a rule
     below ever stops winning, the fix is to check what gained specificity —
     not to reach for the hammer. */
body.fe-dark h1,
body.fe-dark h2,
body.fe-dark h3,
body.fe-dark h4,
body.fe-dark h5,
body.fe-dark h6 { color: var(--text); }
body.fe-dark .fe-faq > summary { color: var(--text); }
body.fe-dark .fe-faq > summary::before { color: var(--accent); }
body.fe-dark .fe-vs tbody th,
body.fe-dark .fe-shift-headline,
body.fe-dark .fe-ask-q { color: var(--text); }
body.fe-dark .fe-nav a.fe-navlink:hover,
body.fe-dark .fe-nav a.fe-navlink.is-active,
body.fe-dark .fe-brand:hover,
body.fe-dark .fe-btn:hover,
body.fe-dark .fe-foot a:hover { color: #fff; }
body.fe-dark .fe-receipts tr:hover td { background: rgba(255, 255, 255, .03); }

/* Bootstrap's own light-surface buttons and form controls. The vendor sheet
   paints `#fff` backgrounds directly, so they arrive as white slabs. */
body.fe-dark .btn-outline-secondary,
body.fe-dark .btn-secondary,
body.fe-dark .btn-light {
    background: transparent;
    border-color: var(--line-2);
    color: var(--text);
}
body.fe-dark .btn-outline-secondary:hover,
body.fe-dark .btn-secondary:hover,
body.fe-dark .btn-light:hover {
    background: rgba(255, 255, 255, .06);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}
/* `--bs-heading-color` is Bootstrap's own variable and it wins on `.h1`-style
   utility classes, which the element rule above does not cover. */
body.fe-dark { --bs-heading-color: var(--text); --bs-body-color: var(--text-dim); }

/* --- the last light components, found by `manage.py check_ui` ------------
   These four are the whole remaining tail after the surface went dark
   product-wide, and every one of them is a rule written in firstemployee.css
   or Bootstrap for a white page. They are listed individually rather than
   swept with a wildcard so that adding a fifth is a deliberate act. */

/* Bootstrap's table header inherits `--bs-table-bg`, which is white. It shows
   up as three solid white bars across the billing history on /account/ and
   /verify/ — the single most jarring thing left in the signed-in product. */
body.fe-dark table,
body.fe-dark .table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text);
    --bs-table-striped-bg: rgba(255, 255, 255, .03);
    --bs-table-striped-color: var(--text);
    --bs-table-border-color: var(--line);
    color: var(--text);
}
body.fe-dark th,
body.fe-dark td { background-color: transparent; border-color: var(--line); }
body.fe-dark thead th { color: var(--text-faint); }

/* The danger buttons. `.btn-danger` and `.btn-outline-danger` are painted
   white-with-red-text by firstemployee.css (correct on paper, a white slab on
   ink). They keep the red — destructive actions must stay legible as
   destructive — and lose the fill. */
body.fe-dark .btn-danger,
body.fe-dark .btn-outline-danger {
    background: transparent;
    border-color: rgba(248, 113, 113, .45);
    color: var(--bad);
}
body.fe-dark .btn-danger:hover,
body.fe-dark .btn-outline-danger:hover {
    background: rgba(248, 113, 113, .12);
    border-color: var(--bad);
    color: var(--bad);
}

/* A bare <input> with no `.form-control` — the contact page's captcha field.
   The typed rule above only reaches inputs Bootstrap has classed. */
body.fe-dark input:not([type=checkbox]):not([type=radio]):not([type=submit]),
body.fe-dark select,
body.fe-dark textarea {
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .14);
    color: var(--text);
}
body.fe-dark input::placeholder,
body.fe-dark textarea::placeholder { color: rgba(255, 255, 255, .5); }

/* --- the build feed (fe-feed.css) ----------------------------------------
   `.fe-now` — the live "what it is doing right now" line on a running build —
   is painted `var(--paper-2, #FBFAF8)`, and `--paper-2` is defined in NO
   stylesheet in this project. So it has always used its fallback: a near-white
   box. On the old light app that was invisible; on ink it is a white slab in
   the middle of the build, and it is the first thing a new user watches.

   It also leaked into the landing page, because `manage.py landing_shots`
   photographs this exact screen for `build-feed.png`.

   Defining the variable rather than overriding the rule, so anything else in
   that sheet reaching for it lands somewhere sensible too. */
body.fe-dark {
    --paper: var(--bg);
    --paper-2: var(--bg-2);
    --ink: var(--text);
}

/* Links in prose. `--accent` is the anchor and clears 7.4:1 on the canvas. */
body.fe-dark .fe-col a { color: var(--accent); }
body.fe-dark .fe-col a:hover { color: var(--accent-hi); }
/* ...but not the ones that are already styled as something other than a link. */
body.fe-dark .fe-col a.fe-btn,
body.fe-dark .fe-col a.fe-btn-primary { color: #fff; }

/* ==========================================================================
   6. SCROLL REVEAL
   One transition, applied by JS only after it has confirmed
   IntersectionObserver exists. The un-revealed state is therefore never
   painted for a browser that cannot un-paint it: `.fe-rise` on its own does
   nothing, and JS adds `.fe-rise-armed` to the <html> element before the
   observer starts. No JS → everything is simply visible.
   ========================================================================== */
html.fe-rise-armed .fe-rise {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .55s cubic-bezier(.22, 1, .36, 1),
                transform .55s cubic-bezier(.22, 1, .36, 1);
}
html.fe-rise-armed .fe-rise.is-in { opacity: 1; transform: none; }

/* ==========================================================================
   7. REDUCED MOTION
   Everything above that moves is listed here, and the rule is "show the end
   state", never "hide the element". A reader who asks for no motion still
   gets the whole page — the mini-site fully assembled, every step ticked,
   the headline holding one word. fe-stage.js checks the same media query and
   does not start its timers, so this is belt and braces rather than the only
   defence.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .fe-rot { transition: none; }
    .fe-rot-word { transition: none; }
    .fe-rot-word.is-out { opacity: 1; filter: none; }
    [data-buildloop] .fe-mini > *,
    .fe-bl-steps li { opacity: 1 !important; transform: none !important; transition: none; }
    html.fe-rise-armed .fe-rise { opacity: 1; transform: none; transition: none; }
    body.fe-dark .fe-nav { transition: none; }
}
