/* ============================================================
   site/forge.css · BIFROST FORGE HOME, PAGE LAYER (F-series)
   ============================================================
   One page's layer, the same status as site/studios.css: markup
   the Figma draws that the engine does not yet own. Every entry
   here is a promotion candidate and is documented in DECISIONS.md.

   It is deliberately short, and it is short for a reason worth
   noting: the seven blocks Forge needed from the Studios layer
   were moved into site/home.css as G9 to G15 rather than copied,
   so this file holds only what is genuinely Forge's. Four rules.
   If a fifth arrives, ask first whether it is really the third
   brand's rule and belongs upstream.

   Source of truth: Figma 40004579:19389, UI SECTIONS - FORGE.
   Measured at 1440. There is a MOBILE - FORGE section
   (40004580:50703) and no TABLET - FORGE, so 834 is extrapolated.
   ============================================================ */


/* ------------------------------------------------------------
   F1 · TWO BUTTONS UNDER THE HERO LEAD                PROMOTE
   ------------------------------------------------------------
   Group and Studios both put a stats line under the hero lead.
   Forge puts two buttons there instead: "See what we are
   building" and "Build with us", drawn at y 500 of the 766 frame,
   34 tall, S apart. The engine's hero has no actions slot because
   until now no hero had actions.

   A <p> holding two <a class="ui-btn">, not a <div>, because it is
   a line of the hero's own flow and the shared layer already
   spaces .bf-hero__inner's children as a stack.

   Promote alongside the hero: a hero with a call to action is not
   a Forge idea, it is the normal case, and Group and Studios will
   both want it the moment anyone asks for a button up there.
   ------------------------------------------------------------ */
.bf-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-w-s);
  margin: 0;
}

/* The pills. .ui-btn fills with --ui-plate, which on an inverted band is
   20% white and is what the navbar's own control uses. It came out solid
   accent here instead, so something in §5 wins on an inverted section and
   the hero has to say what it wants. --ui-ink-40, measured against the
   frame: the drawn pill is white at 47% over #FF5001 (solved from two
   channels, 0.469 and 0.469), and the nearest token is 40%. Label at full
   knockout, as drawn. */
.ui-mode--inverted .bf-hero__actions .ui-btn {
  background: var(--ui-ink-40);
  color: var(--ui-ink);
}

/* The drawn measure of the two text blocks. The shared hero leaves the
   inner 1700 wide and lets the copy run, which Studios never noticed
   because its title is long enough to wrap anyway. Forge's title is
   drawn 632 wide and wraps to two lines, and its lead 352 and wraps to
   three. Written as min(px, 100%) rather than a percentage because the
   percentage would resolve against that 1700, not against the viewport.
   The 1700 inner is a latent bug in the shared hero; noted, not fixed
   here, because fixing it moves Group and Studios. */
/* The title was drawn 632 wide for "We build companies that matter.", which
   fits two lines at that measure. The copy doc's headline is half as long
   again and ran to THREE. Lasse, 11 September: two lines, and he picked the
   break that falls naturally rather than a forced one.

   Measured by sweeping the width and counting rendered line boxes: three lines
   up to 795px, two from 800, and never one, because the sentence is too long
   to fit a single line at 64px on any viewport this site serves. 840 takes the
   bottom of that band plus headroom, so a font that loads a hair wider cannot
   tip it back to three. The block resolves to 840 and the longest line sets
   the visible width at about 790, inside the 1100 content column.

   This is a real departure from the frame's 632, and it is the departure the
   copy change requires: the frame's measure was drawn for the frame's words. */
.bf-hero--image .bf-hero__title { max-inline-size: min(840px, 100%); }
/* The lead was drawn 352 wide for the original three-line sentence. The copy
   doc's is more than twice as long and ran to FIVE lines at that measure,
   which is a paragraph under a display line rather than a hero lead. Lasse,
   11 September: three lines.

   Measured rather than guessed, by sweeping the width in a browser and
   counting rendered line boxes: four lines up to 535px, three from 540px, and
   still three at 700. 580 is taken from the middle of the bottom of that band,
   so a font that loads a hair wider does not tip it to four. It also lands
   just under the title's 632, which reads as one block rather than two. */
.bf-hero--image .bf-hero__lead  { max-inline-size: min(580px, 100%); }


/* ------------------------------------------------------------
   F2 · THE CARD INDEX AND THE CTA CENTRE THEIR HEADS
   ------------------------------------------------------------
   Measured, not eyeballed. In the frame the What We Build title
   and its intro both sit at x 280 in the 1100 column and are 540
   wide, and (1100 - 540) / 2 is exactly 280. The CTA title is at
   x 189 and 722 wide, and (1100 - 722) / 2 is 189. Both centred.

   G5 already does this for .ui-section--cards-stacked, off the
   Studios file, and G5's own comment says the engine leaves every
   head left. So this is the same finding on two more sections and
   the third and fourth data point for the same engine question:
   whether a centred head should be a documented section variant
   rather than a per-page override. Raised in DECISIONS.md.
   ------------------------------------------------------------ */
