/* ===========================================================================
   BadgeBox landing — the «Agents» section.

   THE IDEA: every row is a PARALLEL. On the left the product feature where
   that thing is done, with its real screenshot and the steps you would take
   by hand; on the right the time and what the agent did in your place. The
   comparison reads horizontally, not from memory between one section and
   the next, and in the order it is read: first how it is done today, then
   how it is already done.

   Above, a bar that stays with you while you scroll: the numbers go up and
   the status line changes. The motion doesn't decorate — it is the proof of
   the sentence «lavorano al posto tuo», and the time passing is the scroll.

   WHAT HAPPENS WITHOUT JAVASCRIPT, and it must be read before touching
   anything: the steps are already all lit, the counters already show the
   total (it is in the markup) and the status line is the final one. In here
   NOTHING hides without `html.js` in front — it is the contract of
   motion.css, and this section honours it like the others.

   Vocabulary: `ag-`, like `mg-` for the AI section. Everything from the
   tokens in tokens.css: no new colour and no new radius is born here.
   =========================================================================== */

.ag { margin-top: var(--lp-6); }

/* ── THEM, staying ────────────────────────────────────────────────────────
   A BAR and not a column: the two columns of the parallel belong to the
   steps, and a third column stuck on the side would leave the screenshot at
   four hundred pixels, that is unreadable. Above, instead, it takes seventy
   pixels and stays with you for the whole section.

   `sticky` and not `fixed`: it must stay inside the section and leave the
   stage with it. The `top` is the header height plus some air — if the
   header changes height, this number follows it. */
.ag__agent {
    position: sticky;
    /* 75 = the sticky header (63) plus a little air. */
    top: 75px;
    z-index: 3;
    margin-bottom: var(--lp-6);
}

/* Three columns and two rows: who they are on the left, what they are doing
   and what is left to you in the middle, the numbers on the right. On a
   single row they didn't fit — «what is left to you» wrapped and took a
   second row all to itself, bringing the bar to a hundred and twenty pixels.
   A sticky bar an eighth of the screen tall doesn't accompany the reading:
   it covers it. */
.ag__card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "who status counts"
                         "who you    counts";
    align-items: center;
    column-gap: clamp(16px, 2.4vw, 32px);
    row-gap: 2px;
    padding: var(--lp-3) var(--lp-4);
    background: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: var(--lp-radius-card);
    box-shadow: var(--bbx-shadow-md);
}

.ag__who { grid-area: who; display: flex; align-items: center; gap: var(--lp-3); }

.ag__face {
    position: relative;
    flex: 0 0 auto;
    width: 36px; height: 36px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--lp-accent-tint);
    color: var(--lp-accent);
}

.ag__name { display: grid; line-height: 1.25; min-width: 0; }
.ag__name b { font-size: 14.5px; font-weight: 700; color: var(--lp-ink); }
.ag__name i { font-size: 12px; font-style: normal; color: var(--lp-ink-soft); }

/* The status line: it changes as you scroll down, and it is their voice.
   One line only and in the middle, because it is the only thing in the bar
   that MOVES: placed at the end it would get lost among the numbers. */
.ag__status {
    grid-area: status;
    margin: 0;
    font-size: 14px;
    line-height: 1.35;
    color: var(--lp-ink);
}

/* ── the three numbers ───────────────────────────────────────────────────
   Tabular figures: going up, a number that changes width makes the one next
   to it dance. */
.ag__counts {
    grid-area: counts;
    display: flex;
    align-items: baseline;
    gap: clamp(14px, 2vw, 26px);
    margin: 0;
}
.ag__counts > div {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
    /* The negative indent keeps the veil as WIDE as needed without widening
       the bar: the margin offsets the padding, and at rest it doesn't show. */
    padding: 3px 8px;
    margin: -3px -8px;
    border-radius: var(--lp-radius-control);
}
.ag__counts dd {
    margin: 0;
    font-size: 22px;
    font-weight: 800;
    line-height: 1;
    color: var(--lp-ink);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.ag__counts dt {
    font-size: 11.5px;
    line-height: 1.2;
    color: var(--lp-ink-soft);
}

/* What is left to you: under the status line, in the same column. They are
   the two things that CHANGE as you scroll down, and they sit close for that. */
.ag__you {
    grid-area: you;
    margin: 0;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--lp-ink-soft);
}

