/* ══════════════════════════════════════════════════════════════════════════
   Decision tree — one generated insight, and the decisions it forces
   ══════════════════════════════════════════════════════════════════════════

   Beside "Built to Drive Better Leadership Decisions". The sentence in that
   column says BeSync'd makes key insights accessible to everyone who needs
   them, and that configurable permissions give each person the right level of
   detail. Read plainly, that is a claim about consequence: a report says one
   thing, and three different roles have to decide three different things about
   it. So the graphic puts an insight at the top and decisions underneath.

   ── Why the root is a sentence, not a label ───────────────────────────────
   The earlier version labelled the root "Key insights", which named the
   category and showed nothing. A category cannot force a decision, so the
   branches underneath it had no visible cause and the tree argued nothing.
   The root now carries one insight written in the register the product's own
   generated text uses: third person, full sentences, a named department, a
   named blocker, no metrics, and no source system quoted. The reference is the
   "Team Insights" section of besyncd-app's report template sample data
   (data/report-template/defaultTemplateData.ts) and the "Team Insights" tab in
   components/app/TeamBriefing.vue. The sentence is held to about twenty words, so it sets in two or three lines
   and stays a headline rather than a paragraph. The insight itself is fictional: no real
   person, customer or company appears in it.

   ── Why the branches are decisions ───────────────────────────────────────
   Each child node states a decision in the imperative, because a decision is
   something somebody does, and pairs it with the outcome the live page already
   promises for that role. The role tag is on the node rather than being the
   node, which is the difference from the earlier version: the earlier cards
   were roles that happened to contain text, so the graphic read as an audience
   list. These are decisions that happen to belong to a role.

   ── Why there are two decisions and not three ────────────────────────────
   Three cards is the whole graphic: the insight and two decisions. The section
   is titled "Built to Drive Better Leadership Decisions", so the two decisions
   kept are the two leadership-facing roles the copy names, managers and
   executive leadership. Team members appear in the copy column's own sentence
   and are deliberately absent here, including from the aria-label, because a
   graphic that narrates a role it does not draw describes something the reader
   cannot see.

   ── Why it is portrait ───────────────────────────────────────────────────
   The graphic sits in the right half of a two-column section next to roughly
   400 words of copy, so its column is tall and narrow, and a landscape graphic
   leaves dead space beside the list it is illustrating. Three side-by-side
   cards also cannot hold a sentence each: at a third of a 420px column a line
   is about six words, which forces the type below 14px. Stacking the three
   decisions in one column gives every sentence the full width, keeps all body
   text at 14px, and makes the tree read top to bottom in the same direction as
   the copy beside it.

   ── Geometry: how the trunk and branches are drawn ────────────────────────
   The tree is one CSS grid of two columns: a narrow rail column on the left
   that holds every line, and a content column on the right that holds the root
   and the three decision nodes. Rows alternate node, gap, node, gap, node, so
   each node's row is exactly as tall as the node, and 50% of a row is
   therefore 50% of the node in it. That single fact is what lets every
   connector land on a node's vertical centre without a hard-coded offset.

     .dtree__stem   row 2, the short vertical leaving the root's underside
     .dtree__rail   rows 3 to 4, the continuous trunk past the first node
     .dtree__drop   one per node: the horizontal branch into that node, at 50%
                    of its own row; the third drop also draws the trunk's last
                    segment and stops at 50%, so the trunk ends on the final
                    branch instead of running past it
     .dtree__card::before   the arrowhead, a CSS triangle whose tip sits on the
                    node's own left border, so the arrow touches what it points
                    into rather than hovering beside it

   Lines are CSS boxes rather than an inline SVG for the same reason as before:
   an SVG needs a viewBox, and this tree's height is set by how five sentences
   wrap at the column's width, which is not a number available at authoring
   time. Boxes inside the grid derive from the grid's own rows, so a branch
   cannot drift off a node's centre at any width.

   ── Colour ───────────────────────────────────────────────────────────────
   The root is the only filled element and the connectors are the only coloured
   lines, because "one insight caused all of this" is the half of the claim a
   reader could otherwise miss. The fill is --sp-brand-dark, the same
   value .sp-card--dark uses in shared.css, which is what the dark card in the
   section directly above this one on the page is filled with. Reusing that
   token rather than a teal gradient keeps one dark surface on the page instead
   of two competing ones. The two decision nodes are identical white
   surfaces so that nothing ranks the roles against each other. The only other
   colour is the teal tick before each outcome line, which is the same tick the
   copy column uses on its bullet list, tying the graphic to the list it
   illustrates.

   ── The only thing that animates ─────────────────────────────────────────
   Motion belongs to graphics whose claim is "this is happening now", and this
   graphic's claim is structural: one insight, two decisions. So motion is
   confined to the root's lightbulb, which throws three short rays that blink on
   and off out of phase with one another. Nothing else in the tree moves, and
   the bulb itself does not: it is a flat gold glyph with no glow, no shadow and
   no gradient. The only property any keyframe touches is opacity, and only on
   the rays, which are out of flow, so nothing here can change a measured box or
   push a phone into horizontal scroll.

   ── Inherited line-height ────────────────────────────────────────────────
   line-height is unitless on the root for the reason it is on .ir2-flow: the
   theme sets line-height as a length, lengths do not scale down, and a 12px
   tag left to inherit would compute to roughly 2.6x leading.

   Every selector is scoped to .static-page, so this file is safe to load on
   any page that declares it in deps.json.
   ══════════════════════════════════════════════════════════════════════════ */