.ui-section--cards-colorful .ui-section__head,
.ui-section--cta .ui-section__head {
  align-items: center;
  text-align: center;
}
.ui-section--cards-colorful .ui-section__title,
.ui-section--cards-colorful .ui-section__intro,
.ui-section--cta .ui-section__title {
  margin-inline: auto;
}
/* The intro is drawn at the card width, not the column width: 540 of
   1100. Expressed as a ratio so it holds when the column does not. */
.ui-section--cards-colorful .ui-section__intro {
  max-inline-size: calc(540 / 1100 * 100%);
}
.bf-cta__actions {
  display: flex;
  justify-content: center;
  margin: 0;
}


/* ------------------------------------------------------------
   F3 · THE BUTTON UNDER THE CARD GRID
   ------------------------------------------------------------
   "See everything we are building", drawn at x 0 of the column and
   40 under the last card row, so it is left-aligned even though the
   head above it is centred. That asymmetry is in the frame and it
   reads correctly: the head introduces the section, the button
   continues the grid.
   ------------------------------------------------------------ */
.bf-cards__more {
  display: flex;
  margin: 0;
}


/* ------------------------------------------------------------
   F4 · A CONTROL WITH NOWHERE TO GO YET               PROMOTE
   ------------------------------------------------------------
   Three affordances on this page have no destination: the
   companies button (its page is not built), the Contact button
   (there is no address, form or page anywhere in this build) and
   the newsletter (no endpoint). All three are drawn in the file, so
   removing them would misrepresent the design, and wiring them to
   a guess would misrepresent the client.

   So they are visibly dead: dimmed, not underlined on hover, and
   not focusable. `aria-disabled` plus `data-bf-pending` rather than
   the `disabled` attribute, because `disabled` is not valid on an
   anchor and a <button> here would be a lie about what it is.

   The same reasoning as G8, which does this for the signup. G8 and
   this should become one rule about pending controls when the
   engine gets one. Delete the attribute in the markup and the
   control comes alive with no CSS change.
   ------------------------------------------------------------ */
.ui-btn[data-bf-pending] {
  opacity: 0.45;
  pointer-events: none;
}


/* ------------------------------------------------------------
   F5 · THE ACTIVE FILTER CHIP, AND A PATTERN WORTH NAMING
   ------------------------------------------------------------
   The frame draws the active chip as a solid accent pill with a
   knockout label. The engine draws it with --ui-plate, and on a
   plated band --ui-plate IS the band, so the chip had no pill at
   all: the word "All" floating between two outlined neighbours.
   Its pressed state moves to --ui-plate-up, which is one step and
   still not a pill.

   THIRD TIME TODAY. The Read more button on the legal page head
   was invisible for exactly this reason, and so was that button's
   first fix when it reached for a token scoped to the navbar. The
   pattern is one sentence: a control token that resolves to the
   surface the control sits on is invisible, and the engine has
   three of them. That is an engine question, not three page fixes,
   and it is raised as one in DECISIONS.md.

   ui-core §5.2 already says the accent fill is what an active tag
   wants ("Active fills with the accent, the one place a tag takes
   a colour plate") and reaches it through .ui-mode--alternative.
   This page is not in that mode, so it asks directly.
   ------------------------------------------------------------ */
.ui-section__filters .ui-tag--filled[aria-pressed="true"] {
  background: var(--c-accent);
  border-color: transparent;
  color: var(--ui-ink-on-accent);
}


/* ------------------------------------------------------------
   F6 · WHAT WE BELIEVE IS THREE UP
   ------------------------------------------------------------
   The frame draws three 353-wide columns in the 1100 column
   (40004579:20352), which is four grid columns each. Set here
   rather than inline, the same way S6 sets the portfolio's
   four-up, so the number sits next to the measurement it came
   from. Below 640 the engine ignores --span and stacks, which is
   what the mobile frame does too.
   ------------------------------------------------------------ */
#believe .ui-section__cards > * { --span: 6; }

/* THREE BECAME FOUR, 11 September, so three-up became two-by-two. The frame
   draws three 353-wide columns and the copy doc added a fourth belief. At
   --span: 4 the fourth wraps alone onto a second row, which reads as a
   mistake; at --span: 3 the four columns come down to 265 and the existing
   paragraphs, which run 70 to 90 words, become very tall and thin. Two rows of
   540 is the measure the rest of this page already uses. A frame for four
   columns, if one arrives, wins over this. */