/* ── the steps ───────────────────────────────────────────────────────────
   The vertical thread joining them is the day going by. It starts at the
   first dot and ends at the last: drawing it along the whole column would
   leave two stubs above and below. */
.ag__steps {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}
/* THE THREAD IS IN THE MIDDLE, and it is a change of meaning before one of
   position: on the edge it was a progress bar beside a list, in the middle
   it is the SPINE of the parallel — everything on the left you would do,
   everything on the right they did. To really sit there the two columns
   must be equal: with .82fr/1fr the gap between them doesn't fall at fifty
   percent, and an «almost» centred line looks crooked. */
.ag__steps::before {
    content: "";
    position: absolute;
    left: 50%; margin-left: -1px;
    top: 12px; bottom: 12px;
    width: 2px;
    background: var(--lp-border);
}

/* Every step is a grid of TWO EQUAL HALVES, even the one without a
   screenshot: so the agent's text always has the same width and the thread
   always falls at the same point. A step without a second half leaves its
   cell empty — which is exactly what «there is no screenshot to put
   alongside here» means. */
.ag__step {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(28px, 3.5vw, 56px);
    align-items: center;
    padding: 0 0 clamp(40px, 5vw, 72px);
}
.ag__step:last-child { padding-bottom: 0; }

/* the dot on the thread */
/* The dot stays at the top of the step even when the two columns are
   centred: it is the mark on the timeline, and halfway down it would no
   longer mark the start of anything. */
.ag__step::before {
    content: "";
    position: absolute;
    left: 50%; top: 7px;
    transform: translateX(-50%);
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--lp-surface);
    border: 2px solid var(--lp-border);
}

/* The two halves face each other at the CENTRE and not at the top: two
   lines of text next to a screenshot four hundred pixels tall, aligned at
   the top, leave a hole that reads as «something is missing here».

   The dot instead stays at the TOP (below): it is the mark on the timeline,
   and halfway down it would no longer mark the start of anything. */

/* ── on the left:  the feature, with its screenshot ───────────────────── */
/* ── on the right: the time, and what they did in your place ─────────── */

/* Both halves breathe away from the thread: the grid gap splits it in half,
   and without this the text would end up on top of it. */
.ag__left { min-width: 0; }
.ag__right { min-width: 0; }

/* A step WITHOUT a parallel stays in the agent's column, which here is the
   second one: left to fall where the grid puts it on its own (the first),
   the agent's voice would jump from one side to the other between one step
   and the next, and the thread in the middle would no longer divide
   anything. */
.ag__step--solo .ag__right { grid-column: 2; }

.ag__when {
    display: flex;
    align-items: baseline;
    gap: var(--lp-3);
    margin: 0 0 var(--lp-2);
}

