/* ======================================================================
   Workflow steps: the shared master for the "numbered step" sections.
   One step = a giant hairline numeral, an eyebrow + title + body in a fixed text column, a scaled product-UI figure
   beside it, a hairline rule above, and an optional row of substeps (icon list) underneath.
   First built on Homeowners (2026-10-14); any page that shows workflow steps links this file.
   How to adopt it on a page: docs/WORKFLOW-STYLE.md. To change the look everywhere, edit THIS file only.

   Link order: tokens.css, site.css, list-icons.css, workflow.css, then the page's own stylesheet.
   Script: js/workflow.js (keeps the figure contents scaled to the figure).
   Relies on site.css for the figure frame (.figure.figure--ui: surface fill, card radius, 1px hairline, 16:9) and
   on list-icons.css for the substep icons (.li-item / .li-ico).
   ====================================================================== */

/* ---------- the dials ----------
   Every number the pattern uses lives here, on the block, so a page (or one block) can override a dial without
   touching the rules below. Defaults are the values Homeowners shipped with on 2026-10-14. The dials are also set on
   .wf-section, because the section gap is the section's own margin (the section is outside its blocks), and on
   .wf-cards, so a card row that sits outside any block still gets the same numeral, eyebrow and gap values. */
.wf-block, .wf-section, .wf-cards {
  /* spacing rhythm. Owner 2026-11-01 ("I don't like the hairlines between sections", chose B): no rule, and two
     rhythms instead of one, so proximity does the grouping the line used to do. Inside a step (step top -> step
     content, step -> substeps) 64; between steps (previous content -> step, section -> section) 128, twice the inside
     gap, so each step reads as one group with its substeps. Owner 2026-11-04 ("the whole ladder down one except the
     128px gaps"): 192/96 -> 128/64 after the section gap went 288 -> 128, so steps never sit wider apart than the
     sections around them. Was one 64 rhythm with a hairline (then 96, then 128 earlier on 2026-11-01). */
  --wf-rhythm: var(--pn-space-128);            /* between: previous content -> step, section -> section */
  --wf-rhythm-in: var(--pn-space-64);          /* inside: step top -> step content, step -> substeps */
  /* the hairline rule above each step: off (owner 2026-11-01). Set to 1px solid var(--pn-color-border-decorative) to bring it back */
  --wf-rule: 0;
  /* text column (eyebrow, title, body) and the gap between it and the figure */
  --wf-text-w: 440px;
  --wf-col-gap: var(--pn-space-48);
  --wf-text-gap: var(--pn-space-16);   /* between eyebrow, title and body */
  /* eyebrow label: sits this much closer to the title than the text gap (16 - 4 = 12 above the title) */
  --wf-eyebrow-pull: -4px;
  --wf-eyebrow-size: var(--pn-type-ui-eyebrow-size); /* 2026-10-29: follows the site eyebrow size token */
  --wf-eyebrow-weight: 500;
  --wf-eyebrow-color: var(--pn-color-accent-primary);
  /* giant hairline numeral behind the text */
  --wf-num-size: 280px;
  --wf-num-weight: 300; /* 2026-10-18: Figtree has no 200 cut (axis 300-900); 200 silently resolved to this face. Dial now says what renders. */
  --wf-num-tracking: -0.05em;
  --wf-num-stroke: rgba(242, 240, 233, 0.2);
  --wf-num-stroke-w: 1px;              /* the visible hairline (see the numeral rule for why it is drawn at 2x) */
  --wf-num-ground: var(--pn-color-background-canvas); /* the page colour behind the numeral */
  --wf-num-offset: -24px;              /* left, from the text column's edge */
  --wf-num-nudge: 0.138em;             /* optical: lifts the em box so the digit tops, not the box, meet the figure top (Figtree: digits sit 0.138em into the box) */
  --wf-num-fade: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 28%, #000 62%, rgba(0, 0, 0, 0) 100%);
  /* figure contents: the UI recreation is laid out at this native size, then scaled to the figure's width */
  --wf-fit-native-w: 906.667px;
  --wf-fit-native-h: 510px;
  /* substep grid */
  --wf-sub-col-gap: var(--pn-space-48);
  --wf-sub-row-gap: var(--pn-space-32);
}

