/* ─────────────────────────────────────────────────────────────────────────────
   FLoCK subdomain — dark, hairline-ruled product, access and pricing pages.

   Paired with resources/views/pages/flock/.

   WHAT IS LEFT HERE. This sheet used to carry the whole design system. The apex
   now uses the same system, so everything that was not specific to these three
   pages moved to public/css/fx.css under a .fx-site scope — the shell, the type
   scale, the capability rows, the buttons, the facts strip, the CTA band, the
   nav, the footer and the brief components. What remains is genuinely FLoCK's:
   the video hero, the canvas stages, the tier columns, the comparison matrix
   and the offer form.

   The tokens moved too, to :root in main.css. Nothing here declares one.

   LOAD ORDER AND SCOPE. The pages carry BOTH classes on the wrapper —
   `.content flock-site fx-site` — so fx.css styles them and this sheet, loading
   after it, overrides where FLoCK differs. A rule here scoped `.flock-site X`
   has the same specificity as fx.css's `.fx-site X`, so the ordering is what
   decides it; that is deliberate and is why head.blade.php loads fx.css first.

   These pages also load main.css, flock/main.css and flock/subdomain.css, which
   are the light styling the three-tab shell left behind — this sheet loads last
   and overrides the parts of it that still show. The pricing here is .fx-tier-*
   and .fx-matrix-*, never .pricing-*: those names belonged to
   product_cards.css, deleted with the tab shell.

   The design: no cards, no shadows, no fills. Separation is a 1px rule and
   space. Type carries the hierarchy — a small uppercase label above a large
   light heading above quiet body copy.
   ────────────────────────────────────────────────────────────────────────── */


/* The comparison matrix scrolls inside its own container, and that container
   clips correctly — but Chromium still counts the table's full 640px in
   documentElement.scrollWidth, which leaves a strip of empty page a user can
   swipe into. main.css only guards this under 768px; this closes it at every
   width. `clip` rather than `hidden` so no scroll container is created and the
   sticky matrix header keeps working.

   Scoped to .flock-site rather than declared on .fx-site in fx.css: the apex
   has no table like this, and its wrapper is a <main> with fixed overlays
   inside it that a clipping ancestor can disturb. */
.flock-site {
    overflow-x: clip;
}

/* ─── Hero: the parallax, on both clips ────────────────────────────────────
   All that is left here of the hero — fx.css owns the rest of it, including
   --fx-hero-travel, which this block reads.

   It stays because it is the one part that is not generic: subdomain.css drives
   the desktop clip from a view() timeline it names on .banner, and its keyframes
   are written for a full-viewport hero. Re-pointing animation-name at a local
   set is the only way to retune the amplitude without editing that shared file.
   The apex hero is a still image and has no timeline to retune.

   THE PHONE'S CLIP IS DECLARED IN FULL, not just retuned, because subdomain.css
   predates it and names nothing on .banner-video-mobile. It is not decoration
   either way: fx.css sizes EVERY hero medium to 100vh + 2 × travel and pulls it
   up by one travel, so with no animation to spend that on, the phone's clip sat
   permanently 12vh high in its own frame, the bottom 12vh of the file cropped
   off and nothing moving. The <img> this replaced had the same problem and it
   was just as invisible there. Either the sizing goes or the animation arrives;
   the animation is what the desktop already does.

   motion.js is not a factor on either: it skips any .banner containing a
   <video>, which this one has had since long before the phone got its own. */
@supports (animation-timeline: view()) {
    .flock-site .banner-video {
        animation-name: fx-hero-parallax;
    }

    .flock-site .banner-video-mobile {
        animation: fx-hero-parallax linear both;
        /* Named rather than a bare view(): the timeline is .banner's own box,
           never the clip's transformed one. subdomain.css declares it. */
        animation-timeline: --flock-hero;
        animation-range: cover 0% cover 100%;
    }

    @keyframes fx-hero-parallax {
        from { transform: translate3d(0, calc(var(--fx-hero-travel) * -1), 0); }
        to   { transform: translate3d(0, var(--fx-hero-travel), 0); }
    }

    /* motion.js clears its transforms under reduced motion; match that here.
       flock-loader.js already declines to attach either clip's sources in that
       case, so what stays still is the poster. */
    @media (prefers-reduced-motion: reduce) {
        .flock-site .banner-video,
        .flock-site .banner-video-mobile {
            animation: none;
        }
    }
}


/* subdomain.css turns .catalog-canvas into a COLUMN only for the two live modes
   it knows by name — `[data-canvas-mode="scope"], [data-canvas-mode="watcher"]`.
   The experiment's scenes are marked data-fx-scene, so without this their rails
   land BESIDE the tree instead of above or below it, which is exactly what the
   first render did. */