.static-page .dtree {
    --dt-rail: 2px;
    --dt-rail-color: var(--sp-brand-teal-dark);   /* #175E56 */
    --dt-rail-col: 1.6rem;        /* width of the line column */
    --dt-stem-h: 0.9rem;          /* root underside down to the trunk */
    --dt-branch-gap: 0.9rem;      /* between two decision nodes */
    --dt-arrow: 6px;
    --dt-pad: 1.5rem;             /* 24px node padding; offsets derive from it */
    --dt-root-pad: 1.75rem;       /* 28px: the root carries the graphic's one big idea */

    width: 100%;
    max-width: 29rem;             /* 352px: the widest cap that still leaves the
                                     tree clearly portrait once the root is held
                                     to one sentence and there are two branches */
    margin-inline: auto;
    line-height: 1.35;
    letter-spacing: -0.005em;
    text-align: left;
}

/* ── The tree ──────────────────────────────────────────────────────────────
   Row gap is zero on purpose. The trunk has to be continuous, and a row gap
   would open a break in it at every join. Vertical separation between nodes is
   carried by the three empty gap rows instead, which the trunk passes through.

   Rows, in order: root, stem, node, gap, node. */

.static-page .dtree__tree {
    display: grid;
    grid-template-columns: var(--dt-rail-col) 1fr;
    grid-template-rows: auto var(--dt-stem-h)
                        auto var(--dt-branch-gap)
                        auto;
    column-gap: 0;
    row-gap: 0;
    align-items: stretch;
}

/* ── Root: the generated insight ───────────────────────────────────────────
   Spans both columns, so the sentence gets the graphic's whole width and the
   trunk leaves it from the left. The one filled element in the graphic. */

.static-page .dtree__root {
    grid-area: 1 / 1 / 2 / 3;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: var(--dt-root-pad);
    border-radius: 10px;
    background: var(--sp-brand-dark);
    box-shadow: 0 1px 2px rgba(21, 41, 39, 0.05),
                0 18px 40px -26px rgba(21, 41, 39, 0.45);
}

.static-page .dtree__root-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 1.95rem;
    height: 1.95rem;
    font-size: 1.875rem;          /* 30px: the graphic's one large glyph */
    line-height: 1;

    /* Warm gold rather than the pale teal the rest of the dark surface uses.
       --sp-brand-gold is the brand accent named in AGENTS.md and already
       appears on this page, on the Customer Success node of the knowledge base
       animation, so the colour is not new to the reader. A lit bulb reads warm,
       and a glow in a different hue from the glyph it surrounds looks like a
       rendering fault rather than light, so the glyph and its glow share one
       colour.

       The resting state carries a soft static glow on purpose. The animation
       below is added only under prefers-reduced-motion: no-preference, so the
       reduced-motion state is this rule on its own: a lit bulb that does not
       breathe, which is the animation's own resolved middle rather than an
       unlit glyph. */
    color: var(--sp-brand-gold);

    /* The rays are absolutely positioned against this box, so the wrapper is the
       containing block. Its own width and height stay fixed at 1.95rem and the
       rays are out of flow, which is what keeps the measured icon box stable
       while light appears to leave it. */
    position: relative;
}

