/* ===========================================================================
   Future Dynamics — reset, primitives and shared components
   ---------------------------------------------------------------------------
   Everything here is page-agnostic: the grid, the buttons, the rule bar, the
   footer. A second page should need nothing from home.css.
   Raw values are not permitted in this file. Read tokens.css.
   =========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fd-bg);
  color: var(--fd-text);
  font-family: var(--fd-font);
  font-size: var(--fd-text-md);
  line-height: var(--fd-leading-body);
  font-weight: var(--fd-weight-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { display: block; max-width: 100%; height: auto; }
/* figure and blockquote carry a 40px side margin by default, which on a
   quote card is 160px of the measure gone before a word is set. */
h1, h2, h3, p, figure, blockquote, figcaption { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

/* A soft ring rather than a hard rule. outline follows border-radius, so an
   element's own shape shapes its focus; the halo underneath keeps it visible
   against both the white ground and the warm surface. */
:focus-visible {
  outline: 2px solid var(--fd-focus-ring);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px var(--fd-focus-halo);
  transition: box-shadow var(--fd-duration-fast) var(--fd-ease);
}

/* Round the icon buttons so their ring is a circle, which is the sphere the
   whole identity turns on rather than a box. */
.fd-menu-toggle, .fd-menu-close { border-radius: 50%; }

/* Text links get a little breathing room so the ring is not tight on the
   glyphs. The negative margin keeps the layout where it was. */
.fd-menu-panel a, .fd-nav__link, .fd-footer a {
  border-radius: var(--fd-radius-md);
}
.fd-menu-panel a:focus-visible, .fd-footer a:focus-visible {
  outline-offset: 6px;
}

/* A button already carries a shadow, so its focus halo has to be added to it
   rather than replace it. */
.fd-button--gold:focus-visible {
  box-shadow: var(--fd-button-gold-inset), 0 0 0 6px var(--fd-focus-halo);
}
.fd-button--outline:focus-visible {
  box-shadow: var(--fd-button-second-inset), 0 0 0 6px var(--fd-focus-halo);
}

.fd-visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* --- Layout ---------------------------------------------------------------
   .fd-shell is the only thing that knows about the page gutter. .fd-grid is
   the only thing that knows about the column count. Nothing else sets a
   horizontal margin. */

.fd-shell {
  width: 100%;
  max-width: calc(var(--fd-content) + var(--fd-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--fd-gutter);
}

.fd-grid {
  display: grid;
  grid-template-columns: repeat(var(--fd-columns), minmax(0, 1fr));
  gap: var(--fd-column-gap);
}

/* Spans, so a block states its width in columns and never in pixels. */
.fd-col-4  { grid-column: span 4; }
.fd-col-5  { grid-column: span 5; }
.fd-col-6  { grid-column: span 6; }
.fd-col-7  { grid-column: span 7; }
.fd-col-12 { grid-column: span 12; }

/* Centred six columns: the mission panel's footprint. */
.fd-col-center-6 { grid-column: 4 / span 6; }

/* --- The rule bar ---------------------------------------------------------
   Silver over a crimson hairline over gold. Bleeds off the left edge and stops
   dead on the content's right edge, which is the "cut final edge" from the
   design notes. The gradients run vertically, per the supplied artwork, and
   the bar is still: the earlier horizontal drift is gone with them. */

.fd-rule-bar {
  /* From the viewport's left edge to the content column's right edge, at every
     width. Half the viewport plus half the content is exactly where the shell
     ends once it stops growing; the max-width takes over below that. */
  width: calc(50% + var(--fd-content) / 2);
  max-width: calc(100% - var(--fd-gutter));
}
.fd-rule-bar > span { display: block; }
.fd-rule-bar__silver  { height: 18.5px; background-image: var(--fd-bar-silver); }
.fd-rule-bar__crimson { height: 3px;    background-color: var(--fd-crimson); }
.fd-rule-bar__gold    { height: 18.5px; background-image: var(--fd-bar-gold); }

/* Only the two corners that exist: the bar bleeds left and is cut square right. */
.fd-rule-bar__silver { border-top-right-radius: var(--fd-radius-sm); }
.fd-rule-bar__gold   { border-bottom-right-radius: var(--fd-radius-sm); }

/* --- Buttons --------------------------------------------------------------
   Two kinds only. A gold face for actions, a hairline outline for the nav. */

.fd-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--fd-space-2);
  font-family: var(--fd-font);
  font-size: var(--fd-label-size);
  font-weight: var(--fd-weight-medium);
  line-height: var(--fd-label-leading);
  border: 0;
  border-radius: var(--fd-radius-md);
  cursor: pointer;
  transition:
    transform  var(--fd-duration-fast) var(--fd-ease),
    box-shadow var(--fd-duration-fast) var(--fd-ease),
    filter     var(--fd-duration-fast) var(--fd-ease);
}