.catalog-canvas[data-fx-scene] {
    flex-direction: column;
}

/* Matching the --owners / --events borders subdomain.css already defines: a
   rail above the tree closes with a bottom edge, one below with a top edge. */
.canvas-rail--filters,
.canvas-rail--viewers {
    border-bottom: 1px solid rgb(55 65 81);
}

/* flock/main.css sizes .docker from the .deploy grid it normally sits in;
   inside the frame it has to carry its own height. */
/* subdomain.css sets `.docker.docker--stage { min-height: 500px }` — cleared
   for the tallest of the live modes' reserves (490, the catalog mode's random
   worst case). min-height outranks height, so the frame here stayed 500px
   whatever it was told, and the experiment's scenes reserve 300-320. Measured,
   that left 286px of empty grid around a 215px tree.

   So: drop the floor, and set the frame to the scene's reserve plus its rail.
   The selector carries an extra class to outrank (0,2,0). */
.flock-site .fx-stage .docker.docker--stage {
    min-height: 0;
    height: 380px;
    border: none;
}

@media (max-width: 768px) {
    .flock-site .fx-stage .docker.docker--stage {
        height: 330px;
    }
}

/* ─── Pricing: tier columns ────────────────────────────────────────────────
   Three columns divided by vertical rules. No borders around them, no lift on
   hover, no shadow — a card would reintroduce exactly the weight this layout
   is trying to shed. */

.fx-tiers {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    border-top: 1px solid var(--fx-rule);
}

.fx-tier {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    /* 22px, down from 32: at four columns in the 1180px measure each column is
       295px, and 64px of side padding left a 231px feature list that broke
       nearly every line in two. */
    padding: 40px 22px;
    border-left: 1px solid var(--fx-rule);
}

.fx-tier:first-child {
    border-left: none;
    padding-left: 0;
}

.fx-tier:last-child {
    padding-right: 0;
}

/* The featured tier: an accent rule along the top edge, and a wash beneath it
   that fades out within the first third of the column. Enough to pull the eye
   without the column becoming a card — it still does not move, grow or glow. */
.fx-tier--featured {
    box-shadow: inset 0 2px 0 0 var(--fx-accent);
    background-image: linear-gradient(to bottom,
        rgba(77, 124, 255, 0.07) 0%,
        rgba(77, 124, 255, 0) 38%);
}

.fx-tier--featured .fx-tier-name {
    color: var(--fx-accent);
}

.fx-tier-name {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--fx-fg);
}

.fx-tier-badge {
    display: inline-block;
    margin-left: 10px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fx-accent);
    vertical-align: 1px;
}

.flock-site .fx-tier-tagline {
    margin: 14px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--fx-label);
    /* Reserves two lines, so a tier whose tagline wraps keeps its price on the
       same baseline as the ones whose tagline does not. */
    min-height: 48px;
}

.fx-tier-price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin: 32px 0;
    padding-bottom: 32px;
    border-bottom: 1px solid var(--fx-rule);
}

.fx-tier-amount {
    /* 38px, down from 44: "€2 299" at 44px no longer cleared a four-column
       track with its "from" and "/ month" qualifiers on the same baseline. */
    font-size: 38px;
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--fx-fg);
}

/* A quoted tier's figure slot holds a phrase, not an amount. Set at the size
   the phrase wants rather than the size a number wants — "On request" in 38px
   display type reads as shouting, and in this column it would also wrap. */
.fx-tier-amount--quoted {
    font-size: 24px;
    letter-spacing: -0.01em;
}

/* Baseline strut.
   `align-items: baseline` aligns items to each other WITHIN one flex line, and
   each tier column is its own flex container — so a quoted column, whose only
   item is a 24px phrase, had nothing to align against and sat 12px above the
   38px figures in the columns beside it. Matching line-heights by hand does not
   fix it either: half-leading re-centres the smaller glyph in the taller box,
   which is how it ended up 5px out in the other direction.

   This gives every price row a second, zero-width item carrying the FIGURES'
   metrics. The real text then baseline-aligns to it, priced or quoted, with no
   number tuned to a particular font. The negative margin cancels the flex gap
   the extra item would otherwise introduce.

   A zero-width SPACE, not an empty string: flex blockifies ::before, and a
   block with no text has no line box and therefore no baseline — flex then
   synthesises one from its bottom edge and the alignment silently does nothing.
   The character generates the line box; it has no advance width, so it shows
   nothing and measures nothing. */
.fx-tier-price::before {
    content: "\200B";
    font-size: 38px;
    line-height: 1;
    margin-right: -8px;
}

.fx-tier-qual {
    font-size: 13px;
    color: var(--fx-label);
}