/* ---------- rhythm between blocks and sections ----------
   A block one rhythm below the block before it, or below the section intro (mark the intro with .wf-intro).
   A section whose steps continue the previous section's steps carries .wf-section and sits one rhythm below it
   (instead of site.css's 128 section gap). The first step section on a page keeps the normal section gap. */
.wf-block + .wf-block,
.wf-intro + .wf-block { margin-top: var(--wf-rhythm); }
.page-main > section.wf-section { margin-top: var(--wf-rhythm); }

/* ---------- the step row ----------
   The inside rhythm of space on top (the hairline that used to sit there is off, --wf-rule), then text column | gap | figure. The figure fills what is left of
   the row; the text is centred against it. Positioned so the numeral can be placed against the row. */
.wf-step {
  position: relative;
  display: flex; align-items: center; gap: var(--wf-col-gap);
  padding-top: var(--wf-rhythm-in);
  border-top: var(--wf-rule);
}
/* the lead holds the numeral (out of flow) and the text column; it is not a positioning box, the row is */
.wf-step__lead { flex: none; display: flex; align-items: flex-start; }

/* the giant numeral: hairline outline only, faded top and bottom, behind the text, its digit tops level with the
   figure's top edge.
   Hairline without doubled lines (owner 2026-10-14): Figtree is a variable font whose digits are built from
   overlapping contours (6 and 9 at every weight; Hanken Grotesk 700 overlaps on most digits), and a plain text stroke
   draws those inner overlaps as extra lines. So the stroke is painted first at twice the hairline width and the glyph
   is then filled with the page colour on top (paint-order: stroke fill): the fill covers the inner half of the outer
   stroke and every inner overlap, leaving one clean hairline on the outside. The fill must match what is behind the
   numeral (--wf-num-ground); on a different ground, set that dial. */
.wf-step__num {
  position: absolute; left: var(--wf-num-offset); top: calc(var(--wf-rhythm-in) - var(--wf-num-nudge)); z-index: 0;
  display: block;
  font: var(--wf-num-weight) var(--wf-num-size)/1 var(--pn-font-sans); letter-spacing: var(--wf-num-tracking);
  color: var(--wf-num-ground); -webkit-text-stroke: calc(var(--wf-num-stroke-w) * 2) var(--wf-num-stroke);
  paint-order: stroke fill;
  -webkit-mask-image: var(--wf-num-fade); mask-image: var(--wf-num-fade);
  padding-right: 0.15em; /* 2026-10-15: the mask clips to the box; tight tracking pushes the ink of 3,4,5,6,8,9 past it */
  pointer-events: none; user-select: none; -webkit-user-select: none;
}

/* the text column: eyebrow, title (h3.t-heading-sub), body (p.t-body); over the numeral */
.wf-step__text {
  position: relative; z-index: 1;
  width: var(--wf-text-w);
  display: flex; flex-direction: column; gap: var(--wf-text-gap);
}
.wf-step__text .t-heading-sub { text-wrap: balance; }
.wf-step__text .t-body { text-wrap: pretty; }

/* the eyebrow label right above the title: 14/500, +2% tracking, sentence case as typed, accent */
.wf-step__eyebrow {
  display: block; margin-bottom: var(--wf-eyebrow-pull);
  font: var(--pn-type-ui-eyebrow);
  font-size: var(--wf-eyebrow-size); font-weight: var(--wf-eyebrow-weight); line-height: 1.3; letter-spacing: 0.02em;
  color: var(--wf-eyebrow-color);
}

/* ---------- the figure ----------
   Use on a .figure.figure--ui (site.css draws the frame and keeps it 16:9). It fills the rest of the row
   (792 x 445.5 at 1440 with the default dials). Inside, .wf-fit lays the UI recreation out at its native size and
   scales it to the figure; js/workflow.js keeps --wf-fit = figure width / --wf-fit-native-w (0.75 until it runs).
   Static: nothing inside is interactive. Page-specific crops of a recreation go in the page's stylesheet. */
