/* ==========================================================================
   ARG Laboratories: motion and interaction layer
   Genesis Flow Labs, 2026-08-27

   Vanilla CSS. No build step, no library, no CDN. Pairs with motion.js.

   HOW IT LAYERS
   Everything is namespaced .mo- and additive. Load AFTER style.css.
   Two classes on <html> control it:

     .mo-on   author added, in the markup: <html lang="en" class="mo-on">
              Turns on the site wide motion. Without it, only the .mo-cl
              confirm list styles apply. That is deliberate: the confirm
              list is self contained and does not need the rest.

     .mo-js   added by motion.js the moment it runs. Nothing on this page is
              ever hidden without it, so a script that fails to load leaves
              the page whole and readable rather than blank.

   REDUCED MOTION
   Every moving rule lives inside @media (prefers-reduced-motion:no-preference).
   Under reduce those rules do not exist at all, so there is no hidden state
   to recover from and no transition to sit through. Content is never gated
   on an animation finishing.

   THE ONE GESTURE
   A hairline rule that draws itself. It appears four times and it always
   means the same thing: this has been measured and set down.
     1. under each hero specification figure, at load
     2. under each group heading, on scroll
     3. as the confirm list progress meter, where it carries real data
     4. as the left rule on each confirm row
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Tokens
   Read from style.css where they exist, with the literal value as a fallback
   so this file survives the stylesheet being renamed or rewritten.
   -------------------------------------------------------------------------- */