/* The press is the honest part of a button. Both kinds lift a hair on hover
   and sit back down when held, so the pointer gets an answer before the page
   navigates. Transform and box-shadow only: nothing here triggers layout. */
.fd-button:hover  { transform: translateY(-1px); }
.fd-button:active { transform: translateY(0); transition-duration: 80ms; }

.fd-button--gold {
  padding: var(--fd-space-4) var(--fd-space-6);
  background: var(--fd-button-gold-face);
  box-shadow: var(--fd-button-gold-inset);
  color: var(--fd-on-gold);
}
.fd-button--gold:hover {
  box-shadow: var(--fd-button-gold-inset), 0 4px 14px rgba(128, 92, 0, 0.18);
  filter: saturate(1.06);
}

.fd-button--outline {
  padding: var(--fd-space-3) var(--fd-space-4);
  background: var(--fd-button-second-face);
  box-shadow: var(--fd-button-second-inset);
  color: var(--fd-text);
}
.fd-button--outline:hover {
  box-shadow: var(--fd-button-second-inset), 0 3px 10px rgba(155, 125, 47, 0.16);
}

/* --- Site header ---------------------------------------------------------- */

.fd-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fd-space-5);
  padding-block: var(--fd-space-6) 0;
}
.fd-header__mark { width: 112px; flex: none; }
.fd-nav {
  display: flex;
  align-items: center;
  gap: var(--fd-space-8);
  font-size: var(--fd-text-base);
}
.fd-nav__link { position: relative; padding-block: var(--fd-space-1); }
.fd-nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--fd-duration-base) var(--fd-ease);
}
.fd-nav__link:hover::after { transform: scaleX(1); }

/* --- Services strip -------------------------------------------------------
   Full bleed band. The five labels sit on their own equal columns so the
   spacing is the grid's doing and not a row of hand-set margins. */

.fd-services {
  background: var(--fd-surface);
  padding-block: var(--fd-space-3);
}
.fd-services__list {
  /* The wrapper carries .fd-col-center-6, the same class the mission panel
     uses, so the first and last labels stay flush with the panel's edges at
     every breakpoint instead of drifting apart at one of them. */
  display: flex;
  justify-content: space-between;
  gap: var(--fd-space-4);
  color: var(--fd-brand);
  font-size: var(--fd-text-sm);
  font-weight: var(--fd-weight-medium);
  letter-spacing: var(--fd-tracking-wide);
  text-transform: uppercase;
  line-height: var(--fd-leading-snug);
}

/* The second copy exists only for the mobile marquee. Two classes, so it does
   not depend on sitting after the rule above to win. */
.fd-services__list.fd-services__list--clone { display: none; }

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

.fd-footer {
  background: var(--fd-surface);
  padding-block: var(--fd-space-9) var(--fd-space-5);
  margin-top: var(--fd-space-13);
}
.fd-footer__heading {
  color: var(--fd-ink);
  font-size: var(--fd-text-xs);
  font-weight: var(--fd-weight-bold);
  letter-spacing: var(--fd-tracking-wider);
  text-transform: uppercase;
  line-height: var(--fd-leading-snug);
  margin-bottom: var(--fd-space-4);
}
.fd-footer__links { display: grid; gap: var(--fd-space-2); }
.fd-footer__links a,
.fd-footer__contact { font-size: var(--fd-text-base); }
.fd-footer__legal {
  margin-top: var(--fd-space-9);
  font-size: var(--fd-text-base);
}