/* ── Rays ──────────────────────────────────────────────────────────────────
   Three flat bars pointing up and out of the bulb, at -35, 0 and +35 degrees:
   a tight upward fan rather than a wide spray, so the group reads as one bulb
   throwing light rather than as a starburst.

   Each ray is a solid 2 by 8px bar of the same gold as the glyph. No gradient,
   no blur and no shadow anywhere on the icon or the rays: the bulb is drawn
   flat, and the only thing that ever changes is whether a ray is there or not.

   Position is a static rotate plus a translate along the ray's own rotated
   axis, so an angle is stated once and no x and y arithmetic is needed. The
   rays are absolutely positioned against the wrapper, which is why the wrapper
   keeps its 1.95rem box while light appears to leave it.

   The gap matters as much as the bar. The bulb glyph's outer edge sits about
   11.5px from the wrapper centre. A ray is pushed 22px out and is 8px long, so
   its near end sits 18px from centre, leaving roughly 6.5px of clear space
   between the glyph and the start of the ray, and its far tip reaches 26px.
   Short bars held well off the glyph read as separate points of light; longer
   bars starting closer read as the glyph having grown spikes.

   Containment: the wrapper is 31.2px, so its centre is 15.6px from each edge,
   and a tip at 26px is 10.4px past the wrapper's own edge. The root card
   carries 28px of padding on every side and the fan is narrow, so every tip
   lands well inside the card. Measurement confirms that rather than this
   arithmetic. */

.static-page .dtree__ray {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 2px;
    height: 8px;
    margin-left: -1px;
    margin-top: -4px;
    background: var(--sp-brand-gold);
    pointer-events: none;

    /* On. This is also the reduced-motion state: three rays permanently lit,
       which is the blink's own on phase rather than an empty icon. */
    opacity: 1;
}

.static-page .dtree__ray--a { transform: rotate(-35deg) translateY(-22px); }
.static-page .dtree__ray--b { transform: rotate(0deg)   translateY(-22px); }
.static-page .dtree__ray--c { transform: rotate(35deg)  translateY(-22px); }

@media (prefers-reduced-motion: no-preference) {
    /* Three periods sharing no common factor, each started partway through its
       own cycle by a negative delay, so the rays are never on or off together
       for long and the pattern does not visibly repeat. */
    .static-page .dtree__ray--a { animation: dtreeRayBlink 1.6s step-end infinite; animation-delay: -0.45s; }
    .static-page .dtree__ray--b { animation: dtreeRayBlink 2.1s step-end infinite; animation-delay: -1.25s; }
    .static-page .dtree__ray--c { animation: dtreeRayBlink 2.5s step-end infinite; animation-delay: -1.9s; }
}

/* A blink, not a fade. step-end holds each keyframe's value until the next one
   is reached, so a ray is either fully on or fully off and no intermediate
   opacity is ever painted. On for the first half of the cycle, off for the
   second. */
@keyframes dtreeRayBlink {
    0%   { opacity: 1; }
    50%  { opacity: 0; }
    100% { opacity: 1; }
}

/* 18px, the largest type in the graphic, because the insight is what the tree
   is about. 1.55 leading because this is prose, not a label. */
.static-page .dtree__root-text {
    margin: 0;
    font-size: 1.125rem;          /* 18px */
    font-weight: 500;
    line-height: 1.55;
    letter-spacing: -0.005em;
    color: #ffffff;
}

/* ── Connectors ────────────────────────────────────────────────────────────
   All three pieces put their vertical on the rail column's centre line, so the
   stem, the trunk and the last segment are one unbroken line. */

.static-page .dtree__stem,
.static-page .dtree__rail,
.static-page .dtree__drop {
    position: relative;
    display: block;
}

.static-page .dtree__stem { grid-area: 2 / 1 / 3 / 2; }
.static-page .dtree__rail { grid-area: 3 / 1 / 5 / 2; }

.static-page .dtree__stem::before,
.static-page .dtree__rail::before,
.static-page .dtree__drop--last::before {
    content: "";
    position: absolute;
    left: 50%;
    margin-left: calc(var(--dt-rail) / -2);
    top: 0;
    bottom: 0;
    width: var(--dt-rail);
    background: var(--dt-rail-color);
}

.static-page .dtree__drop--a { grid-area: 3 / 1 / 4 / 2; }
.static-page .dtree__drop--b { grid-area: 5 / 1 / 6 / 2; }

/* The final drop carries the trunk's last segment and stops halfway down its
   own row, which is halfway down the last node, which is where that node's
   branch leaves. The trunk therefore ends on a branch rather than in mid air. */
.static-page .dtree__drop--last::before {
    bottom: 50%;
}

/* The branch itself: from the trunk to the node's left edge, at 50% of the
   row. Because the node fills its row, 50% of the row is the node's centre. */