.wf-fig { flex: 1 1 0; min-width: 0; width: auto; margin-top: 0; }
.wf-fit {
  position: absolute; top: 0; left: 0;
  width: var(--wf-fit-native-w); height: var(--wf-fit-native-h);
  transform: scale(var(--wf-fit, 0.75)); transform-origin: 0 0;
}
.wf-fit .ui { width: 100%; height: 100%; }

/* ---------- substeps under the step ----------
   One rhythm below the step, full content width, 2 or 3 equal columns. Each item is an icon list item
   (.wf-sub.li-item with an .li-ico, see docs/LIST-ICONS.md): a UI/Label L title and a Text/Body line under it. */
.wf-details {
  margin-top: var(--wf-rhythm-in); padding-left: 0;
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-32);
}
.wf-subs { width: 100%; display: grid; column-gap: var(--wf-sub-col-gap); row-gap: var(--wf-sub-row-gap); }
.wf-subs--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wf-subs--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wf-sub { display: flex; align-items: flex-start; gap: var(--pn-space-16); }
.wf-sub__t { font: var(--pn-type-ui-label-l); color: var(--pn-color-text-primary); text-wrap: pretty; }
/* owner 2026-10-31: the body line starts under the icon, not under the title. Only the title keeps the 24 inset
   (16 icon + 8 clearance) from list-icons.css; the item itself drops it, so the icon still sits at the item's left edge. */
.wf-sub.li-item { padding-left: 0; }
.wf-sub.li-item .wf-sub__t { padding-left: 24px; }
.wf-sub__b { margin-top: var(--pn-space-4); font: var(--pn-type-text-body); color: var(--pn-color-text-secondary); text-wrap: pretty; }

/* ======================================================================
   Card variant: steps shown as a row of equal cards (first used for Contractors CO05 steps 04 to 06).
   One card = the same hairline numeral as .wf-step__num (smaller, anchored to the card's top edge), an optional
   eyebrow, a title over the numeral's lower half, a body line, and a figure slot pinned to the card's bottom.
   The master owns the row grid, the numeral, the text stack and the figure's position. The page owns the card's own
   fill, radius, padding and rule, and the figure's size (e.g. a 410.66 x 240 viewport) and contents.
   How-to and the Contractors mapping: docs/WORKFLOW-STYLE.md, "Card variant".
   ====================================================================== */

/* card dials (on the row; override on .wf-cards or on one .wf-card). The shared numeral, eyebrow and text-gap dials
   come from the dial block at the top of this file, which also covers .wf-cards. */
.wf-cards {
  --wf-card-gap: var(--wf-sub-col-gap);  /* column gap: 48, so the cards line up with a .wf-subs--3 row above them */
  --wf-card-num-size: 160px;
  --wf-card-num-offset: -7px;            /* em box left edge, from the card's left edge. Figtree's 0 starts 8px into
                                            its box at 160, so -7 puts the digit's outer hairline on the card's left
                                            edge, in line with the title (-12 would push 4px of the 0 outside the card,
                                            where the card's clip cuts it) */
  --wf-card-num-top: 0px;                /* digit tops, from the card's top edge (inside its border) */
  --wf-card-num-nudge: 0.13em;           /* optical: Figtree's digit tops sit 0.138em into the em box; 0.13em lifts
                                            them to ~1px under the card top, so the hairline is not clipped */
  --wf-card-text-top: var(--pn-space-24);   /* extra space above the text, on top of the card's own padding: places
                                            the title over the numeral's lower half (with a 32 card padding) */
  --wf-card-title-lh: 31.2px;            /* one .t-heading-sub line (26 x 1.2), for the head reservation below */
  /* --wf-card-head-min: unset by default = two title lines, plus the eyebrow when the head has one. Set it to force
     a head height (e.g. three title lines) */
  --wf-card-stack-gap: var(--pn-space-24);  /* minimum space between the body and the figure */
}

/* the row: equal columns, equal-height cards (stretch), list reset for an <ol>/<ul> */
.wf-cards {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch;
  column-gap: var(--wf-card-gap); row-gap: var(--wf-card-gap);
  margin: 0; padding: 0; list-style: none;
}