.fx-tier-features {
    flex: 1 1 auto;
    list-style: none;
    margin: 0 0 32px;
    padding: 0;
}

.fx-tier-features li {
    padding: 11px 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--fx-muted);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.fx-tier-features li:last-child {
    border-bottom: none;
}

/* The inheritance line ("Everything in TEAM, plus:") is a heading for the rows
   under it, not a feature — so it reads as one. */
.fx-tier-features li.fx-tier-inherits {
    color: var(--fx-label);
    font-style: italic;
    border-bottom-color: var(--fx-rule);
}

.fx-tier .fx-btn {
    margin-top: auto;
}

/* ─── Pricing: comparison matrix ───────────────────────────────────────────
   A real table. The container scrolls, never the page — three tier columns plus
   a feature column cannot compress below about 640px and stay legible. */

.fx-matrix-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

/* The phone plan picker. Hidden here and switched on in the phone block at the
   end of this sheet — above that width all four columns are on screen, which is
   what a comparison table is for, and a switcher would only hide three of
   them. */
.fx-plan-pick {
    display: none;
}

.fx-matrix {
    width: 100%;
    /* 760, up from 640: one label column plus FOUR tier columns. At the old
       width the fourth tier squeezed the feature labels into three lines each. */
    min-width: 760px;
    border-collapse: collapse;
    font-size: 14px;
}

.fx-matrix th,
.fx-matrix td {
    padding: 16px 20px;
    text-align: left;
    border-bottom: 1px solid var(--fx-rule);
    vertical-align: middle;
}

.fx-matrix thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    /* Opaque: rows scroll under this. */
    background: var(--fx-bg);
    border-bottom-color: var(--fx-rule-strong);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--fx-fg);
}

.fx-matrix thead th.fx-matrix-featured {
    color: var(--fx-accent);
    /* Opaque, because the sticky header has rows passing under it: this is
       --fx-bg with the featured wash already composited in, not layered over. */
    background: #0e1016;
    box-shadow: inset 0 2px 0 0 var(--fx-accent);
}

/* The featured column, all the way down.
   It used to be marked only in the header and on its ticks, so the eye had
   nothing to follow through twenty-eight rows and kept having to go back up to
   check which column it was reading. A continuous wash is the same thing the
   featured TIER COLUMN and the callouts already do — one grammar for "this is
   the one we mean", used in three places. */
.fx-matrix tbody td.fx-matrix-featured {
    background: rgba(77, 124, 255, 0.05);
}

.fx-matrix th.fx-matrix-cell,
.fx-matrix td.fx-matrix-cell {
    width: 132px;
    text-align: center;
    /* Hairlines between the tier columns, lighter than --fx-rule so the table
       still reads as rows first. Without them four columns of centred ticks
       drift apart at this width and the eye loses which one it is in. */
    border-left: 1px solid rgba(255, 255, 255, 0.055);
}

.fx-matrix tbody th {
    font-weight: 400;
    /* Brighter than --fx-muted: this column is the one actually being READ.
       The tier cells answer it, and they are brighter still. */
    color: rgba(255, 255, 255, 0.8);
}

/* The first column pins horizontally. The table scrolls sideways on a narrow
   screen, and a tick with its label scrolled off is unreadable — this is the
   difference between a comparison table and three columns of ticks.
   Opaque, because rows pass underneath it. */
.fx-matrix th:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--fx-bg);
}

.fx-matrix thead th:first-child {
    /* Corner cell: sticky in both directions, so it has to outrank both. */
    z-index: 3;
}

/* A hairline on its trailing edge, so the pinned column reads as pinned once
   the tiers start sliding under it. */
.fx-matrix tbody th:first-child::after,
.fx-matrix thead th:first-child::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 1px;
    background: var(--fx-rule);
}

/* Group heading rows — the subject the block beneath is about.
   A band rather than a row: it spans every column, carries its own ground, and
   closes on the strong rule, so six subjects are findable by scanning a long
   table instead of reading it. */
.fx-matrix tbody tr.fx-matrix-group th {
    padding: 34px 20px 14px;
    background: rgba(255, 255, 255, 0.022);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--fx-fg);
    border-bottom-color: var(--fx-rule-strong);
}

/* The band spans the table, so the pinned first column must not paint its own
   opaque ground over it — that left a dark notch at the start of every heading.
   It also has nothing to pin against: there is only one cell in the row. */
.fx-matrix tbody tr.fx-matrix-group th:first-child {
    position: static;
    background: rgba(255, 255, 255, 0.022);
}

.fx-matrix tbody tr.fx-matrix-group th:first-child::after {
    display: none;
}