/* --- Responsive -----------------------------------------------------------
   The grid stays twelve columns. Only the spans change, so every page that
   uses the spans inherits this behaviour without its own breakpoints. */

@media (max-width: 1000px) {
  .fd-col-center-6 { grid-column: span 12; }
  .fd-col-5, .fd-col-6, .fd-col-7 { grid-column: span 12; }
  .fd-col-4 { grid-column: span 6; }
}

@media (max-width: 640px) {
  .fd-col-4 { grid-column: span 12; }
  .fd-nav { gap: var(--fd-space-5); }
  .fd-footer { margin-top: var(--fd-space-10); }
}

/* --- The menu toggle ------------------------------------------------------
   Three rules, the middle one short and right aligned, which is the same
   rightward lean the logo's wave has. Hover extends it to full width. Open
   rotates the outer two into a cross and contracts the middle one into the
   golden sphere from the mark, so the close button is the brand's own dot
   sitting at the pivot.

   Everything moves on transform and opacity. The hit area is 44px square even
   though the glyph is 20px, which is the touch minimum. */

.fd-menu-toggle {
  display: none;              /* desktop keeps the full nav */
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  flex: none;
}

.fd-menu-toggle__glyph {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 22px;
  height: 14px;
}

.fd-menu-toggle__bar {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1.5px;
  border-radius: 1px;
  background: var(--fd-text);
  transition:
    transform var(--fd-duration-base) var(--fd-ease-out-soft),
    opacity   var(--fd-duration-fast) var(--fd-ease);
}
.fd-menu-toggle__bar--top    { top: 0; }
.fd-menu-toggle__bar--middle { top: 50%; margin-top: -0.75px; transform-origin: right center; transform: scaleX(0.66); }
.fd-menu-toggle__bar--bottom { bottom: 0; }

.fd-menu-toggle:hover .fd-menu-toggle__bar--middle { transform: scaleX(1); }

/* The sphere: the mark's own radial gradient, dormant until the menu opens. */
.fd-menu-toggle__sphere {
  position: absolute;
  top: 50%; left: 50%;
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--fd-sphere);
  transform: scale(0);
  transition: transform var(--fd-duration-base) var(--fd-ease-out-soft)
              var(--fd-duration-fast);
}

.fd-menu-toggle[aria-expanded="true"] .fd-menu-toggle__bar--top {
  transform: translateY(6.25px) rotate(45deg);
}
.fd-menu-toggle[aria-expanded="true"] .fd-menu-toggle__bar--bottom {
  transform: translateY(-6.25px) rotate(-45deg);
}
.fd-menu-toggle[aria-expanded="true"] .fd-menu-toggle__bar--middle {
  transform: scaleX(0);
  opacity: 0;
}
.fd-menu-toggle[aria-expanded="true"] .fd-menu-toggle__sphere {
  transform: scale(1);
}

/* --- The mobile panel -----------------------------------------------------
   Slides in from the right over the warm surface. Items rise in behind it on a
   short stagger, which is the same gesture the page's scroll reveal uses. */

.fd-menu-panel {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(320px, 82vw);
  z-index: 20;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--fd-space-11) var(--fd-space-8);
  background: var(--fd-surface);
  box-shadow: -24px 0 60px rgba(32, 31, 31, 0.08);
  transform: translateX(100%);
  visibility: hidden;
  transition:
    transform  var(--fd-duration-base) var(--fd-ease-out-soft),
    visibility 0s linear var(--fd-duration-base);
}
.fd-menu-panel[data-open="true"] {
  transform: translateX(0);
  visibility: visible;
  transition:
    transform  var(--fd-duration-base) var(--fd-ease-out-soft),
    visibility 0s;
}

.fd-menu-panel__links {
  display: flex;
  flex-direction: column;
  gap: var(--fd-space-5);
}