/* the card: a column, so the figure can sit at the bottom; clips the numeral to the card */
.wf-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--wf-card-stack-gap);
  min-width: 0;
}

/* the numeral: exactly .wf-step__num's technique (Figtree 200, stroke painted first at 2x the hairline, glyph filled
   with the ground on top, so overlapping inner contours never show; faded top and bottom), sized by the card dials.
   Anchored to the card's top edge, never to the title, so one- and two-line titles leave it in the same place.
   The card nudge lifts the em box so the digit tops (not the box) meet the card top. The card must sit on
   --wf-num-ground; a page that gives the card a fill sets --wf-num-ground to that fill. */
.wf-card__num {
  position: absolute; z-index: 0;
  left: var(--wf-card-num-offset); top: calc(var(--wf-card-num-top) - var(--wf-card-num-nudge));
  display: block; margin: 0;
  font: var(--wf-num-weight) var(--wf-card-num-size)/1 var(--pn-font-sans); letter-spacing: var(--wf-num-tracking);
  color: var(--wf-num-ground); -webkit-text-stroke: calc(var(--wf-num-stroke-w) * 2) var(--wf-num-stroke);
  paint-order: stroke fill;
  -webkit-mask-image: var(--wf-num-fade); mask-image: var(--wf-num-fade);
  padding-right: 0.15em; /* 2026-10-15: the mask clips to the box; tight tracking pushes the ink of 3,4,5,6,8,9 past it */
  pointer-events: none; user-select: none; -webkit-user-select: none;
}

/* the text: head (eyebrow + title) then body, over the numeral */
.wf-card__text {
  position: relative; z-index: 1;
  margin-top: var(--wf-card-text-top);
  display: flex; flex-direction: column; gap: var(--wf-text-gap);
}
/* the head reserves two title lines (+ the eyebrow when present), so one-line and two-line titles start at the
   same place and every body starts on the same line across the row. Titles sit at the top of the reservation. */
.wf-card__head {
  display: flex; flex-direction: column; justify-content: flex-start; gap: var(--wf-text-gap);
  min-height: var(--wf-card-head-min, calc(var(--wf-eyebrow-size) * 1.3 + var(--wf-text-gap) + var(--wf-eyebrow-pull) + 2 * var(--wf-card-title-lh)));
}
.wf-card__head:not(:has(> .wf-card__eyebrow)) {
  min-height: var(--wf-card-head-min, calc(2 * var(--wf-card-title-lh)));
}
/* optional eyebrow: same look as the step eyebrow (14/500, +2%, accent, 12 above the title) */
.wf-card__eyebrow {
  display: block; margin-bottom: var(--wf-eyebrow-pull);
  font: var(--pn-type-ui-eyebrow);
  font-size: var(--wf-eyebrow-size); font-weight: var(--wf-eyebrow-weight); line-height: 1.3; letter-spacing: 0.02em;
  color: var(--wf-eyebrow-color);
}
.wf-card__title { font: var(--pn-type-heading-sub); letter-spacing: -0.015em; color: var(--pn-color-text-primary); text-wrap: balance; }
.wf-card__body { font: var(--pn-type-text-body); color: var(--pn-color-text-secondary); text-wrap: pretty; }

/* the figure slot: last child, pinned to the card's bottom so equal-height cards line their figures up.
   Its size, frame and contents stay with the page (e.g. width: 100%; height: 240px, or an aspect-ratio). */
.wf-card__fig { position: relative; z-index: 1; flex: none; margin-top: auto; }

/* ======================================================================
   Responsive tiers (docs/BUILD-CONTRACT-responsive-2026-11-04.md). The dials step down per tier; a step stacks below
   1024 (text first, the figure full width one inside-rhythm below, the numeral stays behind the text); card rows go
   2 x 2 (four cards) or one column (three cards) at tablet and one column at phone; at phone the numeral (step and card)
   sits above the text.
   ====================================================================== */