/* A short accent rule before the name, so the blocks are findable at a glance. */
.fx-matrix tbody tr.fx-matrix-group th::before {
    content: "";
    display: inline-block;
    width: 14px;
    height: 2px;
    margin-right: 10px;
    vertical-align: middle;
    background: var(--fx-accent);
}

/* The price row is the one line every reader came for. */
.fx-matrix tbody tr.fx-matrix-price td {
    padding-top: 22px;
    padding-bottom: 22px;
    font-size: 17px;
    color: var(--fx-fg);
}

.fx-matrix tbody tr.fx-matrix-price .fx-tier-qual {
    font-size: 12px;
}

/* Same treatment as the generic table: a brightened rule rather than a wash.
   It earns more here than anywhere else — tracking one feature across three
   tier columns is exactly what a ruler is for. Pointer devices only. */
@media (hover: hover) {
    .fx-matrix tbody th,
    .fx-matrix tbody td {
        transition: color 0.15s ease, border-color 0.15s ease;
    }

    .fx-matrix tbody tr:not(.fx-matrix-group):hover th,
    .fx-matrix tbody tr:not(.fx-matrix-group):hover td {
        border-bottom-color: var(--fx-rule-strong);
        color: var(--fx-fg);
    }
}

/* A cell holding a count, a limit or an add-on price instead of a tick. Set at
   the row's own size rather than the tick's, and in full-strength foreground —
   it is the answer to the row, not a qualifier on it. Add-on prices wrap in a
   74px column, so they are allowed to. */
.fx-matrix-value {
    display: inline-block;
    font-size: 13px;
    line-height: 1.35;
    color: var(--fx-fg);
}

/* The masked tick the deleted product_cards.css used, recoloured for the dark
   ground. */
.fx-tick {
    display: inline-block;
    width: 16px;
    height: 16px;
    background-color: var(--fx-fg);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") no-repeat center / contain;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") no-repeat center / contain;
}

.fx-matrix-featured .fx-tick {
    background-color: var(--fx-accent);
}

.fx-dash {
    /* Quiet, but it has to read as a deliberate "not included" rather than an
       empty cell. Dimmed a step further once the ticks and values gained a
       column wash to sit on — at 0.38 the dashes were competing with them, and
       a comparison table should be read for what you get. */
    color: rgba(255, 255, 255, 0.26);
}

/* The tick is a CSS mask, so its element has to stay empty — which would leave
   a screen reader hearing nothing in an included cell. This carries the glyph
   for assistive tech only. */
.fx-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ─── Offer form ───────────────────────────────────────────────────────────
   landing.css draws this form for the apex: a 520px box centred in its band,
   every field a filled rectangle — #1a1a1a ground, #2e2e2e border, 2px radius.
   That is a perfectly good form and it is the wrong one here. This page has no
   fills, no radii and no boxes; it separates things with a single hairline and
   lets type carry the hierarchy, so a centred stack of grey rectangles read as
   something pasted in from another site.

   Rebuilt in the page's own language, inventing nothing for it:

     · The band stays full width so its top rule spans the page like every other
       section's. The CONTENT sits at --fx-max in the same two columns the
       product and access rows use — the argument on the left, the thing itself
       on the right — rather than a centred column nothing else shares.
     · A field is a label over a bottom rule. No fill, no box, no radius. Focus
       brightens that rule to white, the same move the matrix rows and the nav
       links already make.
     · Submit takes .fx-btn--primary's treatment at full width, exactly like the
       tier CTAs above it.

   Every selector is .flock-site-scoped: landing.css and flock/subdomain.css own
   these class names for the apex forms and the old tab shell and must not
   change. This sheet loads after both.

   This works only because the section is NOT given the id 'offer-form':
   flock/main.css hangs a light-state block off that id, left over from the tab
   shell — see the shell's note on the include. */

.flock-site .offer-form-section {
    /* landing.css centres this as a flex column; the grid inside does the layout
       now, and `block` keeps the band a plain full-width strip. */
    display: block;
    padding: var(--fx-pad) 24px;
    background: var(--fx-bg);
    border-top: 1px solid var(--fx-rule);
}

.fx-offer {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 500px);
    gap: 80px;
    align-items: start;
    width: 100%;
    max-width: var(--fx-max);
    margin: 0 auto;
}

/* ── The argument, on the left ─────────────────────────────────────────────── */

.flock-site .offer-form-header {
    /* landing.css centres it and caps it with a 40px gap meant for a stacked
       layout. Here it is a column of its own. */
    text-align: left;
    margin-bottom: 0;
    max-width: 30ch;
}

.flock-site .offer-form-header h2 {
    margin: 0 0 14px;
    font-size: clamp(28px, 3.4vw, 46px);
    line-height: 1.08;
    font-weight: 400;
    color: var(--fx-fg);
}