.fd-menu-panel a {
  font-size: var(--fd-text-lg);
  color: var(--fd-brand);
  opacity: 0;
  transform: translateX(var(--fd-menu-item-travel));
  transition:
    opacity   var(--fd-menu-item-duration) var(--fd-ease),
    transform var(--fd-menu-item-duration) var(--fd-ease);
}
/* Keyed on data-animate, not data-open, and the script sets it a frame later.
   The panel goes from visibility:hidden to visible in the same frame it opens,
   and a browser will not transition a property on an element it has never
   painted: it skips straight to the end value once the delay elapses. That is
   why the links used to pop in one by one with no movement. Waiting a frame
   lets the start state be painted first, so there is something to animate from. */
.fd-menu-panel[data-animate="true"] a { opacity: 1; transform: none; }
.fd-menu-panel[data-animate="true"] a:nth-child(1) { transition-delay: calc(var(--fd-menu-item-step) * 1); }
.fd-menu-panel[data-animate="true"] a:nth-child(2) { transition-delay: calc(var(--fd-menu-item-step) * 2); }
.fd-menu-panel[data-animate="true"] a:nth-child(3) { transition-delay: calc(var(--fd-menu-item-step) * 3); }
.fd-menu-panel[data-animate="true"] a:nth-child(4) { transition-delay: calc(var(--fd-menu-item-step) * 4); }

.fd-menu-scrim {
  position: fixed;
  inset: 0;
  z-index: 10;
  background: rgba(32, 31, 31, 0.28);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fd-duration-base) var(--fd-ease),
              visibility 0s linear var(--fd-duration-base);
}
.fd-menu-scrim[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--fd-duration-base) var(--fd-ease), visibility 0s;
}

body[data-menu-open="true"] { overflow: hidden; }

/* --- Scroll reveal --------------------------------------------------------
   The hidden state only exists once script has run and set .fd-js on the root.
   Without JavaScript nothing is ever hidden, which is the rule the live site
   learned the hard way in September. */

.fd-js [data-reveal] {
  opacity: 0;
  transform: translateY(var(--fd-reveal-rise));
  transition:
    opacity   var(--fd-duration-slow) var(--fd-ease-out-soft),
    transform var(--fd-duration-slow) var(--fd-ease-out-soft);
}
.fd-js [data-reveal].is-revealed { opacity: 1; transform: none; }
.fd-js [data-reveal][data-reveal-delay="1"] { transition-delay: calc(var(--fd-reveal-stagger) * 1); }
.fd-js [data-reveal][data-reveal-delay="2"] { transition-delay: calc(var(--fd-reveal-stagger) * 2); }
.fd-js [data-reveal][data-reveal-delay="3"] { transition-delay: calc(var(--fd-reveal-stagger) * 3); }
.fd-js [data-reveal][data-reveal-delay="4"] { transition-delay: calc(var(--fd-reveal-stagger) * 4); }

/* A sequence reads as one gesture crossing the row rather than five arrivals,
   so its steps are tighter than the stagger between whole blocks. Against an
   1800ms reveal the five overlap heavily, which is what makes it a wave. */
.fd-js [data-reveal][data-reveal-step="1"] { transition-delay: calc(var(--fd-reveal-step) * 1); }
.fd-js [data-reveal][data-reveal-step="2"] { transition-delay: calc(var(--fd-reveal-step) * 2); }
.fd-js [data-reveal][data-reveal-step="3"] { transition-delay: calc(var(--fd-reveal-step) * 3); }
.fd-js [data-reveal][data-reveal-step="4"] { transition-delay: calc(var(--fd-reveal-step) * 4); }

/* --- Reduced motion -------------------------------------------------------
   High severity in the guidelines, and the right default for an audience of
   senior people reading on their own terms. Everything lands in its final
   state; nothing travels. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  .fd-js [data-reveal] { opacity: 1; transform: none; }
}

/* --- Breakpoint: the nav folds into the toggle ---------------------------- */

@media (max-width: 760px) {
  .fd-nav__link, .fd-nav .fd-button { display: none; }
  .fd-menu-toggle { display: block; }
}