.ag__time {
    font-size: 15px;
    font-weight: 800;
    color: var(--lp-ink);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* «Lo fa l'agente» / «Lo faresti tu»: the two labels of the parallel. They
   sit on the same line on the left and on the right, and they are the only
   thing that says which column is which — without them, two blocks of text
   side by side are just two blocks of text. */
.ag__actor,
.ag__byhand {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.ag__actor { color: var(--lp-accent); }

/* The label of the manual gestures sits ATTACHED to the gestures, not in
   the column header: up there it was separated from the list it names by the
   whole height of a screenshot, and a label far from what it labels labels
   nothing. */
.ag__byhand {
    display: block;
    margin: var(--lp-4) 0 var(--lp-2);
    color: var(--lp-ink-soft);
}

.ag__sentence {
    margin: 0;
    font-size: 16px;
    line-height: 1.55;
    color: var(--lp-ink);
}

/* ── the line ────────────────────────────────────────────────────────────
   Two voices, and they are told apart by which side they are on: what THEY
   write has the blue rule on the left, what a PERSON replies is a solid fill
   with the rule on the other side. They are two directions, not two colours. */
.ag__bubble {
    margin: var(--lp-3) 0 0;
    padding: var(--lp-3) var(--lp-4);
    border-left: 2px solid var(--lp-accent);
    border-radius: 0 var(--lp-radius-control) var(--lp-radius-control) 0;
    background: var(--lp-accent-tint);
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--lp-ink);
}
.ag__bubble--theirs {
    border-left: 0;
    border-right: 2px solid var(--bbx-gray-300);
    border-radius: var(--lp-radius-control) 0 0 var(--lp-radius-control);
    background: var(--bbx-gray-50);
    margin-left: var(--lp-6);
}
.ag__bubble cite {
    display: block;
    margin-top: 4px;
    font-size: 12.5px;
    font-style: normal;
    color: var(--lp-ink-soft);
}

/* What is left to you. It is there where it makes sense, not out of
   modesty: a comparison where one column does everything and the other
   nothing is believed by nobody. */
.ag__remaining {
    margin: var(--lp-3) 0 0;
    padding-left: var(--lp-4);
    border-left: 2px solid var(--bbx-gray-200);
    font-size: 13px;
    line-height: 1.45;
    color: var(--lp-ink-soft);
}

/* The step waiting for a person: it is the thing that sets the product
   apart, and it shows — the dot turns solid and the sentence carries the
   accent rule. */
.ag__step.is-foryou::before {
    background: var(--lp-accent);
    border-color: var(--lp-accent);
}
.ag__step.is-foryou .ag__sentence {
    padding-left: var(--lp-4);
    border-left: 2px solid var(--lp-accent);
}

/* ── the feature column: the name, the screenshot, the steps by hand ── */

.ag__where { margin: 0 0 var(--lp-3); }

.ag__section {
    font-size: 15px;
    font-weight: 800;
    color: var(--lp-ink);
}

/* `.shot` is the house frame (landing.css) and already carries everything:
   border, radius, shadow, `overflow: hidden`, and above all the IMAGE
   RECIPE — `width: 107.2%` with `margin-left: -7.2%`, which pushes the
   application's icon column out of the frame and keeps only the content
   inside.

   So here NOTHING is redeclared on the image: a `width: 100%` line written
   later weighs the same, wins by order and switches the recipe off without
   a trace — plus a second radius inside a container that already has its
   own. */
.ag__screen { margin: 0; }

/* The steps by hand: numbered, because the point is that there are three
   or four and you do them EVERY TIME. The number is the content, not a
   bullet list in disguise. */
.ag__hand {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: ag;
}
.ag__hand li {
    counter-increment: ag;
    position: relative;
    padding: 0 0 var(--lp-2) 26px;
    font-size: 14px;
    line-height: 1.45;
    color: var(--lp-ink-soft);
}
.ag__hand li:last-child { padding-bottom: 0; }
.ag__hand li::before {
    content: counter(ag);
    position: absolute;
    left: 0; top: 1px;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: var(--bbx-gray-100);
    color: var(--lp-ink-soft);
    font-size: 11px;
    font-weight: 700;
    display: grid;
    place-items: center;
}

/* ===========================================================================
   THE MOTION — all behind html.js, and all reversible
   =========================================================================== */

/* ── THE TIME PASSING ────────────────────────────────────────────────────
   A step without a screenshot takes a third of the screen: it isn't air, it
   is the DURATION, and it is the only thing that makes the title's sentence
   true. Measured without it: scrolling down the steps jumped two at a time,
   and the day ended before anyone noticed something was happening.

   The steps with a PARALLEL don't need it: a screenshot is already half a
   screen tall on its own, and a minimum on top would add emptiness.

   Only under `html.js`: without JavaScript there is nothing to make happen,
   and blocks half a screen tall would be screens of white. There the
   section stays a compact list, which is the right form for a still thing. */
html.js .ag__step--solo {
    min-height: 32vh;
    align-content: start;
}

/* The last one needs no space below it: the section ends, and half a
   screen of emptiness before the big sentence would detach it from what has
   just proved it. */
html.js .ag__step:last-child { min-height: 0; }

/* The steps arrive dimmed and light up as you pass. Not `filter`: it also
   fades the text inside the bubbles and makes it unreadable mid-transition.
   Only opacity, and not down to zero — an invisible step makes the column
   look shorter than it is, and the page jumps. */
html.js .ag__step {
    opacity: .38;
    transition: opacity var(--mo-base) var(--mo-ease);
}
html.js .ag__step.is-now { opacity: 1; }

/* The ones already passed stay readable: it is the work DONE, and it is the
   point of the section. Dimming them would say they no longer count. */
html.js .ag__step.is-done { opacity: .8; }

html.js .ag__step::before {
    transition: background var(--mo-base) var(--mo-ease),
                border-color var(--mo-base) var(--mo-ease);
}
html.js .ag__step.is-done::before,
html.js .ag__step.is-now::before { border-color: var(--lp-accent); }
html.js .ag__step.is-done::before { background: var(--lp-accent); }

/* The thread is coloured up to where it got: it is the progress of the day.
   The scale starts from the top, so it grows downwards as you read. */
html.js .ag__steps::after {
    content: "";
    position: absolute;
    left: 50%; margin-left: -1px;
    top: 12px; bottom: 12px;
    width: 2px;
    background: var(--lp-accent);
    transform: scaleY(var(--ag-advance, 0));
    transform-origin: top;
    transition: transform var(--mo-base) var(--mo-ease);
}

/* The face breathes ONLY while it is working: a still bar that pulses
   would say it is doing something when it has finished. It is the same rule
   as the Agents section in the product — only what is on moves. */
html.js .ag__card.is-working .ag__face { animation: ag-breathe 2.4s ease-in-out infinite; }

@keyframes ag-breathe {
    0%, 100% { box-shadow: 0 0 0 0 rgba(0, 128, 246, .28); }
    50%      { box-shadow: 0 0 0 7px rgba(0, 128, 246, 0); }
}

/* ── WHAT JUST HAPPENED, at the top ──────────────────────────────────────
   The bar stays still while the steps scroll: if it said nothing, whoever
   scrolls down would read it once and then stop looking at it — and with it
   would stop seeing that the work is going on. So at every change three
   things happen together, and they are three on purpose: just one, on a bar
   a thousand pixels wide, gets lost.

   1 · THE NUMBER jumps and takes the accent colour. It turns black again by
       itself: a number that stays blue would say «this one is different from
       the others», and it isn't. */
html.js .ag__counts dd {
    transition: transform 260ms var(--mo-ease), color 420ms var(--mo-ease);
}
html.js .ag__counts dd.is-up {
    transform: translateY(-3px) scale(1.14);
    color: var(--lp-accent);
}

/* 2 · ITS BOX lights up with a veil, label included: it says WHICH of the
       three counts moved, which the number alone can't say. */
html.js .ag__counts > div {
    transition: background-color 420ms var(--mo-ease);
}
html.js .ag__counts > div.is-changed { background: var(--lp-accent-tint); }

/* 3 · THE FACE makes a ring. It is the signal that holds for ALL changes,
       even when only the status line moves and no number does.
       It sits on a pseudo-element and not on the face, because the face
       already has its breathing and two `animation`s on the same node cancel
       one out: the ring would have switched the breathing off for half a
       second, and it would have shown as a jerk. */
html.js .ag__face::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    pointer-events: none;
}
html.js .ag__face.is-snap::after { animation: ag-snap 620ms var(--mo-ease) both; }

