/* Component: EditorialPages ------------------------------------------------
   The parts of the four narrative compositions that could not travel inline.

   Each page renders one variant per breakpoint, because the design ships a
   separate screen per breakpoint rather than one reflowing layout. Only the
   active variant is displayed; the rest are `display: none`, so desktop
   absolute coordinates never reach a phone. */
@layer components {

  /* ---- Which screen is on ---------------------------------------------- */
  .tp-bp {
    display: none;
  }

  .tp-bp--from-700,
  .tp-bp--from-1100 {
    display: block;
  }

  @media (max-width: 1099px) {
    .tp-bp--from-1100 { display: none; }
    .tp-bp--700-1099  { display: block; }
  }

  @media (max-width: 699px) {
    .tp-bp--from-700,
    .tp-bp--from-1100,
    .tp-bp--700-1099 { display: none; }
    .tp-bp--to-699   { display: block; }
  }

  /* ---- Grounds ---------------------------------------------------------
     Some screens paint the plate on the page itself, viewport-anchored. The
     design uses `background-attachment: fixed`, which phone browsers treat as
     `scroll` — the artwork would then slide and land on the wrong object — so
     the same effect is drawn as a fixed layer, which is reliable everywhere. */
  .tp-ground {
    position: relative;
  }

  .tp-ground::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: var(--tp-plate);
    background-repeat: no-repeat;
  }

  .tp-ground--parchment { background-color: #EFE7D6; }
  .tp-ground--paper     { background-color: var(--tp-color-paper); }

  /* ---- The target, per breakpoint -------------------------------------
     One model for every destination: a focal point on the master plate and a
     scale. The focal point is placed at the centre of the VIEWPORT, so the
     object the page is about is what the visitor is looking at — and the Salon
     transition solves the identical frame from the identical three numbers.

     Replaces the old size/position crop strings, which were a frame derived
     from a frame and drifted from the object they were supposed to be aiming
     at. Those values are still in inc/config/editorial.php for rollback; they
     no longer render anything.

     --tp-plate-box-top is the one genuine offset in the system: the band is a
     box inside .tp-editorial that begins below the sticky header, so its own
     origin is that far down. A viewport-fixed ground has no such offset. */
  .tp-plate-crop,
  .tp-ground::before {
    --tp-fx: var(--tp-focal-desktop-x, 0.5);
    --tp-fy: var(--tp-focal-desktop-y, 0.5);
    --tp-fs: var(--tp-focal-desktop-s, 2);
  }

  @media (max-width: 1099px) {
    .tp-plate-crop,
    .tp-ground::before {
      --tp-fx: var(--tp-focal-tablet-x, 0.5);
      --tp-fy: var(--tp-focal-tablet-y, 0.5);
      --tp-fs: var(--tp-focal-tablet-s, 2);
    }
  }

  @media (max-width: 699px) {
    .tp-plate-crop,
    .tp-ground::before {
      --tp-fx: var(--tp-focal-mobile-x, 0.5);
      --tp-fy: var(--tp-focal-mobile-y, 0.5);
      --tp-fs: var(--tp-focal-mobile-s, 2);
    }
  }

  .tp-plate-crop  { --tp-plate-box-top: var(--tp-editorial-band-top, 0px); }
  .tp-ground::before { --tp-plate-box-top: 0px; }

  /* The plate is 4:3, so its rendered height is 0.75 x its rendered width.
     Place the focal point at 50vw / 50vh, less this box's own origin. */
  .tp-plate-crop {
    background-image: var(--tp-plate);
    background-repeat: no-repeat;
  }

  .tp-plate-crop,
  .tp-ground::before {
    background-size: calc(var(--tp-fs) * 100vw) auto;
    background-position:
      calc(50vw - var(--tp-fx) * var(--tp-fs) * 100vw)
      calc(50vh - var(--tp-plate-box-top) - var(--tp-fy) * var(--tp-fs) * 75vw);
  }

  /* ---- Column counts lifted out of the design's inline styles ----------
     An inline declaration outranks every media query, so these could not stay
     where the prototype put them. Each variant is single-breakpoint, so these
     are plain values. */
  .tp-grid-bio   { grid-template-columns: minmax(0, 1.42fr) minmax(0, 0.58fr); }
  .tp-grid-sense { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .tp-grid-know  { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tp-grid-open  { grid-template-columns: minmax(0, 1fr); }
  .tp-grid-moves { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tp-cols-2     { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tp-cols-3     { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* The desktop screen also serves tablet, where the design narrows these. */
  @media (max-width: 1099px) {
    .tp-grid-bio,
    .tp-grid-sense,
    .tp-grid-open,
    .tp-grid-moves { grid-template-columns: minmax(0, 1fr); }
    .tp-grid-know,
    .tp-cols-3     { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  /* ---- On Procuring: the handoff's own artwork frame ---------------------
     Measured off design handoff/The Procuress.dc.html, driven through the
     prototype itself (md5 ea0829311f54c5a5db4e476a90a396f4):

       desktop  box [0, 0, vw, vh]   165% auto / 78% 4.5%
       mobile   box [0, 0, vw, vh]   472% auto / 83% 0%

     The box is the FULL VIEWPORT at top 0 in the prototype — its nav sits
     over the artwork. Our band is absolute inside .tp-editorial, which starts
     below the sticky header, so it is pulled back up by exactly that much.
     Without this the same percentages resolve against a box 59px (desktop) or
     50px (mobile) lower and the frame is not the design's.

     This page is declared in percentages because the design is: a percentage
     background-position is not reducible to a focal point across aspect
     ratios, and the prototype is the authority. */
  .tp-editorial[data-tp-editorial="proc"] .tp-plate-crop {
    /* !important: the ported band carries `top: 0` as an INLINE style, which
       outranks any rule here. Same trap as the other inline declarations in
       these screens. */
    top: calc(-1 * var(--tp-editorial-band-top, 0px)) !important;
    height: 100vh !important;
    background-size: 165% auto;
    /* 2026-09-15: lifted from 4.5% to 12% so the Baburen sits higher in the
       opening. The Salon handoff crop in inc/config/editorial.php moves with
       it — the bridge and destination must agree to the pixel. */
    background-position: 78% 12%;
    /* The handoff holds this opaque to 90% and kills it by 100% — the whole
       fade happens in a tenth of the band and reads as a line. Same start and
       the same end point, spread over the last 40% in nine steps. */
    /* No mask. The band fades to nothing at its own bottom edge, but
       .tp-proc-continue resumes there at full strength -- so any fade here
       shows as a pale wedge that snaps back to full opacity on a hard line.
       The long .tp-proc-dissolve carries the whole fade instead. */
    -webkit-mask-image: none;
    mask-image: none;
  }

  @media (max-width: 699px) {
    .tp-editorial[data-tp-editorial="proc"] .tp-plate-crop {
      background-size: 472% auto;
      /* USER OVERRIDE: the handoff's 83% 0% puts the Baburen at y 83-442,
         i.e. directly under the title and the caption. Same horizontal
         framing, shifted down so the painting begins BELOW the lockup and can
         be seen whole. -51.6% resolves to +277px at this box. */
      background-position: 83% -51.6%;
      /* USER OVERRIDE: no mask. The handoff fades this band from 64% to 100%
         of 100vh — y 540-844 — which runs straight through the painting now
         that the artwork sits lower. The text no longer overlaps the canvas,
         so the painting is shown at full opacity and the long dissolve below
         does all the blending. */
      -webkit-mask-image: none;
      mask-image: none;
    }
  }

  /* ---- Who Is She: the handoff opening frame --------------------------------
     Measured off the handoff live render, which paints the plate on a box that
     is the whole viewport -- so the band starts at the very top of the
     document, behind the header, exactly as .tp-editorial[proc] does.

       >= 1180px   125% auto   0% 27%
       700-1179px  129% auto   0% 21%

     The focal-target pass had this at scale 2.75 (275% of the viewport width),
     which is 2.2x the handoff: the mannequin filled the frame and the room --
     chandelier, globe, eye, notebook, mirror, hookah, wall art -- was cropped
     away. Mobile is deliberately NOT included here; its composition was
     approved separately and still resolves from the focal custom properties. */
  @media (min-width: 700px) {
    .tp-editorial[data-tp-editorial="who"] .tp-plate-crop {
      top: calc(-1 * var(--tp-editorial-band-top, 0px)) !important;
      height: 100vh !important;
      background-size: 129% auto;
      background-position: 0% 21%;
    }
  }

  @media (min-width: 1180px) {
    .tp-editorial[data-tp-editorial="who"] .tp-plate-crop {
      background-size: 125% auto;
      background-position: 0% 27%;
    }
  }

  /* Mobile, measured off the same handoff render at 430x932, 390x844 and
     375x812 -- identical at all three. The focal model had this at scale 5.5
     (550% of the viewport width), 1.31x the handoff: the mannequin filled the
     frame and the chandelier, florals and wall art were cropped away. Same
     full-viewport box as every other breakpoint.

     The handoff's own band mask here is 1 0%, 1 66%, 0 100% -- flat, then a
     straight drop to nothing meeting the 0.97 cream section on a hard line.
     That is the pattern the site-wide fade instruction supersedes, so the
     softened mask and the section's feathered top are deliberately KEPT. */
  @media (max-width: 699px) {
    .tp-editorial[data-tp-editorial="who"] .tp-plate-crop {
      top: calc(-1 * var(--tp-editorial-band-top, 0px)) !important;
      height: 100vh !important;
      background-size: 420% auto;
      background-position: 22% 26%;
    }
  }

  /* ---- Reflections: the handoff opening frame -------------------------------
     Measured off the handoff live render, on a box that is the whole viewport,
     so the band starts at the top of the document behind the header.

       >= 1180px   196% auto   84% 42%
       700-1179px  200% auto   84% 42%

     The focal-target pass had this at scale 4.80 (480% of the viewport width),
     2.45x the handoff: the frame closed on the mirror's gilt crest until the
     mirror, the Baburen above it, the drapery and the candlesticks were all
     off-frame and the object was no longer identifiable. Mobile is handled
     separately -- the handoff does not use a viewport band there. */
  @media (min-width: 700px) {
    .tp-editorial[data-tp-editorial="refl"] .tp-plate-crop {
      top: calc(-1 * var(--tp-editorial-band-top, 0px)) !important;
      height: 100vh !important;
      background-size: 200% auto;
      background-position: 84% 42%;
    }
  }

  @media (min-width: 1180px) {
    .tp-editorial[data-tp-editorial="refl"] .tp-plate-crop {
      background-size: 196% auto;
      background-position: 84% 42%;
    }
  }

  /* The band is 100vh, but on a viewport taller than the page the wrapper ends
     well above the footer -- and .tp-editorial only clips the x axis, so the
     artwork went on painting, undimmed, through that gap and was then cut dead
     by the opaque footer (texture 15.9 above the edge, 0.0 below). The closing
     dissolve already carries the artwork to the page colour by the wrapper's
     bottom, so clipping there removes the cut without showing a seam: what is
     clipped is already the page colour. */
  /* The clip stops the vh-solved layers extending the page. Its box starts at
     band-top, though, which cut the plate off in a straight line along the
     header's lower edge. The clip margin lets the plate paint up through the
     header to the top of the viewport without letting anything else escape. */
  .tp-editorial[data-tp-editorial="refl"] {
    overflow: clip;
    overflow-clip-margin: var(--tp-editorial-band-top, 59px);
  }

  /* Mobile. The handoff paints this on a tall div with
     background-attachment: fixed, so its positioning area is the VIEWPORT --
     exactly what .tp-ground::before does here with position: fixed. The two are
     equivalent, so only the crop needed correcting: 295% / 82% 42% against the
     viewport box. The focal model had it at scale 8.0 (800% of the viewport
     width), 2.7x the handoff. Measured identical at 430x932, 390x844, 375x812. */
  @media (max-width: 699px) {
    .tp-editorial[data-tp-editorial="refl"] .tp-ground::before {
      background-size: 295% auto;
      /* MOBILE OVERRIDE (user direction, supersedes the handoff for this page):
         the mirror is the compositional anchor and must sit in the middle of
         the frame. Its centre on the master plate is x 0.665 (it spans
         0.60-0.73); centring that in the viewport solves to 74.96% at 375, 390
         and 430 alike. The handoff's 82% put the plate point 0.712 at centre,
         which pushed the mirror left and let the Baburen take the middle. */
      /* lifted 40px: the composition sat low, with the interest in the
         bottom half. The note layer is lifted by the same 40px so it stays
         centred on the mirror. */
      /* 72.28% centres the MIRROR, measured on the master plate with the
         Baburen and the candlesticks masked out: the mirror spans x
         0.589-0.706, centre 0.6473 -- not the 0.665 first estimated from
         a grid read, which left it ~20px left of centre. Scale is
         unchanged at 295%; the -40px lift is unchanged. */
      /* 260% rather than calc(42% - 40px): identical within 2px at 375/390/430
         (the image is nearly as tall as the viewport, so the percentage has
         almost no leverage and the 0.4626*height term dominates), but it
         leaves background-position parseable -- Chrome does not resolve
         calc() in the computed value, which broke the transition probe. */
      background-position: 72.28% 260%;
    }
  }

  /* ---- On Procuring: close the band/continuation gap on desktop -------------
     The proc band is lifted to the very top of the document
     (top: calc(-1 * --tp-editorial-band-top)) so the artwork starts behind the
     header. But .tp-proc-continue and .tp-proc-dissolve are positioned inside
     .tp-proc-ground, which begins AT band-top. Both therefore sat band-top
     lower than the band: the continuation started 59px after the band ended,
     leaving a bare strip of page between them, and its image was out of
     register by the same 59px. That strip -- pale masked band above, bare
     cream, then full-strength artwork below -- is the white bar across the
     middle of the page. Shifting both layers up by band-top closes it; the
     background-position moves with the box, so the image lands back in
     register and the continuation is genuinely the next rows of one picture. */
  @media (min-width: 700px) {
    .tp-editorial[data-tp-editorial="proc"] .tp-proc-continue {
      top: calc(100vh - var(--tp-editorial-band-top, 0px));
    }

    .tp-editorial[data-tp-editorial="proc"] .tp-proc-dissolve {
      top: calc(0px - var(--tp-editorial-band-top, 0px));
    }
  }

  /* ---- On Procuring: continuation + dissolve, aligned to the handoff frame
     The generic .tp-proc-continue solves its position from the focal vars. This
     page is declared in size/position instead, so on mobile the two disagreed:
     the continuation started 50px BELOW the band's bottom edge and its image
     was 277px out of register. That gap and that jump were the cutoff — not
     the gradient. Both are solved here from the same numbers the band uses.

       image height   = 4.72 x 0.75 x 100vw = 354vw
       image top      = -0.516 x (100vh - 354vw)          [the -51.6% offset]
       continuation   = starts at the band's bottom, runs to the image's end */
  @media (max-width: 699px) {
    .tp-editorial[data-tp-editorial="proc"] .tp-proc-continue {
      --tp-proc-oy: calc(-0.516 * (100vh - 354vw));
      top: calc(100vh - var(--tp-editorial-band-top, 0px));
      height: max(0px, calc(var(--tp-proc-oy) + 354vw - 100vh));
      background-size: 472% auto;
      background-position: 83% calc(var(--tp-proc-oy) - 100vh);
    }

    /* The dissolve starts BELOW the painting and closes on the artwork's own
       last row. Eleven stops over ~900px: no segment changes by more than
       about a tenth, so there is no step to see. */
    .tp-editorial[data-tp-editorial="proc"] .tp-proc-dissolve {
      --tp-proc-oy: calc(-0.516 * (100vh - 354vw));
      top: calc(0px - var(--tp-editorial-band-top, 0px));
      height: max(0px, calc(var(--tp-proc-oy) + 354vw));
      background-image: linear-gradient(to bottom, rgba(250, 248, 243, 0) 0%, rgba(250, 248, 243, 0) 15.33%, rgba(250, 248, 243, 0) 30.67%, rgba(250, 248, 243, 0) 46%, rgba(250, 248, 243, 0.0021) 46.86%, rgba(250, 248, 243, 0.0079) 47.71%, rgba(250, 248, 243, 0.0164) 48.57%, rgba(250, 248, 243, 0.0268) 49.43%, rgba(250, 248, 243, 0.0381) 50.29%, rgba(250, 248, 243, 0.0495) 51.14%, rgba(250, 248, 243, 0.06) 52%, rgba(250, 248, 243, 0.0701) 52.86%, rgba(250, 248, 243, 0.0807) 53.71%, rgba(250, 248, 243, 0.0918) 54.57%, rgba(250, 248, 243, 0.1033) 55.43%, rgba(250, 248, 243, 0.1152) 56.29%, rgba(250, 248, 243, 0.1274) 57.14%, rgba(250, 248, 243, 0.14) 58%, rgba(250, 248, 243, 0.153) 58.86%, rgba(250, 248, 243, 0.1664) 59.71%, rgba(250, 248, 243, 0.1803) 60.57%, rgba(250, 248, 243, 0.1947) 61.43%, rgba(250, 248, 243, 0.2095) 62.29%, rgba(250, 248, 243, 0.2246) 63.14%, rgba(250, 248, 243, 0.24) 64%, rgba(250, 248, 243, 0.256) 64.86%, rgba(250, 248, 243, 0.2727) 65.71%, rgba(250, 248, 243, 0.2899) 66.57%, rgba(250, 248, 243, 0.3074) 67.43%, rgba(250, 248, 243, 0.3251) 68.29%, rgba(250, 248, 243, 0.3427) 69.14%, rgba(250, 248, 243, 0.36) 70%, rgba(250, 248, 243, 0.3771) 70.86%, rgba(250, 248, 243, 0.3943) 71.71%, rgba(250, 248, 243, 0.4114) 72.57%, rgba(250, 248, 243, 0.4286) 73.43%, rgba(250, 248, 243, 0.4457) 74.29%, rgba(250, 248, 243, 0.4629) 75.14%, rgba(250, 248, 243, 0.48) 76%, rgba(250, 248, 243, 0.4971) 76.86%, rgba(250, 248, 243, 0.5143) 77.71%, rgba(250, 248, 243, 0.5314) 78.57%, rgba(250, 248, 243, 0.5486) 79.43%, rgba(250, 248, 243, 0.5657) 80.29%, rgba(250, 248, 243, 0.5829) 81.14%, rgba(250, 248, 243, 0.6) 82%, rgba(250, 248, 243, 0.6169) 82.86%, rgba(250, 248, 243, 0.6336) 83.71%, rgba(250, 248, 243, 0.6502) 84.57%, rgba(250, 248, 243, 0.667) 85.43%, rgba(250, 248, 243, 0.6841) 86.29%, rgba(250, 248, 243, 0.7017) 87.14%, rgba(250, 248, 243, 0.72) 88%, rgba(250, 248, 243, 0.7361) 88.71%, rgba(250, 248, 243, 0.753) 89.43%, rgba(250, 248, 243, 0.7704) 90.14%, rgba(250, 248, 243, 0.788) 90.86%, rgba(250, 248, 243, 0.8057) 91.57%, rgba(250, 248, 243, 0.8231) 92.29%, rgba(250, 248, 243, 0.84) 93%, rgba(250, 248, 243, 0.8531) 93.57%, rgba(250, 248, 243, 0.866) 94.14%, rgba(250, 248, 243, 0.8788) 94.71%, rgba(250, 248, 243, 0.8915) 95.29%, rgba(250, 248, 243, 0.9042) 95.86%, rgba(250, 248, 243, 0.917) 96.43%, rgba(250, 248, 243, 0.93) 97%, rgba(250, 248, 243, 0.9411) 97.43%, rgba(250, 248, 243, 0.9539) 97.86%, rgba(250, 248, 243, 0.9672) 98.29%, rgba(250, 248, 243, 0.9797) 98.71%, rgba(250, 248, 243, 0.9901) 99.14%, rgba(250, 248, 243, 0.9973) 99.57%, rgba(250, 248, 243, 1) 100%);
    }

    /* No veil over the painting: the plaque bitmap carries its own ground. */
    .tp-editorial[data-tp-editorial="proc"] .tp-proc-objnote::before {
      content: none;
    }
  }

  /* ---- On Procuring: the long dissolve --------------------------------
     The band is 100vh tall, so the plate used to stop dead one screen down —
     a horizontal line right where I. THE OBJECT begins. The band itself is
     untouched (its box, crop and mask feed the Salon zoom), and instead two
     decorative layers carry the picture the rest of the way:

       .tp-proc-continue   the SAME plate, same scale, same horizontal
                           position, resuming exactly where the band clips it.
                           Not a repeat — it is the remainder of one image, so
                           there is no seam to hide.
       .tp-proc-dissolve   one long parchment veil that thickens down the
                           page, taking the artwork from crisp, through a
                           progressively washed ghost behind the three
                           columns, to clean parchment.

     Both solve their geometry from the crop custom properties the band reads,
     so they cannot drift from it: an image sized S x the viewport width is
     S x 75vw tall (the plate is 4:3), and a percentage background-position
     puts its top at py x (100vh - that height).

     On Procuring only. Nothing else loads these classes. */
  /* Both layers are solved in vh, so they must not be allowed to extend the
     page: this wrapper clips them to the editorial container. */
  .tp-proc-ground {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
  }

  .tp-proc-continue,
  .tp-proc-dissolve {
    --tp-proc-h: calc(var(--tp-proc-s) * 75vw);
    --tp-proc-oy: calc(var(--tp-proc-py) * (100vh - var(--tp-proc-h)));
    --tp-proc-end: calc(var(--tp-proc-oy) + var(--tp-proc-h));

    position: absolute;
    left: 0;
    width: 100vw;
    pointer-events: none;
  }

  /* The desktop screen carries .tp-crop-desktop all the way down to 700px, so
     these follow the same row rather than the tablet one. */
  @media (min-width: 700px) {
    .tp-proc-continue,
    .tp-proc-dissolve {
      --tp-proc-s: var(--tp-crop-desktop-s);
      --tp-proc-py: var(--tp-crop-desktop-py);
      --tp-proc-posx: var(--tp-crop-desktop-posx);
    }
  }

  @media (max-width: 699px) {
    .tp-proc-continue,
    .tp-proc-dissolve {
      --tp-proc-s: var(--tp-crop-mobile-s);
      --tp-proc-py: var(--tp-crop-mobile-py);
      --tp-proc-posx: var(--tp-crop-mobile-posx);
    }
  }

  .tp-proc-continue {
    top: 100vh;
    height: max(0px, calc(var(--tp-proc-end) - 100vh));
    z-index: 0;
    background-image: var(--tp-plate);
    background-repeat: no-repeat;
    background-size: calc(var(--tp-proc-s) * 100%) auto;
    background-position: var(--tp-proc-posx) calc(var(--tp-proc-oy) - 100vh);
  }

  /* Anchored to the artwork's own extent, not to the viewport. How much plate
     survives below the fold depends on the width — the image is sized as a
     multiple of the viewport width, so a narrow screen simply has less of it
     left — and a vh-anchored ramp would run past the last row there and end on
     a step. In percentages the dissolve always finishes exactly on the
     artwork's final row, at every width, and scales itself to whatever room it
     has.

     The first three stops are the approved upper richness and are deliberately
     unchanged. Everything from 60% down was stretched: the tail used to reach
     0.89 by 82% and then run out, which read as the picture being tidied away
     just before AND SO, SHE PROCURES. It now gives up roughly a tenth at a
     time and only closes on the artwork's very last rows, where what is left
     is faint enough that its actual end cannot be located. */
  .tp-proc-dissolve {
    top: 0;
    height: max(0px, var(--tp-proc-end));
    z-index: 1;
    background-image: linear-gradient(to bottom, rgba(250, 248, 243, 0) 0%, rgba(250, 248, 243, 0) 10%, rgba(250, 248, 243, 0) 20%, rgba(250, 248, 243, 0) 30%, rgba(250, 248, 243, 0.0079) 30.86%, rgba(250, 248, 243, 0.0292) 31.71%, rgba(250, 248, 243, 0.0607) 32.57%, rgba(250, 248, 243, 0.0989) 33.43%, rgba(250, 248, 243, 0.1405) 34.29%, rgba(250, 248, 243, 0.182) 35.14%, rgba(250, 248, 243, 0.22) 36%, rgba(250, 248, 243, 0.2571) 36.86%, rgba(250, 248, 243, 0.2971) 37.71%, rgba(250, 248, 243, 0.3388) 38.57%, rgba(250, 248, 243, 0.3812) 39.43%, rgba(250, 248, 243, 0.4229) 40.29%, rgba(250, 248, 243, 0.4629) 41.14%, rgba(250, 248, 243, 0.5) 42%, rgba(250, 248, 243, 0.5354) 42.86%, rgba(250, 248, 243, 0.5708) 43.71%, rgba(250, 248, 243, 0.6054) 44.57%, rgba(250, 248, 243, 0.6384) 45.43%, rgba(250, 248, 243, 0.669) 46.29%, rgba(250, 248, 243, 0.6965) 47.14%, rgba(250, 248, 243, 0.72) 48%, rgba(250, 248, 243, 0.7442) 49%, rgba(250, 248, 243, 0.7671) 50%, rgba(250, 248, 243, 0.7882) 51%, rgba(250, 248, 243, 0.8073) 52%, rgba(250, 248, 243, 0.8242) 53%, rgba(250, 248, 243, 0.8385) 54%, rgba(250, 248, 243, 0.85) 55%, rgba(250, 248, 243, 0.862) 56.29%, rgba(250, 248, 243, 0.8725) 57.57%, rgba(250, 248, 243, 0.8817) 58.86%, rgba(250, 248, 243, 0.8899) 60.14%, rgba(250, 248, 243, 0.8971) 61.43%, rgba(250, 248, 243, 0.9038) 62.71%, rgba(250, 248, 243, 0.91) 64%, rgba(250, 248, 243, 0.9172) 65.57%, rgba(250, 248, 243, 0.9237) 67.14%, rgba(250, 248, 243, 0.9298) 68.71%, rgba(250, 248, 243, 0.9354) 70.29%, rgba(250, 248, 243, 0.9406) 71.86%, rgba(250, 248, 243, 0.9454) 73.43%, rgba(250, 248, 243, 0.95) 75%, rgba(250, 248, 243, 0.9551) 76.86%, rgba(250, 248, 243, 0.9599) 78.71%, rgba(250, 248, 243, 0.9643) 80.57%, rgba(250, 248, 243, 0.9686) 82.43%, rgba(250, 248, 243, 0.9725) 84.29%, rgba(250, 248, 243, 0.9763) 86.14%, rgba(250, 248, 243, 0.98) 88%, rgba(250, 248, 243, 0.9835) 89.71%, rgba(250, 248, 243, 0.9873) 91.43%, rgba(250, 248, 243, 0.9911) 93.14%, rgba(250, 248, 243, 0.9946) 94.86%, rgba(250, 248, 243, 0.9974) 96.57%, rgba(250, 248, 243, 0.9993) 98.29%, rgba(250, 248, 243, 1) 100%);
  }

  /* ---- Reflections: the plate below the fold --------------------------
     .tp-plate-crop is pinned to 100vh because the Salon zoom hands off to
     exactly that box -- the bridge and destination rects have to agree to the
     pixel, so its height cannot change. Whenever the section is taller than
     the viewport, though (a short or wide window), the plate stopped at 100vh
     and left bare parchment standing between it and the footer.

     This resumes the SAME image, at the same scale and the same horizontal
     position, continuing from exactly where the band clips it down to the
     foot of the section. Not a repeat -- it is the remainder of one picture,
     so there is no seam to hide. Solved from the crop's own geometry: an
     image sized S x the viewport width is 0.75*S x 100vw tall, the band puts
     its top at 0.42*(100vh - that height), and the continuation simply
     carries that offset on by one viewport. */
  .tp-editorial[data-tp-editorial="refl"] .tp-refl-continue {
    position: absolute;
    left: 0;
    width: 100vw;
    top: calc(100vh - var(--tp-editorial-band-top, 0px));
    bottom: 0;
    z-index: 0;
    pointer-events: none;
    background-image: var(--tp-plate);
    background-repeat: no-repeat;
  }

  @media (min-width: 700px) and (max-width: 1179px) {
    /* plate 200%: image height 150vw */
    .tp-editorial[data-tp-editorial="refl"] .tp-refl-continue {
      background-size: 200% auto;
      background-position: 84% calc(-58vh - 63vw);
    }
  }

  @media (min-width: 1180px) {
    /* plate 196%: image height 147vw */
    .tp-editorial[data-tp-editorial="refl"] .tp-refl-continue {
      background-size: 196% auto;
      background-position: 84% calc(-58vh - 61.74vw);
    }
  }

  /* ---- Reflections: the middle note, tied to the mirror ----------------
     The note is centred on the mirror GLASS, not on the viewport, so it has
     to be solved from the same geometry the plate uses. For a plate sized
     S x the viewport width (4:3, so S x 75vw tall) positioned at 84% / 42%,
     a feature at normalised (fx, fy) lands at

       x = 0.84(100vw - S*100vw) + fx*S*100vw
       y = 0.42(100vh - 0.75*S*100vw) + fy*0.75*S*100vw

     The mirror glass centre is fx 0.655, fy 0.468. The two rows below are the
     same point solved for the two plate scales the page uses, which is why
     the note holds its place on the glass at every aspect ratio instead of
     drifting. Nothing else about the note changes. */
  @media (min-width: 700px) and (max-width: 1179px) {
    /* plate 200% */
    .tp-editorial[data-tp-editorial="refl"] .tp-refl-mirrornote__card {
      left: 47vw;
      top: calc(42vh + 7.2vw);
    }
  }

  @media (min-width: 1180px) {
    /* plate 196% */
    .tp-editorial[data-tp-editorial="refl"] .tp-refl-mirrornote__card {
      left: 47.74vw;
      top: calc(42vh + 7.06vw);
    }
  }

  /* ---- On Procuring: the left reading field ---------------------------
     The upper plate is naturally pale on the left, which is what lets the
     title and the archival note sit there. Below the fold the plate's left
     side is busy again -- vases, a book, the blue cord -- and I. THE OBJECT
     had to be read off it. This continues the softening the opening already
     has, the whole way down.

     Two gradients, not one: the horizontal ramp is the vignette itself, the
     vertical mask fades it IN, so nothing is added over the approved opening.
     Both are Fritsch-Carlson resampled, so neither has a locatable edge.
     Artwork, crop and composition are untouched -- this is a veil. */
  .tp-proc-ground::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(to right, rgba(250, 248, 243, 0.62) 0%, rgba(250, 248, 243, 0.6187) 1.33%, rgba(250, 248, 243, 0.6152) 2.67%, rgba(250, 248, 243, 0.6098) 4%, rgba(250, 248, 243, 0.6029) 5.33%, rgba(250, 248, 243, 0.595) 6.67%, rgba(250, 248, 243, 0.5863) 8%, rgba(250, 248, 243, 0.5773) 9.33%, rgba(250, 248, 243, 0.5684) 10.67%, rgba(250, 248, 243, 0.56) 12%, rgba(250, 248, 243, 0.5509) 13.44%, rgba(250, 248, 243, 0.541) 14.89%, rgba(250, 248, 243, 0.5305) 16.33%, rgba(250, 248, 243, 0.5195) 17.78%, rgba(250, 248, 243, 0.508) 19.22%, rgba(250, 248, 243, 0.4963) 20.67%, rgba(250, 248, 243, 0.4843) 22.11%, rgba(250, 248, 243, 0.4721) 23.56%, rgba(250, 248, 243, 0.46) 25%, rgba(250, 248, 243, 0.4477) 26.44%, rgba(250, 248, 243, 0.435) 27.89%, rgba(250, 248, 243, 0.422) 29.33%, rgba(250, 248, 243, 0.4087) 30.78%, rgba(250, 248, 243, 0.3952) 32.22%, rgba(250, 248, 243, 0.3815) 33.67%, rgba(250, 248, 243, 0.3677) 35.11%, rgba(250, 248, 243, 0.3539) 36.56%, rgba(250, 248, 243, 0.34) 38%, rgba(250, 248, 243, 0.3271) 39.33%, rgba(250, 248, 243, 0.314) 40.67%, rgba(250, 248, 243, 0.3007) 42%, rgba(250, 248, 243, 0.2873) 43.33%, rgba(250, 248, 243, 0.2739) 44.67%, rgba(250, 248, 243, 0.2604) 46%, rgba(250, 248, 243, 0.2468) 47.33%, rgba(250, 248, 243, 0.2334) 48.67%, rgba(250, 248, 243, 0.22) 50%, rgba(250, 248, 243, 0.2089) 51.11%, rgba(250, 248, 243, 0.1978) 52.22%, rgba(250, 248, 243, 0.1867) 53.33%, rgba(250, 248, 243, 0.1756) 54.44%, rgba(250, 248, 243, 0.1644) 55.56%, rgba(250, 248, 243, 0.1533) 56.67%, rgba(250, 248, 243, 0.1422) 57.78%, rgba(250, 248, 243, 0.1311) 58.89%, rgba(250, 248, 243, 0.12) 60%, rgba(250, 248, 243, 0.1108) 60.89%, rgba(250, 248, 243, 0.1012) 61.78%, rgba(250, 248, 243, 0.0914) 62.67%, rgba(250, 248, 243, 0.0815) 63.56%, rgba(250, 248, 243, 0.0719) 64.44%, rgba(250, 248, 243, 0.0627) 65.33%, rgba(250, 248, 243, 0.0542) 66.22%, rgba(250, 248, 243, 0.0465) 67.11%, rgba(250, 248, 243, 0.04) 68%, rgba(250, 248, 243, 0.0339) 68.89%, rgba(250, 248, 243, 0.0278) 69.78%, rgba(250, 248, 243, 0.0217) 70.67%, rgba(250, 248, 243, 0.016) 71.56%, rgba(250, 248, 243, 0.0108) 72.44%, rgba(250, 248, 243, 0.0064) 73.33%, rgba(250, 248, 243, 0.003) 74.22%, rgba(250, 248, 243, 0.0008) 75.11%, rgba(250, 248, 243, 0) 76%, rgba(250, 248, 243, 0) 84%, rgba(250, 248, 243, 0) 92%, rgba(250, 248, 243, 0) 100%);
    -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 4.67%, rgba(0, 0, 0, 0) 9.33%, rgba(0, 0, 0, 0) 14%, rgba(0, 0, 0, 0.005) 15.11%, rgba(0, 0, 0, 0.0192) 16.22%, rgba(0, 0, 0, 0.041) 17.33%, rgba(0, 0, 0, 0.069) 18.44%, rgba(0, 0, 0, 0.1017) 19.56%, rgba(0, 0, 0, 0.1376) 20.67%, rgba(0, 0, 0, 0.1752) 21.78%, rgba(0, 0, 0, 0.2132) 22.89%, rgba(0, 0, 0, 0.25) 24%, rgba(0, 0, 0, 0.2905) 25.11%, rgba(0, 0, 0, 0.3389) 26.22%, rgba(0, 0, 0, 0.393) 27.33%, rgba(0, 0, 0, 0.4501) 28.44%, rgba(0, 0, 0, 0.5081) 29.56%, rgba(0, 0, 0, 0.5645) 30.67%, rgba(0, 0, 0, 0.6168) 31.78%, rgba(0, 0, 0, 0.6628) 32.89%, rgba(0, 0, 0, 0.7) 34%, rgba(0, 0, 0, 0.7379) 35.33%, rgba(0, 0, 0, 0.7744) 36.67%, rgba(0, 0, 0, 0.809) 38%, rgba(0, 0, 0, 0.8412) 39.33%, rgba(0, 0, 0, 0.8706) 40.67%, rgba(0, 0, 0, 0.8967) 42%, rgba(0, 0, 0, 0.919) 43.33%, rgba(0, 0, 0, 0.9369) 44.67%, rgba(0, 0, 0, 0.95) 46%, rgba(0, 0, 0, 0.9587) 47.11%, rgba(0, 0, 0, 0.967) 48.22%, rgba(0, 0, 0, 0.9747) 49.33%, rgba(0, 0, 0, 0.9817) 50.44%, rgba(0, 0, 0, 0.9878) 51.56%, rgba(0, 0, 0, 0.9929) 52.67%, rgba(0, 0, 0, 0.9967) 53.78%, rgba(0, 0, 0, 0.9992) 54.89%, rgba(0, 0, 0, 1) 56%, rgba(0, 0, 0, 1) 70.67%, rgba(0, 0, 0, 1) 85.33%, rgba(0, 0, 0, 1) 100%);
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 4.67%, rgba(0, 0, 0, 0) 9.33%, rgba(0, 0, 0, 0) 14%, rgba(0, 0, 0, 0.005) 15.11%, rgba(0, 0, 0, 0.0192) 16.22%, rgba(0, 0, 0, 0.041) 17.33%, rgba(0, 0, 0, 0.069) 18.44%, rgba(0, 0, 0, 0.1017) 19.56%, rgba(0, 0, 0, 0.1376) 20.67%, rgba(0, 0, 0, 0.1752) 21.78%, rgba(0, 0, 0, 0.2132) 22.89%, rgba(0, 0, 0, 0.25) 24%, rgba(0, 0, 0, 0.2905) 25.11%, rgba(0, 0, 0, 0.3389) 26.22%, rgba(0, 0, 0, 0.393) 27.33%, rgba(0, 0, 0, 0.4501) 28.44%, rgba(0, 0, 0, 0.5081) 29.56%, rgba(0, 0, 0, 0.5645) 30.67%, rgba(0, 0, 0, 0.6168) 31.78%, rgba(0, 0, 0, 0.6628) 32.89%, rgba(0, 0, 0, 0.7) 34%, rgba(0, 0, 0, 0.7379) 35.33%, rgba(0, 0, 0, 0.7744) 36.67%, rgba(0, 0, 0, 0.809) 38%, rgba(0, 0, 0, 0.8412) 39.33%, rgba(0, 0, 0, 0.8706) 40.67%, rgba(0, 0, 0, 0.8967) 42%, rgba(0, 0, 0, 0.919) 43.33%, rgba(0, 0, 0, 0.9369) 44.67%, rgba(0, 0, 0, 0.95) 46%, rgba(0, 0, 0, 0.9587) 47.11%, rgba(0, 0, 0, 0.967) 48.22%, rgba(0, 0, 0, 0.9747) 49.33%, rgba(0, 0, 0, 0.9817) 50.44%, rgba(0, 0, 0, 0.9878) 51.56%, rgba(0, 0, 0, 0.9929) 52.67%, rgba(0, 0, 0, 0.9967) 53.78%, rgba(0, 0, 0, 0.9992) 54.89%, rgba(0, 0, 0, 1) 56%, rgba(0, 0, 0, 1) 70.67%, rgba(0, 0, 0, 1) 85.33%, rgba(0, 0, 0, 1) 100%);
  }

  /* ---- Who Is She, mobile: the opening lockup ---------------------------
     The eyebrow, heading, descriptor and intro are one editorial unit in
     normal flow. This gives them air, not a card.

     Two overlapping ellipses rather than one: a single radial centred on a
     tall block always shows as an oval of cream, which is what made the first
     attempt read like a panel. Offsetting a wide, shallow haze against a
     softer, taller one leaves no describable shape — the cream simply thins
     out in every direction and the mannequin keeps coming through. Peak is
     0.82, not 1: the artwork must still be visible inside the lockup. */
  @media (max-width: 699px) {
    .tp-who-lockup {
      position: relative;
      isolation: isolate;
    }

    .tp-who-lockup::before {
      content: "";
      position: absolute;
      inset: -54px -70px -96px -62px;
      z-index: -1;
      pointer-events: none;
      background:
        radial-gradient(ellipse 52% 40% at 26% 36%, rgba(246, 240, 229, 0.7216) 0%, rgba(246, 240, 229, 0.7154) 5.43%, rgba(246, 240, 229, 0.6986) 10.86%, rgba(246, 240, 229, 0.6731) 16.29%, rgba(246, 240, 229, 0.6411) 21.71%, rgba(246, 240, 229, 0.6047) 27.14%, rgba(246, 240, 229, 0.5664) 32.57%, rgba(246, 240, 229, 0.528) 38%, rgba(246, 240, 229, 0.4989) 41.71%, rgba(246, 240, 229, 0.4637) 45.43%, rgba(246, 240, 229, 0.4245) 49.14%, rgba(246, 240, 229, 0.3832) 52.86%, rgba(246, 240, 229, 0.3414) 56.57%, rgba(246, 240, 229, 0.3011) 60.29%, rgba(246, 240, 229, 0.264) 64%, rgba(246, 240, 229, 0.2368) 66.86%, rgba(246, 240, 229, 0.2096) 69.71%, rgba(246, 240, 229, 0.1825) 72.57%, rgba(246, 240, 229, 0.1563) 75.43%, rgba(246, 240, 229, 0.1315) 78.29%, rgba(246, 240, 229, 0.1086) 81.14%, rgba(246, 240, 229, 0.088) 84%, rgba(246, 240, 229, 0.0718) 86.29%, rgba(246, 240, 229, 0.0549) 88.57%, rgba(246, 240, 229, 0.0384) 90.86%, rgba(246, 240, 229, 0.0234) 93.14%, rgba(246, 240, 229, 0.0111) 95.43%, rgba(246, 240, 229, 0.003) 97.71%, rgba(246, 240, 229, 0) 100%),
        radial-gradient(ellipse 70% 62% at 38% 50%, rgba(246, 240, 229, 0.5808) 0%, rgba(246, 240, 229, 0.5763) 4.86%, rgba(246, 240, 229, 0.564) 9.71%, rgba(246, 240, 229, 0.5453) 14.57%, rgba(246, 240, 229, 0.522) 19.43%, rgba(246, 240, 229, 0.4956) 24.29%, rgba(246, 240, 229, 0.4677) 29.14%, rgba(246, 240, 229, 0.44) 34%, rgba(246, 240, 229, 0.4184) 37.43%, rgba(246, 240, 229, 0.3928) 40.86%, rgba(246, 240, 229, 0.3642) 44.29%, rgba(246, 240, 229, 0.3341) 47.71%, rgba(246, 240, 229, 0.3036) 51.14%, rgba(246, 240, 229, 0.274) 54.57%, rgba(246, 240, 229, 0.2464) 58%, rgba(246, 240, 229, 0.2222) 61.14%, rgba(246, 240, 229, 0.1976) 64.29%, rgba(246, 240, 229, 0.1733) 67.43%, rgba(246, 240, 229, 0.1495) 70.57%, rgba(246, 240, 229, 0.1271) 73.71%, rgba(246, 240, 229, 0.1064) 76.86%, rgba(246, 240, 229, 0.088) 80%, rgba(246, 240, 229, 0.0717) 82.86%, rgba(246, 240, 229, 0.0547) 85.71%, rgba(246, 240, 229, 0.0382) 88.57%, rgba(246, 240, 229, 0.0232) 91.43%, rgba(246, 240, 229, 0.0111) 94.29%, rgba(246, 240, 229, 0.003) 97.14%, rgba(246, 240, 229, 0) 100%);
    }

    /* The handwritten notes are marginalia, not part of the opening. Pushed
       down the artwork so the intro is read first and the mannequin gets the
       viewport it is the subject of. */
    .tp-who-margins {
      height: 430px;
      margin-top: 30px;
    }

    .tp-who-margins > p {
      opacity: 0.92;
    }
  }

  /* ---- The Particulars, mobile: the title -------------------------------
     Its own treatment, not Who Is She's. Two lines rather than four, sitting
     over daisies rather than a mannequin, so the haze is wide and shallow and
     weighted left where the type is. Same two-ellipse construction, same
     reason: one radial on a short wide block reads as a cream bar. */
  @media (max-width: 699px) {
    .tp-part-title {
      position: relative;
      isolation: isolate;
    }

    .tp-part-title::before {
      content: "";
      position: absolute;
      /* The box is deliberately far larger than the type and the ellipses are
         sized to reach zero well inside it. An earlier version let the tail
         run to the box edge, which put a faint horizontal line right under
         the subtitle — the cream bar this was meant to avoid. */
      inset: -70px -90px -120px -80px;
      z-index: -1;
      pointer-events: none;
      background:
        radial-gradient(ellipse 46% 34% at 27% 44%, rgba(246, 240, 229, 0.84) 0%, rgba(246, 240, 229, 0.832) 4.86%, rgba(246, 240, 229, 0.81) 9.71%, rgba(246, 240, 229, 0.7771) 14.57%, rgba(246, 240, 229, 0.7366) 19.43%, rgba(246, 240, 229, 0.6915) 24.29%, rgba(246, 240, 229, 0.6449) 29.14%, rgba(246, 240, 229, 0.6) 34%, rgba(246, 240, 229, 0.5638) 37.71%, rgba(246, 240, 229, 0.5223) 41.43%, rgba(246, 240, 229, 0.4774) 45.14%, rgba(246, 240, 229, 0.4308) 48.86%, rgba(246, 240, 229, 0.3845) 52.57%, rgba(246, 240, 229, 0.3403) 56.29%, rgba(246, 240, 229, 0.3) 60%, rgba(246, 240, 229, 0.2681) 63.14%, rgba(246, 240, 229, 0.2366) 66.29%, rgba(246, 240, 229, 0.2059) 69.43%, rgba(246, 240, 229, 0.1764) 72.57%, rgba(246, 240, 229, 0.1486) 75.71%, rgba(246, 240, 229, 0.123) 78.86%, rgba(246, 240, 229, 0.1) 82%, rgba(246, 240, 229, 0.0815) 84.57%, rgba(246, 240, 229, 0.0622) 87.14%, rgba(246, 240, 229, 0.0434) 89.71%, rgba(246, 240, 229, 0.0264) 92.29%, rgba(246, 240, 229, 0.0126) 94.86%, rgba(246, 240, 229, 0.0034) 97.43%, rgba(246, 240, 229, 0) 100%),
        radial-gradient(ellipse 62% 52% at 40% 50%, rgba(246, 240, 229, 0.5) 0%, rgba(246, 240, 229, 0.4952) 4.57%, rgba(246, 240, 229, 0.4821) 9.14%, rgba(246, 240, 229, 0.4626) 13.71%, rgba(246, 240, 229, 0.4387) 18.29%, rgba(246, 240, 229, 0.4124) 22.86%, rgba(246, 240, 229, 0.3855) 27.43%, rgba(246, 240, 229, 0.36) 32%, rgba(246, 240, 229, 0.339) 35.71%, rgba(246, 240, 229, 0.3157) 39.43%, rgba(246, 240, 229, 0.2908) 43.14%, rgba(246, 240, 229, 0.2651) 46.86%, rgba(246, 240, 229, 0.2392) 50.57%, rgba(246, 240, 229, 0.2139) 54.29%, rgba(246, 240, 229, 0.19) 58%, rgba(246, 240, 229, 0.17) 61.14%, rgba(246, 240, 229, 0.1494) 64.29%, rgba(246, 240, 229, 0.1289) 67.43%, rgba(246, 240, 229, 0.109) 70.57%, rgba(246, 240, 229, 0.0905) 73.71%, rgba(246, 240, 229, 0.074) 76.86%, rgba(246, 240, 229, 0.06) 80%, rgba(246, 240, 229, 0.0484) 82.86%, rgba(246, 240, 229, 0.0366) 85.71%, rgba(246, 240, 229, 0.0253) 88.57%, rgba(246, 240, 229, 0.0153) 91.43%, rgba(246, 240, 229, 0.0073) 94.29%, rgba(246, 240, 229, 0.0019) 97.14%, rgba(246, 240, 229, 0) 100%);
    }
  }

  /* ---- On Procuring, mobile: the object-detail lockup -------------------
     USER OVERRIDE (2026-09-12), an explicit exception to the handoff.

     The prototype renders the object detail as live TEXT sitting on the
     painting's faces at y 392-458. Desktop mounts a bitmap plaque instead
     (plaque-procuress.png, [905, 631, 356, 148]). Mobile now uses that same
     plaque, directly under the subtitle, so the caption reads as one museum
     lockup and the painting below it is unobstructed.

     No cream panel: the plaque art carries its own ground. */
  @media (max-width: 699px) {
    .tp-proc-objnote {
      position: relative;
      width: min(84%, 320px);
      /* centred under the canvas, like a museum label */
      margin: 18px auto 0;
    }

    .tp-proc-objnote img {
      display: block;
      width: 100%;
      height: auto;
      filter: drop-shadow(0 6px 14px rgba(28, 20, 8, 0.3));
    }

  }

  /* ---- The Particulars, mobile: the title -------------------------------
     Its own treatment, not Who Is She's. Two lines rather than four, sitting
     over daisies rather than a mannequin, so the haze is wide and shallow and
     weighted left where the type is. Same two-ellipse construction, same
     reason: one radial on a short wide block reads as a cream bar. */
  @media (max-width: 699px) {
    .tp-part-title {
      position: relative;
      isolation: isolate;
    }

    .tp-part-title::before {
      content: "";
      position: absolute;
      /* The box is deliberately far larger than the type and the ellipses are
         sized to reach zero well inside it. An earlier version let the tail
         run to the box edge, which put a faint horizontal line right under
         the subtitle — the cream bar this was meant to avoid. */
      inset: -70px -90px -120px -80px;
      z-index: -1;
      pointer-events: none;
      background:
        radial-gradient(ellipse 46% 34% at 27% 44%, rgba(246, 240, 229, 0.84) 0%, rgba(246, 240, 229, 0.832) 4.86%, rgba(246, 240, 229, 0.81) 9.71%, rgba(246, 240, 229, 0.7771) 14.57%, rgba(246, 240, 229, 0.7366) 19.43%, rgba(246, 240, 229, 0.6915) 24.29%, rgba(246, 240, 229, 0.6449) 29.14%, rgba(246, 240, 229, 0.6) 34%, rgba(246, 240, 229, 0.5638) 37.71%, rgba(246, 240, 229, 0.5223) 41.43%, rgba(246, 240, 229, 0.4774) 45.14%, rgba(246, 240, 229, 0.4308) 48.86%, rgba(246, 240, 229, 0.3845) 52.57%, rgba(246, 240, 229, 0.3403) 56.29%, rgba(246, 240, 229, 0.3) 60%, rgba(246, 240, 229, 0.2681) 63.14%, rgba(246, 240, 229, 0.2366) 66.29%, rgba(246, 240, 229, 0.2059) 69.43%, rgba(246, 240, 229, 0.1764) 72.57%, rgba(246, 240, 229, 0.1486) 75.71%, rgba(246, 240, 229, 0.123) 78.86%, rgba(246, 240, 229, 0.1) 82%, rgba(246, 240, 229, 0.0815) 84.57%, rgba(246, 240, 229, 0.0622) 87.14%, rgba(246, 240, 229, 0.0434) 89.71%, rgba(246, 240, 229, 0.0264) 92.29%, rgba(246, 240, 229, 0.0126) 94.86%, rgba(246, 240, 229, 0.0034) 97.43%, rgba(246, 240, 229, 0) 100%),
        radial-gradient(ellipse 62% 52% at 40% 50%, rgba(246, 240, 229, 0.5) 0%, rgba(246, 240, 229, 0.4952) 4.57%, rgba(246, 240, 229, 0.4821) 9.14%, rgba(246, 240, 229, 0.4626) 13.71%, rgba(246, 240, 229, 0.4387) 18.29%, rgba(246, 240, 229, 0.4124) 22.86%, rgba(246, 240, 229, 0.3855) 27.43%, rgba(246, 240, 229, 0.36) 32%, rgba(246, 240, 229, 0.339) 35.71%, rgba(246, 240, 229, 0.3157) 39.43%, rgba(246, 240, 229, 0.2908) 43.14%, rgba(246, 240, 229, 0.2651) 46.86%, rgba(246, 240, 229, 0.2392) 50.57%, rgba(246, 240, 229, 0.2139) 54.29%, rgba(246, 240, 229, 0.19) 58%, rgba(246, 240, 229, 0.17) 61.14%, rgba(246, 240, 229, 0.1494) 64.29%, rgba(246, 240, 229, 0.1289) 67.43%, rgba(246, 240, 229, 0.109) 70.57%, rgba(246, 240, 229, 0.0905) 73.71%, rgba(246, 240, 229, 0.074) 76.86%, rgba(246, 240, 229, 0.06) 80%, rgba(246, 240, 229, 0.0484) 82.86%, rgba(246, 240, 229, 0.0366) 85.71%, rgba(246, 240, 229, 0.0253) 88.57%, rgba(246, 240, 229, 0.0153) 91.43%, rgba(246, 240, 229, 0.0073) 94.29%, rgba(246, 240, 229, 0.0019) 97.14%, rgba(246, 240, 229, 0) 100%);
    }
  }

  /* ---- On Procuring, mobile: the object-detail lockup -------------------
     Moving this block up put it against the top of the Baburen, which is the
     lightest part of the crop but still a painting. Measured down its own
     column the plate runs busy 48-77 with brightness 105-188, so the caption
     needs a ground or it cannot be read at all.

     Same vocabulary as the header scrim and the Salon tagline: the header's
     own cream, a low peak, most of the radius spent feathering out. Localized
     to this lockup — On Procuring's long downward dissolve is a separate
     treatment and is untouched. Mobile only; the desktop screen places this
     copy on the plaque instead. */
  @media (max-width: 699px) {
    .tp-proc-objnote {
      position: relative;
      isolation: isolate;
    }

    .tp-proc-objnote::before {
      content: "";
      position: absolute;
      inset: -14px -18px -12px -20px;
      z-index: -1;
      pointer-events: none;
      border-radius: 2px;
      background: radial-gradient(ellipse 104% 116% at 34% 50%, rgba(246, 240, 229, 0.88) 0%, rgba(246, 240, 229, 0.8778) 4.57%, rgba(246, 240, 229, 0.8717) 9.14%, rgba(246, 240, 229, 0.8622) 13.71%, rgba(246, 240, 229, 0.8497) 18.29%, rgba(246, 240, 229, 0.8348) 22.86%, rgba(246, 240, 229, 0.8181) 27.43%, rgba(246, 240, 229, 0.8) 32%, rgba(246, 240, 229, 0.7839) 35.14%, rgba(246, 240, 229, 0.7617) 38.29%, rgba(246, 240, 229, 0.7347) 41.43%, rgba(246, 240, 229, 0.704) 44.57%, rgba(246, 240, 229, 0.6705) 47.71%, rgba(246, 240, 229, 0.6355) 50.86%, rgba(246, 240, 229, 0.6) 54%, rgba(246, 240, 229, 0.5688) 56.57%, rgba(246, 240, 229, 0.5337) 59.14%, rgba(246, 240, 229, 0.4959) 61.71%, rgba(246, 240, 229, 0.4566) 64.29%, rgba(246, 240, 229, 0.4167) 66.86%, rgba(246, 240, 229, 0.3775) 69.43%, rgba(246, 240, 229, 0.34) 72%, rgba(246, 240, 229, 0.3074) 74.29%, rgba(246, 240, 229, 0.2743) 76.57%, rgba(246, 240, 229, 0.2412) 78.86%, rgba(246, 240, 229, 0.2087) 81.14%, rgba(246, 240, 229, 0.1773) 83.43%, rgba(246, 240, 229, 0.1475) 85.71%, rgba(246, 240, 229, 0.12) 88%, rgba(246, 240, 229, 0.0989) 89.71%, rgba(246, 240, 229, 0.0761) 91.43%, rgba(246, 240, 229, 0.0535) 93.14%, rgba(246, 240, 229, 0.0328) 94.86%, rgba(246, 240, 229, 0.0157) 96.57%, rgba(246, 240, 229, 0.0042) 98.29%, rgba(246, 240, 229, 0) 100%);
    }
  }

  /* ---- On Procuring: the plaque mounted to the frame -------------------
     Solved from the crop exactly as the design solves it — the painting sits
     between 68.2% and 84.5% of the plate's width, its lower edge at 38.55% of
     its height — but in viewport units, so it needs no measurement pass and
     cannot reframe mid-transition. Desktop and tablet only; the mobile screen
     places its plaque in flow. */
  .tp-proc-plaque {
    position: absolute;
    z-index: 6;
    pointer-events: none;
    --tp-plaque-frame: 26.895vw;
    --tp-plaque-w: max(200px, 24.7434vw);
    left: calc(61.83vw + (var(--tp-plaque-frame) - var(--tp-plaque-w)) / 2);
    top: calc(4.5vh + 39.4474vw - 1px);
    width: var(--tp-plaque-w);
  }

  @media (max-width: 1099px) {
    .tp-proc-plaque {
      --tp-plaque-frame: 27.71vw;
      --tp-plaque-w: max(200px, 25.4932vw);
      left: calc(59.24vw + (var(--tp-plaque-frame) - var(--tp-plaque-w)) / 2);
      top: calc(1.7vh + 44.2129vw - 1px);
    }
  }

  /* ---- Photographs not yet supplied -----------------------------------
     The designed frame is kept and nothing is invented to fill it. */
  .tp-slot-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12%;
    text-align: center;
    font-family: var(--tp-font-mono);
    font-size: clamp(8px, 0.68vw, 10px);
    letter-spacing: var(--tp-track-wide);
    text-transform: uppercase;
    color: var(--tp-color-gold-text);
    opacity: 0.75;
  }

  /* The pages paint a viewport-wide vignette; the site footer must sit above
     it, as the design's own footer does, or it shows through washed out. */
  .tp-editorial ~ .tp-footer,
  .tp-site > .tp-footer {
    position: relative;
    z-index: 5;
  }
}


/* ---- Who Is She, mobile: the side vignette ---------------------------------
   The opening was hard to read because the chandelier (reaching in to 30.4%% of
   the width) and the wall art (from 55.6%%) sit directly behind the heading,
   descriptor and intro. A full-screen haze fixes that only by bleaching the
   mannequin, which is the subject.

   This fades inward from BOTH edges instead. The mannequin occupies
   17.8%%-68.2%% of the width at 375, 390 and 430 alike (the crop is declared in
   percentages, so those figures do not move), so the clear band is 28%%-70%%:
   the mannequin's core is untouched while the bulk of the chandelier and the
   wall art is behind cream. Painted on the band's own ::after, so it fades out
   with the band's mask and cannot outlive it. */
@media (max-width: 699px) {
  .tp-editorial[data-tp-editorial="who"] .tp-plate-crop::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(to right, rgba(246, 240, 229, 0.88) 0%, rgba(246, 240, 229, 0.8313) 3.43%, rgba(246, 240, 229, 0.7055) 6.86%, rgba(246, 240, 229, 0.5336) 10.29%, rgba(246, 240, 229, 0.3464) 13.71%, rgba(246, 240, 229, 0.1745) 17.14%, rgba(246, 240, 229, 0.0487) 20.57%, rgba(246, 240, 229, 0) 24%, rgba(246, 240, 229, 0) 38.67%, rgba(246, 240, 229, 0) 53.33%, rgba(246, 240, 229, 0) 68%, rgba(246, 240, 229, 0.0487) 72.57%, rgba(246, 240, 229, 0.1745) 77.14%, rgba(246, 240, 229, 0.3464) 81.71%, rgba(246, 240, 229, 0.5336) 86.29%, rgba(246, 240, 229, 0.7055) 90.86%, rgba(246, 240, 229, 0.8313) 95.43%, rgba(246, 240, 229, 0.88) 100%);
  }
}


/* ---- The Particulars: the handoff opening frame ----------------------------
   Measured off the handoff live render. The plate is painted with
   background-attachment: fixed, so the positioning area is the viewport --
   which is exactly what .tp-ground::before already does here with
   position: fixed, so only the crop needed correcting.

     >= 1280px   200% auto   6% 80%
     768-1279px  250% auto   11% 76%
     <= 699px    330% auto   16% 74%

   The focal-target pass had 540%/680%/860% of the viewport width, 2.6-2.7x the
   handoff: the opening closed on a fragment of the eye and lost the crystal
   ball, the globe and the blue-and-white room detail the page opens around. */
.tp-editorial[data-tp-editorial="part"] .tp-ground::before {
  background-size: 250% auto;
  background-position: 11% 76%;
}

@media (min-width: 1280px) {
  .tp-editorial[data-tp-editorial="part"] .tp-ground::before {
    background-size: 200% auto;
    background-position: 6% 80%;
  }
}

@media (max-width: 699px) {
  .tp-editorial[data-tp-editorial="part"] .tp-ground::before {
    background-size: 330% auto;
    /* USER OVERRIDE on the handoff for mobile only. The handoff's 16% 74% puts
       the mannequin centre-stage and the page is explicitly meant to open on
       the eye / crystal ball / globe with the mannequin incidental at most.
       Scale is the handoff's 330%; only the framing moves. The cluster spans
       plate x 0.02-0.30, y 0.58-0.80 (centre 0.16, 0.69); centring it
       horizontally and seating it at 62% of the height solves to 1.22% / 118%
       at 375, 390 and 430 alike, which leaves the mannequin upper-right and
       largely out of frame. */
    background-position: 1.22% 118%;
  }
}


/* ---- The Particulars, tablet: the title reading field ----------------------
   The lockup now sits at the top of the opening (it was pushed to the bottom of
   a 560px artwork box by margin: auto, which is why tablet read as a different
   design family from desktop and mobile). The ground there is calmer but still
   carries the lampshade and daisies, so the subhead needed a lift.

   Two overlapping ellipses rather than one, for the same reason as the Who Is
   She lockup: a single radial on a wide block reads as an oval of cream, while
   two offset hazes simply thin out in every direction with no describable
   shape. Peak is a composite 0.67 -- well below the 0.92 Who Is She needs,
   because this ground is far less busy -- so the artwork stays visible.

   Both radii complete INSIDE the box (vertical radius <= 50% about a centre
   near 50%). A first attempt used 150%, which left the gradient still
   opaque at the element's bounds and showed its rectangle across the
   lampshade. */
@media (min-width: 700px) and (max-width: 1279px) {
  .tp-part-lockup {
    position: relative;
  }

  .tp-part-lockup::before {
    content: "";
    position: absolute;
    inset: -96px -90px -120px -76px;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(ellipse 42% 46% at 22% 46%, rgba(246, 240, 229, 0.5) 0%, rgba(246, 240, 229, 0.4905) 7.14%, rgba(246, 240, 229, 0.465) 14.29%, rgba(246, 240, 229, 0.4278) 21.43%, rgba(246, 240, 229, 0.3834) 28.57%, rgba(246, 240, 229, 0.336) 35.71%, rgba(246, 240, 229, 0.2901) 42.86%, rgba(246, 240, 229, 0.25) 50%, rgba(246, 240, 229, 0.2099) 57.14%, rgba(246, 240, 229, 0.164) 64.29%, rgba(246, 240, 229, 0.1166) 71.43%, rgba(246, 240, 229, 0.0722) 78.57%, rgba(246, 240, 229, 0.035) 85.71%, rgba(246, 240, 229, 0.0095) 92.86%, rgba(246, 240, 229, 0) 100%), radial-gradient(ellipse 64% 40% at 34% 52%, rgba(246, 240, 229, 0.34) 0%, rgba(246, 240, 229, 0.3336) 7.14%, rgba(246, 240, 229, 0.3162) 14.29%, rgba(246, 240, 229, 0.2909) 21.43%, rgba(246, 240, 229, 0.2607) 28.57%, rgba(246, 240, 229, 0.2285) 35.71%, rgba(246, 240, 229, 0.1973) 42.86%, rgba(246, 240, 229, 0.17) 50%, rgba(246, 240, 229, 0.1427) 57.14%, rgba(246, 240, 229, 0.1115) 64.29%, rgba(246, 240, 229, 0.0793) 71.43%, rgba(246, 240, 229, 0.0491) 78.57%, rgba(246, 240, 229, 0.0238) 85.71%, rgba(246, 240, 229, 0.0064) 92.86%, rgba(246, 240, 229, 0) 100%);
  }
}