/* --- Pointer parallax on the lockup --------------------------------------
   The mark is a golden sphere riding a silver wave, so the obvious depth is
   the one the artwork already implies: the sphere nearest, the wave behind it,
   the wordmark furthest back and almost still. Each layer translates by its
   own amount against the same pointer position, and the whole plate tilts a
   few degrees, which is what turns parallax into something spatial rather than
   a slide.

   --px and --py are written by site.js and run -1 to 1. They default to 0, so
   with no script the logo simply sits where it was drawn. */

.fd-lockup, .fd-mark {
  display: block;
  --px: 0;
  --py: 0;
}
.fd-lockup { perspective: 900px; }
.fd-mark   { perspective: 500px; }

.fd-lockup svg, .fd-mark svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;          /* the sphere travels past the viewBox edge */
  transform: rotateY(calc(var(--px) * var(--fd-depth-tilt)))
             rotateX(calc(var(--py) * var(--fd-depth-tilt) * -0.6));
  transform-style: preserve-3d;
}

.fd-lockup__word, .fd-mark__word {
  transform: translate(calc(var(--px) * var(--fd-depth-word)),
                       calc(var(--py) * var(--fd-depth-word) * 0.5));
}
.fd-lockup__wave, .fd-mark__wave {
  transform: translate(calc(var(--px) * var(--fd-depth-wave)),
                       calc(var(--py) * var(--fd-depth-wave) * 0.5));
}
.fd-lockup__sphere, .fd-mark__sphere {
  transform: translate(calc(var(--px) * var(--fd-depth-sphere)),
                       calc(var(--py) * var(--fd-depth-sphere) * 0.5));
}

/* The header mark is small and sits beside the nav, so it takes half the
   travel. One attribute, read by the script, rather than a second rule set. */
[data-parallax-scale="0.5"] {
  --fd-depth-sphere: 8px;
  --fd-depth-wave:   4px;
  --fd-depth-word:   1px;
  --fd-depth-tilt:   3deg;
}

@media (prefers-reduced-motion: reduce) {
  .fd-lockup svg, .fd-mark svg,
  .fd-lockup__word, .fd-lockup__wave, .fd-lockup__sphere,
  .fd-mark__word, .fd-mark__wave, .fd-mark__sphere { transform: none; }
}

/* --- Services on a small screen: an endless pass ---------------------------
   Below 640px the five labels no longer fit on one line. Rather than wrapping
   them into a block or shrinking the type, the row becomes a slow pass that
   travels left to right and never ends.

   Seamless because the track holds the row twice and the animation moves it by
   exactly half its width: at -50% the clone sits precisely where the original
   began, so the loop point has nothing to see. The clone is aria-hidden, so a
   screen reader still hears the five services once.

   The edges are masked rather than cut, so labels dissolve instead of being
   chopped at the viewport wall. */