@keyframes ag-snap {
    from { box-shadow: 0 0 0 0 rgba(0, 128, 246, .5); }
    to   { box-shadow: 0 0 0 14px rgba(0, 128, 246, 0); }
}

/* AND THE LINES THAT SPEAK fade out and come back, instead of swapping
   abruptly: out of the corner of the eye a word that turns into another word
   reads as a drawing error. The script writes the text halfway through the
   fade, so the switch is never seen. */
html.js .ag__status,
html.js .ag__you {
    transition: opacity 170ms var(--mo-ease), transform 170ms var(--mo-ease);
}
html.js .ag__status.is-changing,
html.js .ag__you.is-changing { opacity: 0; transform: translateY(4px); }

/* ===========================================================================
   WHOEVER DOESN'T WANT MOTION — and whoever doesn't have the room
   =========================================================================== */

/* The FINAL state, not less stuff: steps lit, thread full, nothing pulsing.
   It is the house rule, and here it counts double — the section PROVES
   something, and a half-shown proof isn't understood. */
@media (prefers-reduced-motion: reduce) {
    html.js .ag__step--solo { min-height: 0; }
    html.js .ag__step,
    html.js .ag__step.is-now,
    html.js .ag__step.is-done { opacity: 1; transition: none; }
    html.js .ag__steps::after { transform: scaleY(1); transition: none; }
    html.js .ag__card.is-working .ag__face { animation: none; }
    html.js .ag__face.is-snap::after { animation: none; }
    html.js .ag__counts dd,
    html.js .ag__counts > div,
    html.js .ag__status,
    html.js .ag__you { transition: none; }
    html.js .ag__status.is-changing,
    html.js .ag__you.is-changing { opacity: 1; transform: none; }
}