.flock-site .offer-form-header p {
    margin: 0;
    font-size: clamp(15px, 1.4vw, 17px);
    line-height: 1.55;
    color: var(--fx-muted);
}

/* ── The fields, on the right ──────────────────────────────────────────────── */

.flock-site .offer-form-wrap {
    /* landing.css caps this at 520px for a centred layout; the grid track is the
       cap now. */
    max-width: none;
}

.flock-site .flock-offer-form,
.flock-site .offer-field-row {
    gap: 26px;
}

.flock-site .offer-field {
    gap: 0;
}

/* The field label is the page's micro-label pulled tight to its input —
   .fx-label's own 20px is sized for standing above a whole section. */
.flock-site .offer-field .fx-label {
    margin: 0 0 8px;
    transition: color 0.2s ease;
}

.flock-site .offer-field input,
.flock-site .offer-field select {
    /* background-COLOR, not the shorthand. The shorthand also resets
       background-repeat to `repeat`, and it outranks landing.css's no-repeat on
       the select — which tiled the dropdown arrow across the whole field. */
    background-color: transparent;
    border: none;
    border-bottom: 1px solid var(--fx-rule);
    border-radius: 0;
    padding: 9px 0;
    /* 16px, not 0.9rem: iOS zooms the viewport on focus for anything smaller,
       which on a form this far down the page is a jarring jump. */
    font-size: 16px;
    font-family: inherit;
    /* Stated on both, so the select and the inputs are the same height. A select
       takes its line-height from the UA stylesheet and an input does not, which
       left the country field a couple of pixels taller than the row above it. */
    line-height: 1.5;
    height: auto;
    color: var(--fx-fg);
    transition: border-color 0.2s ease;
}

.flock-site .offer-field input::placeholder {
    color: rgba(255, 255, 255, 0.3);
}

/* Focus: the rule steps up and the label comes out of grey. The same two moves
   a hovered table row and a hovered tier column make, so a live field reads the
   way everything else on the page reads.

   Deliberately NOT solid white, and deliberately not the --fx-accent ring the
   Focus block further down gives every other control: this field has no box, so
   a rectangle drawn 3px off it sits in empty space and points at nothing. The
   indicator is the field's own rule, which is the only edge it has.

   Still a visible focus indicator for keyboard users — a 24%-white rule and a
   white label against a near-black ground, where the resting state is a 12%
   rule and a 45% label. The override is scoped to these fields only; every
   other control on the page keeps its ring. */
.flock-site .offer-field input:hover,
.flock-site .offer-field select:hover {
    border-bottom-color: var(--fx-rule-strong);
}

.flock-site .offer-field input:focus,
.flock-site .offer-field select:focus {
    border-bottom-color: var(--fx-rule-strong);
    outline: none;
}

.flock-site .offer-field input:focus-visible,
.flock-site .offer-field select:focus-visible {
    outline: none;
}

/* The label is the other half of it. :focus-within, because the label is a
   sibling of the input rather than an ancestor — .offer-field is what both sit
   in. */
.flock-site .offer-field:focus-within .fx-label {
    color: var(--fx-fg);
}

.flock-site .offer-field input.input-error,
.flock-site .offer-field select.input-error {
    border-bottom-color: var(--fx-danger);
}

/* appearance:none (landing.css) removed the native arrow, so the sheet draws
   one. Flush right, because the field no longer has a box to be inset from. */
.flock-site .offer-field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23ffffff' fill-opacity='0.45'/%3E%3C/svg%3E");
    /* Restated rather than inherited from landing.css: the background-color
       above is a longhand now, but keeping this next to the image it governs is
       what stops the next edit re-tiling it. */
    background-repeat: no-repeat;
    background-position: right 2px center;
    padding-right: 26px;
    cursor: pointer;
}

.flock-site .offer-field select option {
    /* The open dropdown is painted by the OS, not the page: on a transparent
       select these inherit white-on-white in most browsers. */
    background: #141414;
    color: var(--fx-fg);
}

/* ── Terms ─────────────────────────────────────────────────────────────────── */

.flock-site .offer-terms {
    gap: 14px;
    margin-top: 2px;
    cursor: pointer;
}

/* THE BOX IS DRAWN HERE. It used to be the native control with
   `accent-color: #ffffff`, and on this ground that is the wrong way round: the
   page does not declare a dark color-scheme, so Chromium draws the light-theme
   checkbox — a SOLID WHITE SQUARE when unchecked. The brightest thing in the
   form, and it reads as already ticked, which on a consent box is the one
   mistake worth avoiding. (Checked, the native control was already white with a
   dark tick, so the two states were nearly indistinguishable.)

   Replacing the control also fixes a 4px misalignment: the native widget
   carries its own inset, so the box sat 4px right of the left edge every field
   above it starts at.

   This is the same control the apex forms draw — see .fx-form .terms-label in
   elements/fx-form.css. It is duplicated rather than shared because the two
   cannot reach one sheet: the apex pair must load AFTER elements/form.css to
   win their overrides, and fx.css (the one sheet both sites do share) loads
   before it. Keep the two in step. */