/* ---- responsive: tablet (2026-11-04) ---- */
@media (max-width: 1023px) {
  .wf-block, .wf-section, .wf-cards {
    --wf-rhythm: var(--pn-space-96);   /* = the tablet section gap (ladder down one, owner 2026-11-04) */
    --wf-rhythm-in: var(--pn-space-48);
    --wf-num-size: 200px;
    --wf-sub-col-gap: var(--pn-space-32);
  }
  .wf-cards { --wf-card-gap: var(--pn-space-32); --wf-card-num-size: 128px; row-gap: var(--pn-space-64); } /* rows further apart than a card's numeral is from its title */
  /* three cards: one column (three 208 columns at 768 ran the bodies to 5-6 lines); four cards: 2 x 2. One column needs
     no two-line title reservation (it only levels titles across a row) */
  .wf-cards { grid-template-columns: minmax(0, 1fr); }
  .wf-cards:not(:has(> :nth-child(4))) { --wf-card-head-min: auto; }
  .wf-cards:has(> :nth-child(4)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .wf-step { flex-direction: column; align-items: stretch; gap: var(--wf-rhythm-in); }
  .wf-step__text { flex: 1 1 0; min-width: 0; width: auto; max-width: 640px; } /* fills the row to 640; width:auto alone hugged short steps at 348 */
  .wf-fig { flex: none; width: 100%; }
}

/* ---- responsive: phone (2026-11-04) ---- */
@media (max-width: 767px) {
  .wf-cards { --wf-card-head-min: auto; } /* one column: the two-line title reservation only lines titles up across a row */
  .wf-block, .wf-section, .wf-cards {
    --wf-rhythm: calc(var(--pn-space-64) + var(--pn-space-16)); /* 80 = the phone section gap (ladder down one, owner 2026-11-04); inside stays 48, the house floor for a lead -> figure gap */
    --wf-rhythm-in: var(--pn-space-48);
    --wf-num-size: 112px; /* the card numeral's size: above the text, like the cards (r1) */
    --wf-num-offset: calc(-1 * var(--pn-space-4)); /* the 0's sidebearing keeps its ink inside the 20 margin */
    --wf-sub-row-gap: var(--pn-space-32);
  }
  .wf-cards { --wf-card-gap: var(--pn-space-64); --wf-card-num-size: 112px; }
  .wf-subs--2, .wf-subs--3, .wf-cards, .wf-cards:has(> :nth-child(4)) { grid-template-columns: minmax(0, 1fr); }
  /* owner 2026-11-04 ("on narrow screens make the copy bottom aligns and overlaps with the big numbers"; r1 had put
     the numeral above the text): the card is a one-column grid and the numeral and the text share its first cell.
     The numeral's margin box is its ink height (the em box less the 0.15em under the digits' foot), the text sits at
     the cell's bottom: a short text ends on the digits' foot; a taller one starts no higher than 0.45em under the
     digit tops (the floor margin) and runs past the foot, the desktop relation. A figure, where a page has one, is row 2. */
  .wf-card { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--wf-card-stack-gap); }
  .wf-card__num {
    position: relative; grid-area: 1 / 1; align-self: start; left: var(--wf-card-num-offset); top: 0;
    margin-top: calc(var(--wf-card-num-top) - var(--wf-card-num-nudge)); margin-bottom: calc(-0.15 * var(--wf-card-num-size));
  }
  .wf-card__text { grid-area: 1 / 1; align-self: end; margin-top: calc(var(--wf-card-num-top) + 0.45 * var(--wf-card-num-size)); } /* the floor counts from the digit tops, wherever a page puts them (Professionals: one inside-rhythm down) */
  .wf-card__fig { margin-top: 0; }
  /* the step numeral likewise sits above the text (behind it at 350 it collided with the eyebrow and title): in flow, digit tops on the lead's top (the nudge), the eyebrow 8 under the digits' foot (~0.72em) */
  .wf-step__lead { flex-direction: column; }
  .wf-step__num {
    position: relative; top: auto;
    margin-top: calc(-1 * var(--wf-num-nudge)); margin-bottom: calc(0.72em + var(--wf-num-nudge) - 1em + var(--pn-space-8));
  }
}