.static-page .dtree__drop::after {
    content: "";
    position: absolute;
    left: 50%;
    right: 0;
    top: 50%;
    margin-top: calc(var(--dt-rail) / -2);
    height: var(--dt-rail);
    background: var(--dt-rail-color);
}

/* ── Decision nodes ────────────────────────────────────────────────────────
   Three identical white surfaces, because the graphic argues that the
   decisions differ, not that the roles rank. They carry the resting-card
   elevation: here they are the surfaces, not the contents of one. */

.static-page .dtree__card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--dt-pad);
    background: #ffffff;
    border: 1px solid #E7EEEC;
    border-radius: 10px;
    box-shadow: 0 1px 2px rgba(21, 41, 39, 0.05),
                0 18px 40px -26px rgba(21, 41, 39, 0.45);
}

.static-page .dtree__card--managers { grid-area: 3 / 2 / 4 / 3; }
.static-page .dtree__card--exec { grid-area: 5 / 2 / 6 / 3; }

/* The arrowhead. Absolute offsets resolve against the padding box, so the
   1px border is added back to land the tip exactly on the node's outer edge. */
.static-page .dtree__card::before {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(-1 * var(--dt-arrow) - 1px);
    margin-top: calc(-1 * var(--dt-arrow) + 1px);
    width: 0;
    height: 0;
    border-left: var(--dt-arrow) solid var(--dt-rail-color);
    border-top: calc(var(--dt-arrow) - 1px) solid transparent;
    border-bottom: calc(var(--dt-arrow) - 1px) solid transparent;
}

/* ── Role tag ──────────────────────────────────────────────────────────────
   A tinted disc plus the role's name. The role is named and never drawn: a
   role holds many people, so a face would misrepresent it. The disc marks the
   role rather than the decision, which is why both discs come from the
   same icon family. */

.static-page .dtree__card-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}

.static-page .dtree__card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.45rem;
    height: 2.45rem;
    border-radius: 50%;
    background: var(--sp-brand-teal-tint);
    color: var(--sp-brand-teal);
    font-size: 1.4rem;            /* 22.4px glyph in a 39px disc */
    line-height: 1;
}

.static-page .dtree__card-role {
    font-size: 0.8125rem;         /* 13px, the smallest type in the graphic */
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sp-ink-muted);
}

/* ── Decision and outcome ──────────────────────────────────────────────────
   The decision is the node's own sentence and carries the weight. The outcome
   is the live page's own promise for that role, prefixed with the same tick
   the copy column sets on its bullet list, so a reader recognises the pairing
   instead of reading two sentences of equal rank. */

.static-page .dtree__card-decision {
    display: block;
    font-size: 1rem;              /* 16px */
    font-weight: 700;
    line-height: 1.5;
    letter-spacing: -0.01em;
    color: var(--sp-ink);
}

.static-page .dtree__card-outcome {
    display: flex;
    align-items: flex-start;
    gap: 0.35rem;
    margin-top: 0.55rem;
    padding-top: 0.55rem;
    border-top: 1px solid #F2F6F5;
    font-size: 1rem;              /* 16px */
    line-height: 1.5;
    color: var(--sp-ink-soft);
}

.static-page .dtree__card-tick {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 0.95rem;
    height: 1.5rem;               /* one 16px line, so the tick sits on it */
    font-size: 0.8rem;
    line-height: 1;
    color: var(--sp-brand-teal);
}

/* ── Caption ───────────────────────────────────────────────────────────────
   Kept from the earlier version because it answers the question the fork
   raises: the three roles act on the same insight at different levels of
   detail because the permissions are configurable. Set in the body font rather
   than mono, because these are words and not identifiers. */

.static-page .dtree__note {
    margin: 0.9rem 0 0;
    text-align: center;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sp-ink-faint);
}

.static-page .dtree__note-dot {
    color: #CFDAD7;
    margin: 0 0.4rem;
}

/* ── Below 480px ───────────────────────────────────────────────────────────
   The layout is already a single column, so nothing rotates and nothing is
   dropped. Only the rail narrows and the padding tightens, which buys back
   about 12px of sentence width on a phone. The node padding is not reduced: the
   sentences have to stay as readable on a phone as on a desktop. The tree keeps its shape, and
   because every line is inside the grid there is nothing that can extend
   past the graphic's own box. */

@media (max-width: 479px) {
    .static-page .dtree {
        --dt-rail-col: 1.15rem;
        --dt-branch-gap: 0.8rem;
    }
}