.flock-site .offer-terms input[type="checkbox"] {
    flex: none;
    position: relative;
    width: 16px;
    height: 16px;
    /* Centres the box on the first line's cap height: (13px x 1.6) - 16 is
       about 5, half of that, plus a hair. */
    margin: 3px 0 0;
    padding: 0;
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: 1px solid var(--fx-rule-strong);
    border-radius: 2px;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.flock-site .offer-terms input[type="checkbox"]:hover {
    border-color: var(--fx-fg);
}

/* Checked is the page inverted, the same move the submit button makes. */
.flock-site .offer-terms input[type="checkbox"]:checked {
    background: #ffffff;
    border-color: #ffffff;
}

.flock-site .offer-terms input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 4px;
    height: 8px;
    border: 2px solid #0a0a0a;
    border-top: none;
    border-left: none;
    transform: translate(-50%, -60%) rotate(45deg);
}

.flock-site .offer-terms input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--fx-accent);
    outline-offset: 3px;
}

/* It has a border to recolour now, so the invalid state is the border — the
   same signal every other field in this form gives. */
.flock-site .offer-terms input[type="checkbox"].input-error {
    border-color: var(--fx-danger);
}

@media (prefers-reduced-motion: reduce) {
    .flock-site .offer-terms input[type="checkbox"] {
        transition: none;
    }
}

.flock-site .offer-terms span {
    font-size: 13px;
    line-height: 1.6;
    color: var(--fx-label);
}

/* Legal links keep their underline — the one place on the page that does. A
   terms link that reads as body copy is a terms link nobody opens. */
.flock-site .offer-terms span a {
    color: var(--fx-muted);
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color 0.2s ease;
}

.flock-site .offer-terms span a:hover {
    color: var(--fx-fg);
}

/* ── Submit ────────────────────────────────────────────────────────────────── */

.flock-site .offer-submit {
    /* landing.css right-aligns a pill. Full width instead, like the tier CTAs
       directly above it on this same page. */
    display: block;
    margin-top: 6px;
}

.flock-site .offer-submit-btn {
    width: 100%;
    box-sizing: border-box;
    padding: 14px 28px;
    border: 1px solid transparent;
    border-radius: 4px;
    background: #ffffff;
    color: #0a0a0a;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.flock-site .offer-submit-btn:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.82);
}

/* Not landing.css's opacity:0.5, which fades the black label into the grey and
   leaves "Sending…" barely legible at the moment it matters most. */
.flock-site .offer-submit-btn:disabled {
    background: rgba(255, 255, 255, 0.3);
    color: rgba(0, 0, 0, 0.55);
    opacity: 1;
    cursor: not-allowed;
}

/* ── Processing / success states ───────────────────────────────────────────────
   flock.js sets display on these inline, so they keep landing.css's flex and
   only their alignment, colour and type change here. */

.flock-site .offer-form-text {
    align-items: flex-start;
    text-align: left;
    gap: 6px;
    margin-bottom: 24px;
}

.flock-site .offer-form-text h3 {
    font-size: 17px;
    font-weight: 600;
    color: var(--fx-fg);
}

.flock-site .offer-form-text span {
    font-size: 14px;
    color: var(--fx-muted);
}

.flock-site .offer-success {
    align-items: flex-start;
    padding: 8px 0;
}

.flock-site .offer-success-text {
    font-size: 15px;
    color: var(--fx-fg);
}

@media (prefers-reduced-motion: reduce) {
    .flock-site .offer-field .fx-label,
    .flock-site .offer-field input,
    .flock-site .offer-field select,
    .flock-site .offer-submit-btn,
    .flock-site .offer-terms span a {
        transition: none;
    }
}

/* Stacks at 900px rather than the 1000px the .fx-row grids use: this grid's
   right track is a fixed 500px, so it survives further down than a pair of
   fluid columns would. */
@media (max-width: 900px) {
    .fx-offer {
        grid-template-columns: minmax(0, 1fr);
        gap: 44px;
    }

    .flock-site .offer-form-header {
        max-width: 46ch;
    }
}

/* ─── Responsive ───────────────────────────────────────────────────────── */