@media (max-width: 640px) {
  .fd-services__viewport {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  }
  .fd-services__track {
    display: flex;
    width: max-content;
    animation: fd-marquee var(--fd-marquee) linear infinite;
    will-change: transform;
  }
  /* The separation between the two copies lives INSIDE each copy, as trailing
     padding, never as a gap on the track. With a track gap the width is
     2L + G while the repeat period is L + G, so -50% lands half a gap out and
     the loop visibly jumps once per pass. Carrying the gap inside makes each
     copy L + G wide and -50% exactly one period. */
  .fd-services__list {
    flex: none;
    justify-content: flex-start;
    gap: var(--fd-space-7);
    padding-right: var(--fd-space-7);
  }
  .fd-services__list.fd-services__list--clone { display: flex; }

  /* A held finger or a keyboard landing inside stops the pass, so a label can
     actually be read. */
  .fd-services__viewport:hover .fd-services__track,
  .fd-services__viewport:focus-within .fd-services__track { animation-play-state: paused; }

  /* The scroll reveal stands down inside the marquee. Only the originals carry
     data-reveal, so a staggered fade would run against solid clone labels half
     a pass away. The pass is the entrance here. */
  .fd-js .fd-services__list [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

@keyframes fd-marquee {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* Reduced motion: stop the pass, drop the mask, and let the row be swiped
   instead. Freezing a clipped row would hide three of the five services. */
@media (prefers-reduced-motion: reduce) and (max-width: 640px) {
  .fd-services__viewport {
    overflow-x: auto;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .fd-services__track { animation: none; }
  .fd-services__list.fd-services__list--clone { display: none; }
}

/* --- Fulcrum card ---------------------------------------------------------
   Shared, not home-only: the live site carries this block on every page, so it
   lives here with the header and the footer rather than in a page stylesheet.
   Full width, hairline edge, split into text and artwork. The artwork is the
   gradient plate from the design, used as vector so it stays crisp at any
   size. */

.fd-fulcrum { padding-top: var(--fd-space-12); }

.fd-fulcrum__card {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--fd-space-11);
  align-items: center;
  background: var(--fd-bg);
  border: var(--fd-hairline);
  border-radius: var(--fd-radius-xl);
  box-shadow: var(--fd-shadow-card);
  padding: var(--fd-space-6);
}
.fd-fulcrum__heading {
  color: var(--fd-brand);
  font-size: var(--fd-text-lg);
  font-weight: var(--fd-weight-medium);
  line-height: var(--fd-leading-snug);
  margin-bottom: var(--fd-space-4);
}
.fd-fulcrum__body { margin-bottom: var(--fd-space-6); }
.fd-fulcrum__plate { width: 100%; height: auto; }  /* its corners are drawn into the SVG */

@media (max-width: 1000px) {
  .fd-fulcrum__card { grid-template-columns: minmax(0, 1fr); gap: var(--fd-space-7); }
}

/* --- Skip link ------------------------------------------------------------
   Off screen until focused, which is the first thing a keyboard user reaches
   on every page. */

.fd-skip {
  position: absolute;
  left: var(--fd-space-5);
  top: var(--fd-space-5);
  z-index: 30;
  padding: var(--fd-space-3) var(--fd-space-4);
  background: var(--fd-surface);
  border-radius: var(--fd-radius-md);
  box-shadow: var(--fd-shadow-card);
  font-size: var(--fd-text-base);
  transform: translateY(-200%);
  transition: transform var(--fd-duration-fast) var(--fd-ease);
}
.fd-skip:focus { transform: translateY(0); }

/* --- The panel's own close button -----------------------------------------
   Four bars radiating from the golden sphere, with a gap between each bar and
   the sphere, rather than a cross drawn through it. The sphere is the subject
   and the bars point at it.

   Each bar is rotated and then pushed out along its own rotated axis, so the
   gap is one number and all four stay equal. Hover widens that gap, which
   makes the glyph breathe outward without anything changing size. */

.fd-menu-close {
  position: absolute;
  top: var(--fd-space-5);
  right: var(--fd-space-5);
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--fd-duration-base) var(--fd-ease);
}
.fd-menu-panel[data-animate="true"] .fd-menu-close { opacity: 1; }

.fd-menu-close__glyph {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 36px;
  height: 36px;
  /* Distance from the centre to each bar's midpoint. An unregistered custom
     property cannot transition, but it does not need to: changing it changes
     each bar's computed transform, and the bars animate that.
     Measured off the reference artwork and scaled to 36px: sphere 10.7,
     bar from 7.3 to 16.6 out, so a 9.2 bar centred at 12. */
  --fd-close-gap: 12px;
}

.fd-menu-close__bar {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 2px;
  margin: -1px 0 0 -4.5px;
  border-radius: 1px;
  background: var(--fd-close-bar);
  transition: transform var(--fd-duration-fast) var(--fd-ease);
}
.fd-menu-close__bar:nth-of-type(1) { transform: rotate(45deg)  translateX(calc(var(--fd-close-gap) * -1)); }
.fd-menu-close__bar:nth-of-type(2) { transform: rotate(45deg)  translateX(var(--fd-close-gap)); }
.fd-menu-close__bar:nth-of-type(3) { transform: rotate(-45deg) translateX(calc(var(--fd-close-gap) * -1)); }
.fd-menu-close__bar:nth-of-type(4) { transform: rotate(-45deg) translateX(var(--fd-close-gap)); }

.fd-menu-close__sphere {
  position: absolute;
  top: 50%; left: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: var(--fd-sphere);
}

.fd-menu-close:hover .fd-menu-close__glyph { --fd-close-gap: 13.5px; }