:root{
  --mo-navy:var(--navy,#0A2B7C);
  --mo-navy-deep:var(--navy-deep,#071E58);
  --mo-navy-lite:#9FB4E8;              /* the hero accent, already in style.css */
  --mo-graphite:var(--graphite,#414042);
  --mo-signal:var(--signal,#B26B00);
  --mo-signal-soft:var(--signal-soft,#FDF3E2);
  --mo-signal-line:#D6B888;            /* #B26B00 at 45% over the paper */
  --mo-signal-ink:#6B4300;             /* text on signal-soft, 7.8:1 */
  --mo-ink:var(--ink,#14181F);
  --mo-ink-2:var(--ink-2,#4A525C);
  --mo-muted:var(--muted,#646D78);
  --mo-rule:var(--rule,#D3D8DE);
  --mo-surface:var(--surface,#FFFFFF);
  --mo-paper:var(--paper,#F4F6F8);
  --mo-ease:cubic-bezier(.2,.7,.3,1);
  --mo-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --mo-display:Archivo,"Arial Narrow",sans-serif;
}

/* --------------------------------------------------------------------------
   1. Scroll reveal
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:no-preference){
  .mo-on.mo-js .mo-reveal{
    opacity:0;transform:translateY(14px);
    transition:opacity 620ms var(--mo-ease),transform 620ms var(--mo-ease);
    transition-delay:calc(var(--mo-i,0) * 70ms);
    will-change:opacity,transform;
  }
  .mo-on.mo-js .mo-reveal.mo-in{opacity:1;transform:none;will-change:auto}
}

/* style.css sets .rise{opacity:0} in CSS with no guard. If reveal.js fails to
   load or throws, every .rise block on the site stays invisible for good.
   This puts them back until a script confirms it is running. */
html:not(.mo-js) .rise{opacity:1;transform:none}

/* the ruled line, second use: group headings draw their own underline */
@media (prefers-reduced-motion:no-preference){
  .mo-on.mo-js .mo-rule-in{
    background-image:linear-gradient(var(--mo-ink),var(--mo-ink));
    background-repeat:no-repeat;background-position:0 100%;
    background-size:0% 1px;border-bottom-color:transparent;
    transition:background-size 620ms var(--mo-ease);
  }
  .mo-on.mo-js .mo-rule-in.mo-in{background-size:100% 1px}
}

/* --------------------------------------------------------------------------
   2. Interactive elements
   Additive only. These rules add transition and press feedback to controls
   style.css already colours. No colour, size or layout is changed here.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:no-preference){
  .mo-on .nav a{transition:color 160ms var(--mo-ease),border-bottom-color 200ms var(--mo-ease)}
  .mo-on a:not(.btn){transition:color 160ms var(--mo-ease)}
  .mo-on .btn{transition:background-color 180ms var(--mo-ease),border-color 180ms var(--mo-ease),
              color 180ms var(--mo-ease),transform 110ms var(--mo-ease)}
  .mo-on .enq input,.mo-on .enq select,.mo-on .enq textarea{transition:border-color 160ms var(--mo-ease)}
  .mo-on .masthead{transition:box-shadow 220ms var(--mo-ease)}
}
/* a press is a state change, not an animation, so it survives reduced motion */
.mo-on .btn{touch-action:manipulation;-webkit-tap-highlight-color:rgba(10,43,124,.12)}
.mo-on .btn:active{transform:translateY(1px)}
.mo-on.mo-scrolled .masthead{box-shadow:0 1px 0 rgba(20,24,31,.09),0 6px 18px -12px rgba(20,24,31,.35)}

/* --------------------------------------------------------------------------
   3. The hero specification figures
   2,000 units. 3 to 4 weeks. 50%. $500. These four numbers are the whole
   commercial argument, so nothing here touches their opacity. They are at
   full contrast on the first painted frame and they never move position.
   What animates is the rule underneath: it draws left to right, cell by
   cell, the way a figure gets ruled off on a spec sheet. The figure itself
   settles from 103.5% to 100%, which lands weight without hiding anything.
   -------------------------------------------------------------------------- */
.mo-spec .val{
  display:inline-block;padding-bottom:.18em;
  background-image:linear-gradient(var(--mo-navy-lite),var(--mo-navy-lite));
  background-repeat:no-repeat;background-position:0 100%;background-size:100% 2px;
}
.mo-spec .note{margin-top:.35rem}

@media (prefers-reduced-motion:no-preference){
  /* style.css fades the whole cell up from opacity 0, which delays the
     numbers. Two classes beat its one class plus type, so load order between
     the two files does not matter. */
  .mo-on.mo-js .mo-spec.spec > div{opacity:1;transform:none;animation:none}

  .mo-on.mo-js .mo-spec .val{
    background-size:0% 2px;transform:scale(1.035);transform-origin:0 100%;
    transition:background-size 520ms var(--mo-ease),transform 560ms var(--mo-ease);
    transition-delay:calc(var(--mo-i,0) * 90ms);
  }
  .mo-on.mo-js .mo-spec.mo-in .val{background-size:100% 2px;transform:none}
}

/* ==========================================================================
   4. The confirm list
   Self contained: no .mo-on needed, and it works with JavaScript switched
   off, because the control is three real radio inputs in a radiogroup.
   JavaScript adds three things and nothing else: persistence, the progress
   meter, and the summary readout.
   ========================================================================== */

.mo-cl{
  background:var(--mo-surface);
  border:1px solid var(--mo-signal-line);
  margin:0 0 1.2rem;
}

/* the eyebrow, defined here as well as inherited from .field, so the
   component still reads correctly if style.css renames that class */
.mo-cl__field{
  display:block;margin:0 0 .5rem;
  font-family:var(--mo-mono);font-size:.76rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--mo-muted);
}

/* the internal note, kept as the existing amber block */
.mo-cl__note{
  background:var(--mo-signal-soft);
  border-left:3px solid var(--mo-signal);
  padding:1rem 1.15rem;
}
.mo-cl__note .field{color:var(--mo-signal)}
.mo-cl__note p{font-size:.93rem;color:var(--mo-signal-ink);margin:0;max-width:62ch}

/* --- how to use it, said once, in plain words --------------------------- */
.mo-cl__how{
  padding:1rem 1.15rem .95rem;
  border-bottom:1px solid var(--mo-rule);
}
.mo-cl__how h3{
  font-family:var(--mo-display);font-weight:800;font-size:1.14rem;
  line-height:1.2;margin:0 0 .3rem;color:var(--mo-ink);
}
.mo-cl__how p{font-size:.95rem;color:var(--mo-ink-2);margin:0;max-width:52ch}

/* --- progress: the ruled line, third use -------------------------------- */
.mo-cl__progress{padding:.9rem 1.15rem 1rem;border-bottom:1px solid var(--mo-rule)}
.mo-cl__count{
  font-family:var(--mo-mono);font-size:.78rem;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--mo-signal);margin:0 0 .5rem;
}
.mo-cl__progress[data-mo-complete="true"] .mo-cl__count{color:var(--mo-navy)}
.mo-cl__meter{position:relative;height:3px;background:var(--mo-rule);overflow:hidden}
.mo-cl__meter::after{
  content:"";position:absolute;inset:0;background:var(--mo-signal);
  transform:scaleX(var(--mo-p,0));transform-origin:0 50%;
}
.mo-cl__progress[data-mo-complete="true"] .mo-cl__meter::after{background:var(--mo-navy)}
@media (prefers-reduced-motion:no-preference){
  .mo-cl__meter::after{transition:transform 420ms var(--mo-ease),background-color 300ms var(--mo-ease)}
}

/* --- a group of items --------------------------------------------------- */
.mo-cl__group{padding:1.15rem 1.15rem .4rem}
.mo-cl__group + .mo-cl__group{border-top:1px solid var(--mo-rule)}
.mo-cl__gh{
  display:flex;align-items:baseline;justify-content:space-between;gap:.8rem;
  flex-wrap:wrap;border-bottom:1px solid var(--mo-ink);
  padding-bottom:.5rem;margin:0 0 .5rem;
}
.mo-cl__gh h3{
  font-family:var(--mo-display);font-weight:700;font-size:1.16rem;line-height:1.2;
  letter-spacing:-.005em;margin:0;color:var(--mo-ink);
}
.mo-cl__gcount{
  font-family:var(--mo-mono);font-size:.76rem;letter-spacing:.08em;
  color:var(--mo-muted);white-space:nowrap;
}

/* --- the list ----------------------------------------------------------- */
.mo-cl__list{list-style:none;margin:0;padding:0}
.mo-cl__i{
  position:relative;padding:.9rem 0 1rem .9rem;
  border-bottom:1px solid var(--mo-rule);
}
.mo-cl__i:last-child{border-bottom:0}

/* the ruled line, fourth use. Dashed while the answer is still open,
   solid once it is settled, so the state does not rely on colour alone. */
.mo-cl__i::before{
  content:"";position:absolute;left:0;top:.9rem;bottom:1rem;width:3px;
  background:repeating-linear-gradient(to bottom,
    var(--mo-signal-line) 0 6px,transparent 6px 11px);
}
.mo-cl__i[data-mo-state="yes"]::before{background:var(--mo-navy)}
.mo-cl__i[data-mo-state="no"]::before{background:var(--mo-graphite)}
.mo-cl__i[data-mo-state="unsure"]::before{background:var(--mo-signal)}
@media (prefers-reduced-motion:no-preference){
  .mo-cl__i::before{transition:background-color 260ms var(--mo-ease)}
  /* .mo-armed is added by motion.js, so with no script the rules are simply
     drawn. .mo-in arrives when the list scrolls into view. */
  .mo-cl.mo-armed .mo-cl__i::before{
    transform:scaleY(0);transform-origin:50% 0;
    transition:transform 460ms var(--mo-ease) calc(var(--mo-i,0) * 45ms),
               background-color 260ms var(--mo-ease);
  }
  .mo-cl.mo-armed.mo-in .mo-cl__i::before{transform:scaleY(1)}
}

.mo-cl__n{
  display:block;font-family:var(--mo-display);font-weight:700;font-stretch:105%;
  font-size:1.06rem;line-height:1.25;margin:0 0 .6rem;color:var(--mo-ink);
}
.mo-cl__i[data-mo-state="yes"] .mo-cl__n{color:var(--mo-navy)}
.mo-cl__i[data-mo-state="no"] .mo-cl__n{color:var(--mo-graphite)}
/* opt in, per list: a struck line is the fastest read of "not any more".
   It only makes sense where the item is a thing the plant either runs or
   does not, so about.html leaves it off. */
.mo-cl--strike .mo-cl__i[data-mo-state="no"] .mo-cl__n{text-decoration:line-through}
@media (prefers-reduced-motion:no-preference){
  .mo-cl__n{transition:color 220ms var(--mo-ease)}
}

/* --- the control: three real radios, thumb sized ------------------------ */
.mo-cl__opts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.4rem}
.mo-cl__opt{
  position:relative;display:block;margin:0;cursor:pointer;
  touch-action:manipulation;-webkit-tap-highlight-color:rgba(178,107,0,.14);
}
/* hidden from sight, never from focus or the accessibility tree */
.mo-cl__opt input{
  position:absolute;width:1px;height:1px;margin:0;padding:0;border:0;
  clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;white-space:nowrap;
}
.mo-cl__face{
  display:flex;align-items:center;justify-content:center;text-align:center;
  min-height:48px;padding:.65rem .5rem;
  font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,sans-serif;
  font-size:.94rem;line-height:1.2;font-weight:500;
  background:var(--mo-surface);border:1px solid var(--mo-rule);
  color:var(--mo-ink-2);
}
@media (prefers-reduced-motion:no-preference){
  .mo-cl__face{transition:background-color 170ms var(--mo-ease),
    border-color 170ms var(--mo-ease),color 170ms var(--mo-ease)}
}
@media (hover:hover){
  .mo-cl__opt:hover input:not(:checked) + .mo-cl__face{
    border-color:var(--mo-navy);color:var(--mo-navy)}
}
.mo-cl__opt:active .mo-cl__face{transform:translateY(1px)}

/* answered states. Contrast against white: navy 12.7:1, graphite 10.3:1,
   and the amber is an outline rather than a fill so its text can be
   #6B4300 on #FDF3E2 at 7.8:1. A filled #B26B00 with white text is 4.2:1
   and would have failed. */
.mo-cl__opt input[data-mo-tone="yes"]:checked + .mo-cl__face{
  background:var(--mo-navy);border-color:var(--mo-navy);color:#fff;font-weight:600}
.mo-cl__opt input[data-mo-tone="no"]:checked + .mo-cl__face{
  background:var(--mo-graphite);border-color:var(--mo-graphite);color:#fff;font-weight:600}
.mo-cl__opt input[data-mo-tone="unsure"]:checked + .mo-cl__face{
  background:var(--mo-signal-soft);border:2px solid var(--mo-signal);
  color:var(--mo-signal-ink);font-weight:600}

/* focus. INTEGRATION 2026-08-27: was an amber ring with a navy exception on the
   amber chip. The visual system reserves amber for "needs confirmation" and
   rings everything navy at a 3px offset (style.css section 18), so the ring
   lands on the row's white ground rather than on the chip. Navy on white is
   12.7:1 and it reads on all three chips, including the navy-filled Yes,
   because of the offset. The old amber-chip exception is now the rule. */
.mo-cl__opt input:focus + .mo-cl__face{outline:3px solid var(--mo-navy);outline-offset:3px}
.mo-cl__opt input:focus:not(:focus-visible) + .mo-cl__face{outline:none}
.mo-cl__opt input:focus-visible + .mo-cl__face{outline:3px solid var(--mo-navy);outline-offset:3px}

/* one short acknowledgement that the tap registered */
@media (prefers-reduced-motion:no-preference){
  .mo-cl__i--just{animation:mo-ack 560ms var(--mo-ease)}
  @keyframes mo-ack{
    0%{background:rgba(178,107,0,.10)}
    100%{background:transparent}
  }
}

/* --- the readout -------------------------------------------------------- */
.mo-cl__panel{padding:1.15rem;border-top:1px solid var(--mo-rule);background:var(--mo-paper)}
.mo-cl__panel .field{color:var(--mo-muted)}
.mo-cl__sum{margin:0 0 1rem}
.mo-cl__sum dl{margin:0;display:grid;gap:.55rem}
.mo-cl__sum div{
  display:grid;gap:.15rem .9rem;
  grid-template-columns:minmax(0,1fr);
  padding-bottom:.55rem;border-bottom:1px solid var(--mo-rule);
}
.mo-cl__sum div:last-child{border-bottom:0;padding-bottom:0}
.mo-cl__sum dt{
  font-family:var(--mo-mono);font-size:.72rem;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--mo-muted);
}
.mo-cl__sum dd{margin:0;font-size:1rem;line-height:1.45;color:var(--mo-ink)}
.mo-cl__sum div[data-mo-k="open"] dt{color:var(--mo-signal)}
.mo-cl__empty{font-size:.95rem;color:var(--mo-muted);margin:0}
.mo-cl__warn{
  font-size:.9rem;line-height:1.45;color:var(--mo-signal-ink);
  background:var(--mo-signal-soft);border-left:3px solid var(--mo-signal);
  padding:.6rem .8rem;margin:0 0 1rem;
}
.mo-cl__acts{display:grid;grid-template-columns:1fr 1fr;gap:.5rem}
.mo-cl__btn{
  min-height:48px;padding:.7rem .9rem;cursor:pointer;
  font-family:var(--mo-display);font-weight:700;font-stretch:105%;font-size:.97rem;
  background:var(--mo-navy);border:2px solid var(--mo-navy);color:#fff;
  touch-action:manipulation;-webkit-tap-highlight-color:rgba(10,43,124,.12);
}
.mo-cl__btn--quiet{background:transparent;border-color:var(--mo-rule);color:var(--mo-ink-2)}
.mo-cl__btn[disabled]{opacity:.45;cursor:default}
.mo-cl__btn[data-mo-armed]{background:var(--mo-signal);border-color:var(--mo-signal);color:#fff}
.mo-cl__btn:active{transform:translateY(1px)}
@media (hover:hover){
  .mo-cl__btn:not([disabled]):hover{background:var(--mo-navy-deep);border-color:var(--mo-navy-deep);color:#fff}
  .mo-cl__btn--quiet:not([disabled]):hover{background:var(--mo-graphite);border-color:var(--mo-graphite)}
}
@media (prefers-reduced-motion:no-preference){
  .mo-cl__btn{transition:background-color 180ms var(--mo-ease),border-color 180ms var(--mo-ease),
              color 180ms var(--mo-ease),transform 110ms var(--mo-ease)}
}

/* --- wider than a phone ------------------------------------------------- */
@media (min-width:700px){
  .mo-cl__note,.mo-cl__how,.mo-cl__progress,.mo-cl__group,.mo-cl__panel{
    padding-left:1.5rem;padding-right:1.5rem}
  .mo-cl__list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:1.8rem}
  .mo-cl__i{border-bottom:1px solid var(--mo-rule)}
  .mo-cl__sum div{grid-template-columns:11rem minmax(0,1fr);align-items:baseline}
  .mo-cl__acts{grid-template-columns:auto auto;justify-content:start}
  .mo-cl__btn{padding-left:1.5rem;padding-right:1.5rem}
}