/* Two Engines on Home and The three on Services are the same component again,
   at the counts their copy has. Set here rather than inline for the reason F6
   gives: the number sits next to the measurement it came from. */
#engines .ui-section__cards > * { --span: 6; }

/* And the intro goes back under the title. .ui-section__intro is
   `margin-inline: var(--ui-section-center, auto)`, so it centres itself unless
   a section says otherwise, which is right for the centred card heads F2 deals
   with and wrong here: the title of a --columns section is left, so a centred
   intro leaves one short line stranded in the middle of the band with nothing
   above it. Setting the engine's own token to 0 is the documented way to say
   so, rather than overriding the margin and fighting it. */
#engines { --ui-section-center: 0; }
#services-list .ui-section__cards > * { --span: 4; }


/* ------------------------------------------------------------
   F7 · THE FOOTER WATERMARK, WHEN A WORD HAS A DESCENDER  PROMOTE
   ------------------------------------------------------------
   Lasse, 11 September, on the preview: Forge sits higher than
   Bifrost and they need to align at the bottom. Two faults, one
   cause, and the second one is not visible until you measure.

   THE ENGINE SIZES BOTH WORDS BY BOX HEIGHT. ui-core gives every
   .ui-footer__logo-word `height: var(--ui-footer-logo-h)` and the
   row is `align-items: flex-end`, so the two SVG boxes are the
   same height with their bottoms on one line. That is correct for
   Studios, where Bifrost and Studios both end at the baseline and
   equal boxes mean equal letters. Forge is the first word in the
   house with a DESCENDER, and its viewBox has to include the tail
   of the g. So a box of the same height holds a smaller word, and
   the baseline sits a descender's depth above the line.

   READ OFF THE FIGMA, not off the render (Footer instance
   40004579:19464, vectors in Logo Placeholder). Figma units:

     Bifrost   group   y 20      h 162.3244   baseline y 179.103
     Forge     frame   y 178     h 193.7119   baseline y 321.189
     Bifrost   cap B           h 143.190
     Forge     cap F           h 143.190      <- identical

   The two caps are the same number. The words are set at ONE size
   in the file and the difference is entirely in how the two assets
   were exported: Bifrost is 1.686487 Figma units per SVG user unit
   and Forge is 2.026369, so equal boxes render Forge 16% small.

   Everything below is derived from those five numbers and written
   as a multiple of --ui-footer-logo-h, which is 80 / 92 / 162 at
   the three widths, so one rule holds at all of them.

     scale   0.8821485 H (Bifrost cap) / 0.739193 (Forge cap as a
             fraction of its own box)            = 1.19339
     Forge baseline above its box bottom
             50.5229 / 193.7119 * 1.19339        = 0.311254 H
     Bifrost baseline above its box bottom
             3.2214 / 162.3244                   = 0.019846 H
     shift   the difference                      = 0.291408 H

   A HEIGHT PLUS A TRANSFORM, and the first draft of this was a
   scale() about the right edge, which is worth writing down
   because it measured perfectly at two widths out of three.

   Scaling about the right edge keeps Forge flush right, which the
   frame wants, and at 1440 and 834 it gave baselines equal to
   0.00px and cap heights equal to 0.01px. At 393 the row WRAPS,
   space-between puts the lone word on its own line at flex-start,
   and a transform that grows leftward from a right edge that is
   now on the LEFT took the F to x -29.9 and under the overflow
   clip. Caught by measuring all three widths rather than the one
   the screenshot came from.

   So the size is a real height and flex does the work. The row is
   align-items: flex-end, so a taller item grows the LINE and both
   words still bottom-align inside it: Bifrost does not move
   relative to the row, the row gains 0.19339 H at the top, and
   the word wraps and aligns at every width like any other item.
   Only the baseline shift stays a transform, because that one must
   not affect layout.

   THE DEVIATION FROM THE FRAME. Figma lets the g hang 27px past
   the logo block and overlap the copyright row's band; they do not
   collide because the g is at x 1200 and the copyright text ends
   at 459. Reproducing that needs overflow: visible on the row, and
   that clip is load-bearing: at 393 the words keep their intrinsic
   width and the watermark is most of the measure. So the row is
   given bottom padding equal to the descender instead. On Forge
   the footer is 0.193 H taller at the top and 0.291 H minus the
   standard pad taller at the bottom, 58px at 1440, and nothing is
   clipped at any width.
   ------------------------------------------------------------ */
.ui-footer__logo {
  padding-block-end: calc(0.291408 * var(--ui-footer-logo-h));
}
.ui-footer__logo-word + .ui-footer__logo-word {
  height: calc(1.19339 * var(--ui-footer-logo-h));
  transform: translateY(calc(0.291408 * var(--ui-footer-logo-h)));
}