@media (max-width: 1000px) {
    /* The parallel stacks: the screenshot goes BELOW the text, not beside it.
       At this width placing them side by side leaves half a column each, and
       the screenshot becomes a postage stamp. */
    .ag__step { grid-template-columns: 1fr; gap: var(--lp-5); padding-left: var(--lp-6); }

    /* And the thread goes back to the EDGE. Stacked, there are no longer two
       halves to divide: a line in the middle would run through the words. */
    .ag__steps::before,
    html.js .ag__steps::after { left: 5px; margin-left: 0; }
    .ag__step::before { left: 0; transform: none; }

    /* Stacked, «on the left» and «on the right» no longer mean anything:
       what holds the two halves together is a hairline, not the position.
       It sits on the SECOND one — the agent's column — and only where the
       parallel really exists: on a solo step it would be a hairline above
       nothing.

       And there the second column no longer exists: a `grid-column: 2` in a
       one-column grid would open an implicit one, i.e. half a row of empty
       space to the left of every step without a parallel. */
    .ag__step--pair .ag__right { padding-top: var(--lp-4); border-top: 1px solid var(--lp-border); }
    .ag__step--solo .ag__right { grid-column: 1; }
}

@media (max-width: 900px) {
    /* On a narrow screen a third of a screen per step would be an endless
       scroll, and the bar isn't still anyway. */
    html.js .ag__step--solo { min-height: 0; }

    /* Below 900 the bar stops being sticky: stuck on a narrow screen it would
       eat half the page, and what must stay readable are the steps. */
    .ag__agent { position: static; }

    /* And it stacks: three things in a row on 390px are three unreadable
       things. */
    .ag__card {
        grid-template-columns: 1fr;
        grid-template-areas: "who" "status" "you" "counts";
        row-gap: var(--lp-3);
    }
    .ag__counts { flex-wrap: wrap; }

    .ag__bubble--theirs { margin-left: var(--lp-4); }
}

@media (max-width: 560px) {
    .ag__step { padding-left: var(--lp-5); }

    .ag__counts dd { font-size: 20px; }
    .ag__bubble--theirs { margin-left: 0; }
}