/* Four tiers in two rows of two. Four abreast needs the full 1180px measure —
   below it each column falls under ~230px and the feature lines start breaking
   in two — and one-per-row is five screens of scrolling on a tablet.

   Bounded at BOTH ends on purpose. The stack-to-one rule below is a plain
   max-width:860, so an unbounded max-width:1080 here would also match at 400px
   and, being later in the file, would win: two columns on a phone. The range
   makes the two blocks disjoint and the ordering irrelevant. */
@media (min-width: 861px) and (max-width: 1080px) {
    .fx-tiers {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .fx-tier {
        padding: 36px 26px;
    }

    /* Left-hand tier of each pair carries no divider and sits flush to the
       measure; right-hand tier closes flush on the other side. */
    .fx-tier:nth-child(odd) {
        border-left: none;
        padding-left: 0;
    }

    .fx-tier:nth-child(even) {
        padding-right: 0;
    }

    /* The second row needs the rule that .fx-tiers' own top border gives the
       first. */
    .fx-tier:nth-child(n + 3) {
        border-top: 1px solid var(--fx-rule);
    }
}

@media (max-width: 860px) {
    /* Columns stack; the vertical rules between them become horizontal ones. */
    .fx-tiers {
        grid-template-columns: 1fr;
    }

    .fx-tier {
        padding: 36px 0;
        border-left: none;
        border-top: 1px solid var(--fx-rule);
    }

    .fx-tier:first-child {
        border-top: none;
        padding-top: 36px;
    }

    .fx-tier:last-child {
        padding-right: 0;
    }

    .fx-tier--featured {
        box-shadow: inset 2px 0 0 0 var(--fx-accent);
        padding-left: 20px;
    }

    /* Scoped to match the (0,2,0) base rule above — a bare class here would
       lose to it and the reserve would survive into the stacked layout. */
    .flock-site .fx-tier-tagline {
        min-height: 0;
    }
}

/* The sticky matrix header is a desktop affordance. On a phone the table is
   already inside a horizontal scroller and the page scrolls under a fixed nav;
   a second sticky layer just eats the viewport. */
@media (max-width: 768px) {
    .fx-matrix thead th {
        position: static;
    }

    .fx-matrix th,
    .fx-matrix td {
        padding: 14px 10px;
    }

    /* Narrow enough that the row label and all four tiers are on screen at
       once — a comparison table showing one column at a time compares
       nothing. It still scrolls below this. */
    .fx-matrix {
        min-width: 560px;
    }

    .fx-matrix th.fx-matrix-cell,
    .fx-matrix td.fx-matrix-cell {
        width: 62px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .fx-matrix tbody th,
    .fx-matrix tbody td {
        transition: none;
    }
}

/* ═══ Polish ═══════════════════════════════════════════════════════════════
   Everything below is presentation on top of a page that already reads
   correctly without it. Each block is independent and can be removed on its
   own — none of the layout depends on any of it. */

/* ─── Tier columns: hover ──────────────────────────────────────────────────
   No lift and no shadow — a card would undo the flatness the whole layout is
   built on.

   And no ground wash either, which is what this used to do. That is the
   admin-panel idiom the tables were corrected away from, and leaving it here
   meant the page answered a pointer two different ways: a grey fill under a
   plan, a brightening rule under a table row.

   THE TEXT LIFTS OUT OF MUTED. That is the whole move, and the column's own
   divider is deliberately left alone.

   It did used to brighten, on the analogy that a table row sharpens the rule
   beneath it, so a column should sharpen the divider down its left side. The
   analogy does not survive contact: a row's rule is its own, but a column's
   left divider is SHARED with the neighbour, so lighting it up read as the
   wrong column answering. On the stacked layouts it was plainly wrong — there
   the dividers are border-top, and the overlay still drew a bright left edge
   where no divider existed. The name, the price and the feature list coming out
   of muted already say which column the pointer is in. */

/* Pointer devices only. On touch there is no pointer to leave, so the column
   tapped on the way to the CTA would keep its hover state for the rest of the
   visit — the same reason the table hovers are gated. */
@media (hover: hover) {
    .flock-site .fx-tier-tagline,
    .fx-tier-features li {
        transition: color 0.2s ease;
    }

    .flock-site .fx-tier:hover .fx-tier-tagline,
    .fx-tier:hover .fx-tier-features li {
        color: var(--fx-fg);
    }

    /* The inheritance line heads the rows under it rather than being one of
       them, and it keeps that rank through the hover. */
    .fx-tier:hover .fx-tier-features li.fx-tier-inherits {
        color: var(--fx-muted);
    }
}

/* ─── Phone ────────────────────────────────────────────────────────────────
   Everything above this point stacks correctly on a phone and still reads
   badly, which are different problems. In a 342px column the page was one
   undifferentiated grey slab: display leading calibrated for a 46px heading
   that runs two lines closes up when the same heading runs four at 28px, the
   first-paragraph size step makes the densest paragraph the largest one, and
   body copy at 62% white is dim enough on a phone to cost real legibility.

   This block is the reading pass. It changes no layout — only type, contrast
   and the rhythm between a row's parts. The one structural change is the
   tables, which are stacked rather than panned; that is below.

   IT MUST STAY LAST IN THIS FILE. Almost everything it overrides is declared at
   the same specificity as the rule it replaces — `.fx-table`, `.fx-callout`,
   `.fx-h` — so the cascade is doing the work, and a media query adds no weight
   of its own. Put this block where the other responsive blocks live, halfway up
   the sheet, and the component definitions below it silently win instead: the
   tables stayed 640px wide and kept scrolling sideways. */

@media (max-width: 700px) {

    /* ── Comparison table: one plan at a time ──────────────────────────────
       Four tier columns plus a label column cannot go under about 560px and
       stay legible, which on a 390px screen is 220px of sideways dragging per
       row — and a tick whose column heading has scrolled out of view says
       nothing at all. Panning is the wrong answer on a phone.

       So the table keeps its markup and shows ONE tier column, chosen from the
       picker above it. Comparing becomes tapping instead of dragging, every row
       gets room for its real value rather than a 62px cell, and the page stops
       carrying a horizontal scroller entirely.

       The picker's script sets .fx-matrix-cell--off at every width; only this
       block acts on it, so the desktop table is unaffected and a resize needs
       no listener. With no JS at all, nothing is hidden and the scroller below
       still works — which is why min-width keeps a usable value. */

    .fx-plan-pick {
        display: grid;
        /* Two by two, not four across: ENTERPRISE does not fit a 85px track,
           and a horizontally scrolling switcher would reintroduce the exact
           gesture this is here to remove. */
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
        margin: 28px 0 0;
        /* Holds under the fixed nav so the plan can be changed from anywhere in
           a long table without scrolling back up. */
        position: sticky;
        top: var(--fx-nav-h);
        z-index: 3;
        padding: 10px 0;
        background: var(--fx-bg);
    }

    .fx-plan-pick-btn {
        display: block;
        box-sizing: border-box;
        width: 100%;
        padding: 10px 12px;
        border: 1px solid var(--fx-rule);
        border-radius: 4px;
        background: transparent;
        text-align: left;
        font: inherit;
        cursor: pointer;
        transition: border-color 0.15s ease, background-color 0.15s ease;
    }

    .fx-plan-pick-name {
        display: block;
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: var(--fx-muted);
    }

    .fx-plan-pick-price {
        display: block;
        margin-top: 3px;
        font-size: 12px;
        color: var(--fx-label);
    }

    /* The chosen plan takes the accent rule the featured tier and the callouts
       use, so "this is the one on screen" is said the same way everywhere. */
    .fx-plan-pick-btn[aria-pressed="true"] {
        border-color: var(--fx-rule-strong);
        background: rgba(77, 124, 255, 0.07);
        box-shadow: inset 0 2px 0 0 var(--fx-accent);
    }

    .fx-plan-pick-btn[aria-pressed="true"] .fx-plan-pick-name {
        color: var(--fx-fg);
    }

    .fx-matrix-cell--off {
        display: none;
    }

    /* Two columns now, so none of the panning machinery is needed: no min
       width, no scroller, no pinned first column. */
    .fx-matrix {
        min-width: 0;
    }

    .fx-matrix-scroll {
        overflow-x: visible;
    }

    .fx-matrix th:first-child {
        position: static;
    }

    .fx-matrix th:first-child::after {
        display: none;
    }

    /* The header row says which plan is on screen — and so does the picker
       directly above it, which is sticky and therefore never off screen. With
       one tier column it also rendered as a short accented band floating over
       the right-hand third of the table, attached to nothing. The price row
       below it is a tbody row and stays. */
    .fx-matrix thead {
        display: none;
    }

    .fx-matrix th,
    .fx-matrix td {
        padding: 14px 0;
    }

    /* The answer sits at the right edge, against the label on the left — a spec
       sheet rather than a centred tick floating in a wide column. */
    .fx-matrix th.fx-matrix-cell,
    .fx-matrix td.fx-matrix-cell {
        width: 38%;
        text-align: right;
        border-left: none;
        padding-left: 12px;
    }

    /* The wash marked one column out of four. With one column on screen it
       would just tint the whole table. */
    .fx-matrix tbody td.fx-matrix-featured {
        background: none;
    }

    .fx-matrix tbody tr.fx-matrix-group th {
        padding: 28px 12px 12px 0;
    }

}
